To build a reliable Arduino SPL (Sound Pressure Level) meter, you need more than just a cheap microphone module and a basic code sketch. A true sound level meter requires an electret microphone with automatic gain control (AGC) like the MAX9814, proper DC bias verification, and an ADC sampling rate high enough to capture the AC waveform's peak-to-peak voltage before converting it to RMS and decibels. If you skip the bench verification step, your Arduino will output erratic, meaningless numbers.
This guide walks through the physical verification of your sensor with a digital multimeter (DMM), the wiring and code required to calculate decibels, and the common pitfalls that ruin acoustic measurements.
Verifying the SPL Sensor Module with a Multimeter
Before uploading code, you must verify that your microphone module is biased correctly and outputting a clean AC signal. The MAX9814 outputs a DC-biased AC waveform. If the DC bias is wrong, the Arduino's ADC will clip the waveform, resulting in massive calculation errors.
Meter Setup Block
- Dial Position: V DC (for bias verification), then switch to mV AC or V AC (for signal swing).
- Lead Jacks: Black lead in COM, Red lead in V/Ω/Hz.
- Range: Auto-ranging preferred. If manual, set to 2V DC for bias, and 200mV AC for signal swing.
Probe Placement & Expected Readings
Power the module via the Arduino's 5V and GND pins. Place your probes directly on the module's header pins, not the breadboard traces, to avoid reading voltage drops across loose breadboard contacts.
| Test Point | Meter Mode | Expected Reading (Good) | Fault Reading (Bad) |
|---|---|---|---|
| VCC to GND | V DC | 4.80V – 5.10V | < 4.50V (USB brownout or bad cable) |
| OUT to GND (Silence) | V DC | 1.20V – 1.30V (MAX9814) 2.40V – 2.60V (MAX4466) |
0.00V or 5.00V (Output shorted to rail) |
| OUT to GND (Talking) | mV AC | 50mV – 500mV AC | < 10mV (Dead capsule or AGC locked) |
If your DC bias reads correctly but your AC swing is near zero when you speak directly into the capsule, the electret microphone itself is likely dead or the AGC attack/release capacitor on the module is faulty.
Wiring and Coding the Arduino SPL Meter
For accurate audio sampling, the standard ATmega328P (Arduino Uno) ADC is limited to roughly 9.6 ksps (kilosamples per second). This is enough to capture the envelope of speech, but for true broadband SPL measurement in 2026, we recommend using an ESP32 with an I2S digital microphone like the INMP441. However, for this analog MAX9814 setup, we will optimize the Uno's ADC prescaler to get the fastest possible reads.
Pin Mapping
| MAX9814 Pin | Arduino Uno Pin | Notes |
|---|---|---|
| VCC | 5V | Do not use 3.3V; the module requires 5V for the internal charge pump. |
| GND | GND | Keep ground wires short to avoid 50/60Hz mains hum injection. |
| OUT | A0 | Analog input. Do not use a digital pin. |
Complete Arduino Code
This sketch samples the analog pin as fast as possible, calculates the RMS (Root Mean Square) voltage, and converts it to a relative decibel reading. To get true dB SPL, you must add a calibration offset (see FAQ).
// Arduino SPL Meter - MAX9814 Optimized
// Target: Arduino Uno (ATmega328P)
const int micPin = A0;
const int sampleWindow = 50; // Sample window in ms (50ms = 20Hz)
const float adcReference = 5.0; // Uno uses 5V reference
const float dcBias = 1.25; // MAX9814 typical DC bias in volts
void setup() {
Serial.begin(115200);
// Speed up ADC prescaler to 16 (approx 76.8 kHz sample rate)
// Standard is 128 (9.6 kHz). 16 pushes the ATmega328P ADC limits but works for audio envelopes.
bitClear(ADCSRA, ADPS0);
bitClear(ADCSRA, ADPS1);
bitSet(ADCSRA, ADPS2);
}
void loop() {
unsigned long startMillis = millis();
unsigned int peakToPeak = 0;
unsigned int signalMax = 0;
unsigned int signalMin = 1024;
// Collect data for the sample window
while (millis() - startMillis < sampleWindow) {
int sensorValue = analogRead(micPin);
if (sensorValue < 1024) { // Sanity check
if (sensorValue > signalMax) signalMax = sensorValue;
if (sensorValue < signalMin) signalMin = sensorValue;
}
}
peakToPeak = signalMax - signalMin;
// Convert ADC peak-to-peak to Voltage
float voltsPP = (peakToPeak * adcReference) / 1024.0;
// Convert Peak-to-Peak to RMS (assuming sine wave approximation)
float voltsRMS = voltsPP / 2.828;
// Calculate dB relative to 1V RMS (dBV)
// Add your specific calibration offset here for true dB SPL
float dB = 20.0 * log10(voltsRMS / 1.0);
// Prevent negative infinity on absolute silence
if (voltsRMS < 0.001) dB = 0.0;
Serial.print("Volts RMS: ");
Serial.print(voltsRMS, 4);
Serial.print(" | dB: ");
Serial.println(dB, 1);
delay(100); // UI update rate
}
Common Mistakes That Skew Decibel Readings
Acoustic measurement is notoriously unforgiving. If your readings look like random noise or fail to track actual volume changes, you are likely falling victim to one of these bench mistakes.
1. Using the KY-038 "Sound Sensor" Module
The ubiquitous KY-038 module (often sold in 37-sensor kits) features a cheap LM393 comparator and a low-grade electret capsule. It outputs a digital HIGH/LOW when sound crosses a potentiometer threshold. Its analog out pin is unamplified and lacks AGC. Fix: Throw it away for SPL tasks and buy a dedicated amplifier module like the MAX9814 or MAX4466.
2. Ignoring the Nyquist Limit and Aliasing
Human hearing spans 20Hz to 20kHz. To accurately digitize a 20kHz wave, you need a minimum 40kHz sampling rate (Nyquist theorem). The default Arduino ADC runs at ~9.6kHz. If you sample a 12kHz acoustic tone at 9.6kHz, it aliases down to 2.4kHz, completely skewing your RMS calculation. Fix: The code above modifies the ADC prescaler to push the sample rate to ~76kHz. Alternatively, use an external RMS-to-DC converter IC (like the Analog Devices AD736) between the mic and the Arduino to let hardware handle the math.
3. Acoustic Feedback and Breadboard Resonance
If your module is plugged directly into a solderless breadboard, the plastic cavity acts as a resonant chamber. Tapping the table or low-frequency HVAC rumble will couple mechanically into the breadboard and register as massive acoustic spikes. Fix: Mount the microphone module on a piece of closed-cell foam or hot-glue it to the enclosure wall, decoupling it from the main PCB.
Arduino SPL Meter FAQ
Why is my Arduino SPL meter reading jumping around randomly?
Random jumping is almost always caused by 50Hz or 60Hz mains hum coupling into the high-impedance analog trace. The MAX9814 has high gain, making it sensitive to electromagnetic interference (EMI). Ensure your analog wire from the OUT pin to A0 is as short as possible, ideally under 2 inches. If you are powering the Arduino via a cheap, unfiltered USB wall charger, the switching noise will inject directly into the 5V rail. Switch to a battery power bank or a linear voltage regulator to eliminate the switching noise.
Can I use an Arduino SPL meter for OSHA workplace noise compliance?
No. OSHA and NIOSH require sound level meters to meet ANSI/ASA S1.4 or IEC 61672 Type 1 or Type 2 standards. These standards mandate specific A-weighting and C-weighting analog filters, precise time-weighting (Fast/Slow/Impulse), and traceable acoustic calibration. An Arduino with a raw electret capsule measures flat (Z-weighted) acoustic pressure and lacks the certified hardware filters required for legal or medical compliance.
How do I calibrate my Arduino SPL meter to real decibels?
Decibels are a ratio, not an absolute unit. To display true dB SPL (Sound Pressure Level), you must compare your sensor to a known reference. Purchase a 94 dB SPL acoustic calibrator (a small device that generates an exact 94 dB tone at 1kHz). Place your MAX9814 capsule into the calibrator, run the Arduino code, and note the raw dB value the serial monitor outputs. If the monitor reads 42.5 dB, your calibration offset is +51.5. Add this offset to the final dB variable in your code.
What is the difference between MAX9814 and MAX4466 for SPL measurement?
Both are excellent electret amplifier modules, but they handle gain differently. The MAX9814 features a 3-step selectable gain (40dB, 50dB, 60dB) and, crucially, an Automatic Gain Control (AGC) circuit that prevents loud noises from clipping the output. It has a fixed 1.25V DC bias. The MAX4466 has a manually adjustable gain via a trim potentiometer but lacks AGC. For an SPL meter where you expect both quiet rooms and loud machinery, the MAX9814's AGC prevents the ADC from saturating, making it the superior choice for wide dynamic ranges.






