How do I calculate the volume measured by the Sparkfun Sound Detector?
In this document it is described that changing the resistance between the two r17 pins changes the gain. I'm doing this using an X9C104 (which is just a digital potentiometer) so I can set the gain using my Arduino.
I've written a function that converts a given gain dB value into the resistance required at r17 to reach that gain level. But what I couldn't figure out is how to calculate the actual volume or sound pressure level that is picked up by the Sound Detector.
It's gotta be some equation that takes the gain and raw audio level read at the analog pin into account:
float getDbVolumeByRawVolume(float gain, int rawVolume) {
// magic ?
}
This is my code so far:
#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);
Serial.print("Volume:");
Serial.println(dbVolume);
}
float getDbVolumeByRawVolume(float gain, int rawVolume) {
// 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)
}
Any ideas on how to do this?