If you have ever searched for an arduino mic tutorial, you have likely encountered the ubiquitous $1 LM393 sound sensor module. That module is not a microphone; it is a digital clap switch with a potentiometer. It outputs a simple HIGH/LOW signal when sound crosses a fixed threshold, making it entirely useless for measuring volume levels, building VU meters, or performing frequency analysis. To capture actual audio waveforms, you need an analog electret microphone with a built-in preamplifier and Automatic Gain Control (AGC).
This guide focuses on the Adafruit MAX9814 Electret Microphone Amplifier (Product ID: 1713). We will wire it to an Arduino Nano V3, write a robust peak-to-peak envelope follower, and debug the most common ADC (Analog-to-Digital Converter) traps that cause beginners to think their hardware is broken.
The Problem with Cheap Arduino Mic Modules
The fundamental issue with budget sound sensors is the lack of a bias voltage and proper amplification. An electret microphone capsule requires a DC bias voltage (usually 2V to 5V) to power its internal JFET impedance converter. The raw output is a tiny AC signal (in the millivolt range) riding on that DC bias. The MAX9814 handles this internally, providing a clean, amplified AC signal centered precisely at VCC/2 (typically 2.5V on a 5V system). It also features a 3-setting AGC, which prevents loud sounds from clipping the amplifier while boosting quiet sounds, giving you a massive dynamic range without manual potentiometer tweaking.
Required Parts List
- Microcontroller: Arduino Nano V3 (ATmega328P, 5V/16MHz logic) - $6.00
- Microphone Module: Adafruit MAX9814 (Product ID: 1713) - $14.95
- Decoupling Capacitor: 100nF (0.1µF) Ceramic Capacitor - $0.10
- Pull-down Resistor: 10kΩ (for AGC pin stability) - $0.10
- Wiring: 22 AWG solid core jumper wires and a half-size solderless breadboard.
Wiring the MAX9814 to an Arduino Nano V3
The ATmega328P ADC expects a voltage between 0V and 5V. The MAX9814 outputs a signal biased at 2.5V, swinging roughly ±2V at maximum gain. This fits perfectly within the Arduino's 0-5V ADC window. However, the power supply must be clean; the Arduino's 5V rail can carry high-frequency switching noise from the USB interface.
Pin Mapping and Spec Sheet
| MAX9814 Pin | Arduino Nano V3 Pin | Notes & Function |
|---|---|---|
| VCC | 5V | Powers the op-amp and electret bias. Must be 5V for correct VCC/2 biasing. |
| GND | GND | Shared ground reference. Keep this wire short to avoid ground loops. |
| OUT | A0 | Analog audio output. Centered at ~2.5V DC. |
| AR (Attack/Release) | GND (via 10kΩ) | Controls AGC timing. Tying to GND sets a 1:4000 attack/release ratio (best for general audio). Leave floating for 1:250, or tie to VCC for 1:10. |
Step-by-Step Wiring Procedure
- Insert the Arduino Nano V3 and the MAX9814 breakout board into the breadboard, ensuring they span the center trench.
- Connect the Nano's 5V pin to the positive power rail, and GND to the negative ground rail.
- Wire the MAX9814 VCC to the positive rail, and GND to the negative rail.
- Insert the 100nF decoupling capacitor directly across the MAX9814's VCC and GND pins.
- Connect the 10kΩ resistor from the MAX9814 AR pin to the ground rail.
- Run a jumper wire from the MAX9814 OUT pin directly to the Arduino Nano's A0 pin.
Compilable Code: Real-Time Audio Envelope Follower
Reading audio with a simple analogRead() and printing it to the Serial Monitor is useless. Human eyes cannot process 10,000 samples per second, and the raw waveform just looks like noise. Instead, we calculate the Peak-to-Peak (P2P) amplitude over a 20-millisecond window. This creates a smooth 'envelope' that represents the perceived loudness, which is ideal for driving LEDs or triggering events.
Target Board: Arduino Nano V3 (ATmega328P). Note: If using a 3.3V board like an ESP32, you must use a voltage divider on the OUT pin or power the mic with 3.3V, otherwise you will damage the ADC.
#include <Arduino.h>
// --- PIN DEFINITIONS ---
#define MIC_PIN A0
#define STATUS_LED_PIN 13
// --- CONFIGURATION ---
const unsigned long SAMPLE_WINDOW_MS = 20; // 20ms window for audio envelope
const int NOISE_FLOOR = 35; // Ignore ADC jitter below this P2P value
const int STUCK_THRESHOLD = 50; // Consecutive identical readings to flag hardware error
int consecutiveStuckReadings = 0;
int lastPeakToPeak = 0;
void setup() {
Serial.begin(115200);
pinMode(STATUS_LED_PIN, OUTPUT);
pinMode(MIC_PIN, INPUT);
// Allow ADC to stabilize
analogRead(MIC_PIN);
delay(100);
Serial.println(F("MAX9814 Envelope Follower Initialized."));
}
void loop() {
unsigned long startMillis = millis();
int signalMax = 0;
int signalMin = 1023;
int sample;
// Collect samples for the duration of the window
while ((millis() - startMillis) < SAMPLE_WINDOW_MS) {
sample = analogRead(MIC_PIN);
// Basic error handling: discard out-of-bounds ADC noise
if (sample >= 0 && sample <= 1023) {
if (sample > signalMax) signalMax = sample;
if (sample < signalMin) signalMin = sample;
}
}
// Calculate Peak-to-Peak amplitude
int peakToPeak = signalMax - signalMin;
// Hardware Fault Detection: Check if ADC is locked or disconnected
if (peakToPeak == lastPeakToPeak) {
consecutiveStuckReadings++;
} else {
consecutiveStuckReadings = 0;
}
if (consecutiveStuckReadings > STUCK_THRESHOLD) {
Serial.println(F("ERROR: ADC reading locked. Check OUT pin wiring to A0 and verify 5V power."));
digitalWrite(STATUS_LED_PIN, HIGH); // Solid LED indicates fault
delay(1000); // Throttle error printing
return;
}
// Apply noise floor filtering
if (peakToPeak < NOISE_FLOOR) {
peakToPeak = 0;
}
// Output for Serial Plotter (Arduino IDE -> Tools -> Serial Plotter)
Serial.print(F("Volume: "));
Serial.println(peakToPeak);
// Visual feedback: Blink LED on loud transients (claps/shouts)
if (peakToPeak > 400) {
digitalWrite(STATUS_LED_PIN, HIGH);
} else {
digitalWrite(STATUS_LED_PIN, LOW);
}
lastPeakToPeak = peakToPeak;
}
Debugging: The First Three Things to Check When It Fails
When an analog audio circuit fails, the Serial Monitor rarely gives you a neat compilation error. Instead, you get confusing data streams. Here is the exact decision path for the three most common hardware and logic failures.
1. Symptom: Serial Monitor is stuck outputting exactly '512' or '511'
Cause: The 512 Bias Trap. The MAX9814 outputs an AC signal centered at VCC/2. On a 5V system, 2.5V translates to an ADC reading of 512. If the room is dead silent, or if the AGC hasn't ramped up the gain yet, the peak-to-peak value might be near zero, meaning both signalMax and signalMin hover around 512.
Fix: This is not a failure; it is correct physics. Make a loud noise (clap near the capsule) to force the AGC to react. If it still stays at 512, check that the 100nF decoupling capacitor isn't accidentally shorting the OUT pin to GND.
2. Symptom: Erratic spikes, 60Hz hum, or values jumping from 0 to 800 randomly
Cause: USB Ground Loop or missing decoupling. Laptop switching power supplies inject high-frequency common-mode noise into the USB ground. Because the Arduino's ground is shared with the microphone's ground, this noise modulates the audio signal.
Fix: First, unplug your laptop from the wall and run on battery power. If the noise disappears, you have a ground loop. To fix it permanently while plugged in, ensure your 100nF capacitor is installed, and consider powering the Arduino via a regulated 5V wall adapter instead of the PC USB port.
3. Symptom: Serial Monitor prints 'ERROR: ADC reading locked...'
Cause: Floating Analog Pin or broken jumper. If the A0 pin is not physically connected to the OUT pin, the ATmega328P's internal sample-and-hold capacitor will retain its last charge or float to a random static voltage, resulting in a 'stuck' reading that triggers the software watchdog in our code.
Fix: Use your multimeter in continuity mode. Probe the OUT pin on the MAX9814 and the A0 pin on the Nano. You should read < 1 ohm. If the wire is good, check that the MAX9814 VCC pin is actually receiving 4.8V to 5.2V.
Extending and Simplifying the Build
Once you have a clean envelope signal, the next step depends on your end goal.
To Simplify (Digital I2S Alternative): If you are tired of dealing with analog noise, ADC sampling rates, and bias voltages, abandon analog mics entirely and move to an ESP32 with an INMP441 I2S MEMS Microphone. I2S mics output digital 24-bit audio directly over a serial bus, completely bypassing the microcontroller's noisy internal ADC. The trade-off is that I2S requires an ESP32 or Raspberry Pi Pico; standard 5V Arduinos lack the hardware I2S peripherals and RAM required to buffer digital audio streams.
To Extend (FFT Frequency Analysis): If you want to build a spectrum analyzer (splitting audio into bass, mids, and treble), the peak-to-peak code above won't work. You need to sample at a strict, interrupt-driven rate (e.g., 9.6kHz) and pass the buffer into a Fast Fourier Transform library like arduinoFFT. Be warned: the ATmega328P only has 2KB of SRAM. A 512-sample FFT buffer will consume over half your available memory, leaving very little room for complex LED matrix libraries. For FFT projects, upgrade to an Arduino Nano 33 BLE or an ESP32.
Frequently Asked Questions
Why is my Arduino mic picking up 60Hz mains hum from the wall?
Electret microphones are highly sensitive to electromagnetic interference (EMI). The 60Hz hum (and its 120Hz harmonic) is radiating from your AC wall wiring and fluorescent lights. Because the MAX9814 has an AGC that boosts quiet signals by up to 40dB, it will amplify this ambient EMI. To fix this, move the microphone away from AC power bricks, use a shielded cable for the OUT pin if it runs longer than 4 inches, and ensure your breadboard ground plane is as compact as possible.
How do I wire an Arduino mic MAX9814 for a 3.3V board like the ESP32?
The ESP32's ADC will be permanently damaged if it sees voltages above 3.3V. The MAX9814 can be powered directly from 3.3V, which shifts its output bias to 1.65V and limits the maximum peak-to-peak swing to roughly 3.0V, keeping it safely within the ESP32's ADC limits. Simply wire the MAX9814 VCC pin to the ESP32's 3.3V output instead of 5V. Note that the ESP32's ADC is notoriously non-linear and noisy compared to the ATmega328P, so you may need to implement a software moving-average filter in your code.
Can I use this Arduino mic setup to record voice and save it to an SD card?
Not with the Arduino Nano V3. Recording intelligible voice requires a sampling rate of at least 8,000 Hz (8kHz) and storing those bytes to an SD card via SPI. The ATmega328P lacks the DMA (Direct Memory Access) controllers and SRAM required to read the ADC and write to an SD card simultaneously without dropping samples, resulting in choppy, robotic audio. For voice recording, use a Raspberry Pi Pico or an ESP32, which have the clock speed and memory buffers necessary to handle WAV file creation.






