NicoHood / MSGEQ7

Library for Musicvisualization with MSGEQ7
160 stars 31 forks source link

Value is 0 on loud sounds #14

Open nonsintetic opened 5 years ago

nonsintetic commented 5 years ago

Using this library with an ESP8266 (just a ESP12 module and passives). When the output from the MSGEQ7 is at max (3.3v) the library reads 0 for that band until the level is lower. I checked the output from the chip on the scope and it doesn't go low or anything, it looks as I would expect.

Sketch:

#include "MSGEQ7.h"
#define pinAnalog A0
#define pinReset 2
#define pinStrobe 5
#define MSGEQ7_INTERVAL ReadsPerSecond(50)
#define MSGEQ7_SMOOTH 0 // Range: 0-255

CMSGEQ7<MSGEQ7_SMOOTH, pinReset, pinStrobe, pinAnalog> MSGEQ7;

void setup() {
  Serial.begin(115200);
  MSGEQ7.begin();

}

void loop() {
  // Analyze without delay every interval
  bool newReading = MSGEQ7.read(MSGEQ7_INTERVAL);

  if (newReading) {
    for(int i = 0; i <= 6; i++) {
       uint8_t val = MSGEQ7.get(i);
       Serial.print(val);
       Serial.print(" ");
    }
    Serial.println();
  }
}

Output on tapping the mic:

147 237 202 140 99 64 98 
125 199 169 121 85 58 92 
0 0 0 0 0 0 0 
0 0 0 0 0 0 0 
0 0 0 0 0 0 0 
0 0 0 0 0 0 0 
0 0 0 0 0 0 0 
0 0 0 0 0 0 0 
0 0 0 0 0 0 234 
0 232 234 231 234 226 196 
232 229 214 195 195 190 166 
195 192 180 163 164 160 141 
163 162 151 138 139 138 122 
141 137 129 117 118 116 103 
96 96 89 81 84 83 0 
0 0 0 0 0 0 0 
0 0 0 0 0 0 0 
0 0 0 0 0 0 0 
0 0 0 0 0 0 0 
0 0 0 0 0 0 0 
0 0 0 0 0 0 0 
0 0 0 0 0 0 0 
0 0 0 0 0 0 236 
235 235 235 235 236 235 197 
197 200 197 198 198 198 166 
166 167 165 167 167 166 140 
173 212 180 118 0 0 0 
0 0 0 0 0 0 0 
0 0 0 0 0 0 0 
0 0 0 0 0 0 0 
0 0 0 0 0 0 0 
0 0 0 0 0 0 0 
0 0 0 0 0 0 0 
0 0 0 0 0 0 0 

Scope trace - yellow is strobe pin, red is ADC pin

NicoHood commented 5 years ago

I guess the ESP analog library then has a problem. Because on AVR works, so the calculation must be correct. I think I cannot do anything about this issue. You'd have to debug the analogread output.

ErrorErrorError commented 5 years ago

I guess the ESP analog library then has a problem. Because on AVR works, so the calculation must be correct. I think I cannot do anything about this issue. You'd have to debug the analogread output.<

I also get this issue with my ESP8266 , but this only happens when I use the 8 bit resolution. When I use the 10 bit resolution, the input gets maxed out when it's louder rather than going to 0.

ErrorErrorError commented 5 years ago

I figured it out why the audio sets back to zero when it's louder in 8 bit. The reason is because one cannot just define a variable that is usually in the range 0 - 1023 to 8 bit. If you want to get the input as 8 bit, you have to map from 10 bit to 8 bit and this will prevent the data from going back to zero in loud frequencies.

nonsintetic commented 5 years ago

I figured out the same thing eventually. Due to time restraints I just modified the needed functions from the library to tolerate 10 bit values and it worked fine. I don't have a pull request because I just fixed the small part I used.

ErrorErrorError commented 5 years ago

@nonsintetic what part of the code you changed?

nonsintetic commented 5 years ago

Sadly I just took the parts I needed and put them into my code, I didn't have time to change the library or I would have done a pull request. Here are the relevant bits in what I'm using and work just fine on the ESP8266:

#define MSGEQ7_SMOOTH 200 //0-1024
#define ReadsPerSecond(f) (1000000UL / (f))
#define MSGEQ7_FPS ReadsPerSecond(50)

int bands[7];

void loop() {
  currentMicros = micros();
  if( (currentMicros - lastSample) > MSGEQ7_FPS) {
      readMSGEQ7();
      lastSample = currentMicros; //store time of last sample
  }  
}

void initMSGEQ7() {
  pinMode(RESET_PIN, OUTPUT); 
  pinMode(STROBE_PIN, OUTPUT); 
  digitalWrite(RESET_PIN,LOW); 
  digitalWrite(STROBE_PIN,HIGH);
}

void readMSGEQ7() {
  for(int band = 0; band < 7; band++) {
    digitalWrite(STROBE_PIN,HIGH);
    digitalWrite(STROBE_PIN,LOW);
    delayMicroseconds(40); // allow MSGEQ7 time to settle
    int val = analogRead(A0); //read ADC
    //smooth
    bands[band] = int( bands[band] * MSGEQ7_SMOOTH + val * (1024 - MSGEQ7_SMOOTH) ) / 1024;
    delayMicroseconds(400); //allow ADC to settle
  }
}
ErrorErrorError commented 5 years ago

Sadly I just took the parts I needed and put them into my code, I didn't have time to change the library or I would have done a pull request. Here are the relevant bits in what I'm using and work just fine on the ESP8266:

#define MSGEQ7_SMOOTH 200 //0-1024
#define ReadsPerSecond(f) (1000000UL / (f))
#define MSGEQ7_FPS ReadsPerSecond(50)

int bands[7];

void loop() {
  currentMicros = micros();
  if( (currentMicros - lastSample) > MSGEQ7_FPS) {
      readMSGEQ7();
      lastSample = currentMicros; //store time of last sample
  }  
}

void initMSGEQ7() {
  pinMode(RESET_PIN, OUTPUT); 
  pinMode(STROBE_PIN, OUTPUT); 
  digitalWrite(RESET_PIN,LOW); 
  digitalWrite(STROBE_PIN,HIGH);
}

void readMSGEQ7() {
  for(int band = 0; band < 7; band++) {
    digitalWrite(STROBE_PIN,HIGH);
    digitalWrite(STROBE_PIN,LOW);
    delayMicroseconds(40); // allow MSGEQ7 time to settle
    int val = analogRead(A0); //read ADC
    //smooth
    bands[band] = int( bands[band] * MSGEQ7_SMOOTH + val * (1024 - MSGEQ7_SMOOTH) ) / 1024;
    delayMicroseconds(400); //allow ADC to settle
  }
}

I will make a pull request soon and thank you!

ErrorErrorError commented 5 years ago

The issue was because smoothing is on and smoothing is not supported with 10 bit.

NicoHood commented 5 years ago

Maybe you could prepare a PR with a fix?

ErrorErrorError commented 5 years ago

Maybe you could prepare a PR with a fix?

Created a PR!

NicoHood commented 3 years ago

Ouuups. The PR was not merged yet.

ErrorErrorError commented 3 years ago

I currently do not have an MSGEQ7 to test with, but last thing I remember is that analogRead(int adc) was returning values from 0-1024 and not 0-1023 which the algorithm in the system caused it to return 0 when the sound is loud.