Sound sensor results high reading

Hi , I tried my sound sensor and found one weird value.

min=427	max=1023	p2p=596.00	Loudness: 62Db(A)	Level3: HIGH
min=1024	max=0	p2p=4294966272.00	Loudness: 2099226Db(A)	Level4: Ultimately HIGH
min=0	max=33	p2p=33.00	Loudness: 27Db(A)	Levell: Quiet
min=521	max=854	p2p=333.00	Loudness: 46Db(A)	Level2: Moderate
min=43	max=1021	p2p=978.00	Loudness: 87Db(A)	Level4: Ultimately HIGH
min=926	max=1020	p2p=94.00	Loudness: 30Db(A)	Levell: Quiet
min=1024	max=0	p2p=4294966272.00	Loudness: 2099226Db(A)	Level4: Ultimately HIGH

this is the code


BlynkTimer timer;
const int sampleWindow = 50;                              // Sample window width in mS (50 mS = 20Hz)
const byte soundpin = 35;
const byte led1 = 2;
const byte led2 = 4;
const byte led3 = 17;
const byte led4 = 19;

void setup() {

  pinMode (soundpin, INPUT);
  pinMode (led1, OUTPUT);
  pinMode (led2, OUTPUT);
  pinMode (led3, OUTPUT);
  pinMode (led4, OUTPUT);
  Serial.begin (115200);
  Blynk.begin(auth, ssid, pass);
  timer.setInterval(1000L, sensorDataSend);

}

void sensorDataSend() {
  int sample;
  unsigned long startMillis = millis();
  float peakTopeak = 0;
  int db;

  unsigned int signalMax = 0; // minvalue
  unsigned int signalMin = 1024; //maxvalue previously 1024


  while (millis() - startMillis < sampleWindow)
  {
    sample = analogRead(soundpin);
    if (sample < 1024) //previously i use 1024
    {
      if (sample > signalMax)
      {
        signalMax = sample;   //save just max level
      }
      else if (sample < signalMin)
      {
        signalMin = sample; //save just min level
      }
    }
  }
  Serial.print("\nmin=");
  Serial.print(signalMin);
  Serial.print("\tmax=");
  Serial.print(signalMax);
  peakTopeak = signalMax - signalMin;
  Serial.print("\tp2p=");
  Serial.print(peakTopeak);
  int store = map(peakTopeak, 0, 1023, 25, 90 ); //calibrate the db 20,900,49,90
  db = store;
  Serial.print("\tLoudness: ");
  Serial.print (db);
  Serial.print ("Db(A)\t");
  Blynk.virtualWrite(V0, db);
  digitalWrite (led1, LOW);
  digitalWrite (led2, LOW);
  digitalWrite (led3, LOW);
  digitalWrite (led4, LOW);
  Blynk.virtualWrite(V1, 0);
  Blynk.virtualWrite(V2, 0);
  Blynk.virtualWrite(V3, 0);
  Blynk.virtualWrite(V4, 0);
  if (db <= 40)
  {
    Serial.print("Levell: Quiet");
    digitalWrite(led1, HIGH);
    Blynk.virtualWrite(V1, 1);
  }
  else if (db > 40 && db < 55)
  {
    Serial.print("Level2: Moderate");
    digitalWrite(led2, HIGH);
    Blynk.virtualWrite(V2, 1);
  }
  else if (db > 55 && db < 70)
  {
    Serial.print("Level3: HIGH");
    digitalWrite(led3, HIGH);
    Blynk.virtualWrite(V3, 1);
  }
    else if (db >= 70)
  {
    Serial.print("Level4: Ultimately HIGH");
    digitalWrite(led4, HIGH);
    Blynk.virtualWrite(V4, 1);
  }
}

void loop() {
  Blynk.run();
  timer.run();

}

could you help me solve this because the peak to peak= min -max. but min = 1024. and max = 0. also anyone have other idea to do a project on decibel meter?

What hardware are you using?

Wher is your schematic?

below is the 4 leds connects to esp32 through breadboard to notify the user for certain limit of decibel level. and 3 out of 4 pin of grove sound sensor connect to measure analog signal before get the reading in db.

link?

maybe this one?

https://shopee.com.my/Grove-Loudness-Sensor-PROMO-PRICE--i.6641351.1038780762
this link

is it because of I connect to 5v on the esp32 ? it turn okay but not too fluctuate to follow the sound changes when supply by 3v3 pin

Since the maximum you can ever get from an analog read is 1023, this will ALWAYS be true. Why is it there?

1 Like

i see. so i should put condition like sample<1023

what is the purpose of that if statement?

An ESP32 has a 12 bit A:D converter the max is a bit higher than 1023.

Putting 5V into the 3V3 pins of a ESP32 will destroy the ESP32, as a note.

Here is a task I use to calculate V's.


void fReadBattery( void * parameter )
{
  const float r1 = 50500.0f; // R1 in ohm, 50K
  const float r2 = 10000.0f; // R2 in ohm, 10k potentiometer
  const TickType_t xFrequency = 1000; //delay for mS
  float    adcValue = 0.0f;
  float    Vbatt = 0.0f;
  int      printCount = 0;
  float    vRefScale = (3.3f / 4096.0f) * ((r1 + r2) / r2);
  uint64_t TimePastKalman  = esp_timer_get_time(); // used by the Kalman filter UpdateProcessNoise, time since last kalman calculation
  SimpleKalmanFilter KF_ADC_b( 1.0f, 1.0f, .01f );
  TickType_t xLastWakeTime = xTaskGetTickCount();
  for (;;)
  {
    adc1_get_raw(ADC1_CHANNEL_0); //read and discard
    adcValue = float( adc1_get_raw(ADC1_CHANNEL_0) ); //take a raw ADC reading
    KF_ADC_b.setProcessNoise( (esp_timer_get_time() - TimePastKalman) / 1000000.0f ); //get time, in microsecods, since last readings
    adcValue = KF_ADC_b.updateEstimate( adcValue ); // apply simple Kalman filter
    Vbatt = adcValue * vRefScale;
    xSemaphoreTake( sema_CalculatedVoltage, portMAX_DELAY );
    CalculatedVoltage = Vbatt;
    xSemaphoreGive( sema_CalculatedVoltage );
    
      printCount++;
      if ( printCount == 3 )
      {
      //log_i( "Vbatt %f", Vbatt );
      printCount = 0;
      }
    
    TimePastKalman = esp_timer_get_time(); // time of update complete
    xLastWakeTime = xTaskGetTickCount();
    vTaskDelayUntil( &xLastWakeTime, xFrequency );
    //log_i( "fReadBattery %d",  uxTaskGetStackHighWaterMark( NULL ) );
  }
  vTaskDelete( NULL );
}

Note the use of 4096, float vRefScale = (3.3f / 4096.0f) * ((r1 + r2) / r2); instead of 1024 to calculate V's.

I once made an SPL Meter with an Arduino Uno and an analog SparkFun sound sensor.

You'd have to adapt it to the ESP32, calibrate for particular sound sensor, and possibly make other changes for your sensor. And, you'd need to add the code for the LEDs. (I send the dB values to the Serial Monitor.)

this is the latest one.

void sensorDataSend() {
  int sample;
  unsigned long startMillis = millis();
  float peakTopeak = 0;
  int db;
 
  unsigned int signalMax = 0; // minvalue
  unsigned int signalMin = 1024; //maxvalue previously 1024


  while (millis() - startMillis < sampleWindow)
  {
    analogSetWidth(10);
    sample = analogRead(soundpin);
    if (sample > signalMax)
    {
      signalMax = sample;   //save just max level
    }
    else if (sample < signalMin)
    {
      signalMin = sample; //save just min level
    }

  }
  Serial.print("\nmin=");
  Serial.print(signalMin);
  Serial.print("\tmax=");
  Serial.print(signalMax);
  peakTopeak = signalMax - signalMin;
  Serial.print("\tp2p=");
  Serial.print(peakTopeak);
  int store = map(peakTopeak, 0, 1023, 30, 90 ); //calibrate the db 20,900,49,90
  db = store;

however I still get analog value more than 1023, may I know how it can happened even I reduce to 10 bit. below is the serial monitor

min=0	max=1328	p2p=1328.00	Loudness: 94Db(A)	Level4: Ultimately HIGH
min=472	max=660	p2p=188.00	Loudness: 39Db(A)	Levell: Quiet

I did not realize you were using an ESP32 device. What is the largest value you can get with 12 bits? The 1023 is the largest value for 10 bits.

I have an issue with the sensitivity since I compare the reading with decibelX(software from phone). The above coding I shared with you is less sensitivity, when I clap, theres no big changes in db value. So i taught because of the bit is 12, is there reason I should reduce to 10bit to increase the sens of sensor? or any idea on this thing?

You should forget about the dB calculation until you get the raw values working properly. Use serial.Print() of the raw values and see how they change with the sound level. When they are satisfactory, then begin the dB calculations.

You have no current limiting resistors on the LEDs. There is a good chance that can destroy the ESP output pins.

1 Like

The Arduino IDE may not have properly set the ESP32's ADC API.

You can use the ESP32's AD API to access the ESP32's ADC.


this picture show the raw data I obtained by using the code as shown below.

const byte sensorpin = 35;
void setup() {
 pinMode (sensorpin, INPUT);
 Serial.begin (115200);
}

void loop() {
 int sample;
 sample=analogRead(sensorpin);
 Serial.println(sample);
delay(100);
}

Throughout the test i increase my speaker volume from 0 to 80% and I saw a big difference happened on 80% but the signal value is not up to 4096 (12 bit is default in esp32 right). so why the value is not close to 4000 after increasing the sound. I use vcc 5v.

The opamp (LM2904) used in the sensor board does not have a rail to rail output. So the output will not go as high or as low as you expect.

1 Like

The sound sensor may not have rail-to-rail capabilities.

Put 3V3 onto the AD pin and see what reading you get.

1 Like