Sound_Detector icon indicating copy to clipboard operation
Sound_Detector copied to clipboard

Formula to calculate sound pressure level in dB?

Open T-vK opened this issue 2 years ago • 0 comments

What's the formula to calculate the sound pressure level in dB that the sensor is currently picking up?

I'm setting the gain on pin r17 using a digital potentiometer. In my code I have the variables gainDb, rawAudioVolume and rawEnvelopeVolume available. How do I calculate the sound pressure level / volume from that?

/**
 * gain: A number between 0 and 33
 * rawAudioVolume: A number between 0 and 1023
 * rawEnvelopeVolume: A number between 0 and 1023
 */
float getDbVolumeByRawVolume(float gain, int rawAudioVolume, int rawEnvelopeVolume) {
  // magic
  return ?
}
#include <LapX9C10X.h>

#define SOUND_DETECTOR_AUDIO_PIN A0
#define SOUND_DETECTOR_ENVELOPE_PIN A1
#define POT_CS_PIN 8
#define POT_INC_PIN 9
#define POT_UD_PIN 10
LapX9C10X gainPot(POT_INC_PIN, POT_UD_PIN, POT_CS_PIN, LAPX9C10X_X9C104);

float gainDb = 33;

void setup() {
  Serial.begin(115200);
  pinMode(SOUND_DETECTOR_AUDIO_PIN, INPUT);
  pinMode(SOUND_DETECTOR_ENVELOPE_PIN, INPUT);
  gainPot.begin();
  float resistance = getResistanceByGain(gainDb); 
  gainPot.set(gainDb);
}

void loop() {
  int rawAudioVolume = analogRead(SOUND_DETECTOR_AUDIO_PIN);
  int rawEnvelopeVolume = analogRead(SOUND_DETECTOR_ENVELOPE_PIN);
  
  float dbVolume = getDbVolumeByRawVolume(gainDb, rawAudioVolume, rawEnvelopeVolume);

  Serial.print("Volume:");
  Serial.println(dbVolume);
}

/**
 * gain: A number between 0 and 33
 * rawAudioVolume: A number between 0 and 1023
 * rawEnvelopeVolume: A number between 0 and 1023
 */
float getDbVolumeByRawVolume(float gain, int rawAudioVolume, int rawEnvelopeVolume) {
  // magic
  return ?
}

// Sparkfun sound detector dB<>resistance-interpolation based on Sparkfun's data set
// https://learn.sparkfun.com/tutorials/sound-detector-hookup-guide/configuration
float getResistanceByGain(float dB) {
  const float infinityOhms = 40.0f;
  const float dBTable[] = {0.0f, 6.0f, 13.0f, 19.0f, 25.0f, 30.0f, 33.0f, 40.0f};
  const float resistanceTable[] = {0.0f, 2.2f, 4.7f, 10.0f, 22.0f, 47.0f, 100.0f, INFINITY};

  // Check if the dB value is out of range
  if (dB < dBTable[0] || dB > dBTable[7])
    return -1.0f; // Return an error value or handle the case accordingly

  // Find the two nearest dB values in the table
  int index = 0;
  while (dB > dBTable[index + 1])
    index++;

  // Perform logarithmic interpolation
  float dB1 = dBTable[index];
  float dB2 = dBTable[index + 1];
  float resistance1 = resistanceTable[index];
  float resistance2 = resistanceTable[index + 1];

  float resistance = resistance1 * pow(10, ((dB - dB1) * log10(resistance2 / resistance1)) / (dB2 - dB1));
  return resistance / 1000.0f; // Return resistance in kilohms (K)
}

T-vK avatar May 26 '23 14:05 T-vK