If you want to measure sound pressure levels, detect claps, or build a basic audio-reactive light show, the Adafruit MAX9814 Electret Microphone Amplifier (Product ID: 1713) is the definitive analog Arduino microphone module. Unlike cheap $2 sound sensors that only output a useless digital spike, the MAX9814 features an Automatic Gain Control (AGC) amplifier that normalizes quiet and loud sounds into a clean 0-3.3V analog envelope.
This guide walks through wiring the MAX9814 to an Arduino Uno R3, provides fully compilable C++ code to read the audio envelope, and details the exact debugging steps for the most common ADC and serial errors makers encounter on the bench.
Project Overview & Difficulty Rating
| Parameter | Specification |
|---|---|
| Target Board | Arduino Uno R3 (ATmega328P) or Nano v3 |
| Module | Adafruit MAX9814 (Analog Electret w/ AGC) |
| Difficulty | Beginner-Intermediate (2/5) |
| Time to Complete | 20-30 minutes |
| Core Concept | Analog-to-Digital Conversion (ADC), DC Offset Removal |
Hardware: Parts List & Pin Mapping
Before you start stripping wires, verify you have the exact components listed below. Using a generic 'KY-038' sound sensor will not work with this specific code, as those modules lack the AGC circuitry and output a noisy, unamplified raw signal.
Bill of Materials
- Microcontroller: Arduino Uno R3 (Rev3) or genuine clone with ATmega328P
- Microphone Module: Adafruit MAX9814 Electret Microphone Amplifier (~$9.50)
- Wiring: 3x Male-to-Male jumper wires (22 AWG stranded)
- Power: USB-B cable (for 5V power and Serial monitoring)
Pin Mapping Table
| MAX9814 Pin | Arduino Uno R3 Pin | Notes |
|---|---|---|
| VCC | 5V | Do not use 3.3V; the onboard LDO requires ~3.6V minimum input. |
| GND | GND | Must share a common ground with the Uno for accurate ADC readings. |
| OUT | A0 | Analog output. Centered at ~1.25V DC offset with audio AC riding on top. |
Wiring Steps & Analog Gain Configuration
The MAX9814 has a physical gain pad on the PCB that dictates the AGC range. By default, it ships set to 60dB. For most desk-level environments, this is too sensitive and will cause the AGC to 'pump' (rapidly adjust gain, creating distortion).
- Set the Gain: Look at the bottom edge of the MAX9814 board. You will see three pads labeled 60, 50, and 40. Bridge the 40 and 50 pads with a blob of solder to set the gain to 50dB, or bridge 40 and 60 for 40dB. (Leave as-is for 60dB only if recording very quiet sounds from across the room).
- Connect Power: Route a red jumper from the Arduino 5V pin to the MAX9814 VCC pad.
- Connect Ground: Route a black jumper from any Arduino GND pin to the MAX9814 GND pad.
- Connect Signal: Route a yellow/green jumper from the MAX9814 OUT pad to Arduino Analog Pin A0.
- Verify: Tug gently on the jumper wires. The MAX9814 header pins are notoriously easy to cold-solder if you assembled them yourself; ensure a solid mechanical connection.
Complete Arduino Microphone Code
This sketch targets the Arduino Uno R3. It reads the analog envelope, strips the DC offset (the ~1.25V bias the amplifier adds), calculates the peak-to-peak amplitude over a 50ms window, and outputs both the raw envelope and the calculated volume to the Serial Plotter.
/*
* Arduino Microphone Envelope Reader
* Target: Arduino Uno R3 (ATmega328P)
* Sensor: Adafruit MAX9814 (Analog OUT to A0)
*/
// --- Pin Definitions ---
#define MIC_PIN A0
#define LED_PIN 13 // Optional: onboard LED for visual clipping indicator
// --- Configuration ---
#define BAUD_RATE 115200
#define SAMPLE_WINDOW_MS 50 // 50ms window for volume calculation (20Hz update rate)
#define DC_OFFSET 512 // Approximate 10-bit ADC center for 1.25V bias on 5V Uno
void setup() {
Serial.begin(BAUD_RATE);
pinMode(LED_PIN, OUTPUT);
// Brief delay to allow serial monitor to connect and ADC to stabilize
delay(1000);
// Error handling: Verify ADC is not stuck
int testRead = analogRead(MIC_PIN);
if (testRead == 0 || testRead == 1023) {
Serial.println("ERROR: ADC reading stuck at rail. Check GND and OUT wiring.");
while(1) {
digitalWrite(LED_PIN, HIGH); delay(100);
digitalWrite(LED_PIN, LOW); delay(100);
}
}
Serial.println("System Initialized. Open Serial Plotter (115200 baud).");
}
void loop() {
unsigned long startMillis = millis();
unsigned int peakToPeak = 0;
unsigned int signalMax = 0;
unsigned int signalMin = 1023;
// Collect samples for the duration of the sample window
while (millis() - startMillis < SAMPLE_WINDOW_MS) {
unsigned int sample = analogRead(MIC_PIN);
// Filter out invalid ADC spikes (hardware noise)
if (sample < 1020) {
if (sample > signalMax) signalMax = sample;
else if (sample < signalMin) signalMin = sample;
}
}
// Calculate peak-to-peak amplitude
peakToPeak = signalMax - signalMin;
// Map to a 0-100 volume percentage (empirically tuned for 50dB gain)
int volumePercent = map(peakToPeak, 0, 400, 0, 100);
volumePercent = constrain(volumePercent, 0, 100);
// Visual feedback for loud sounds (clipping threshold)
if (volumePercent > 85) {
digitalWrite(LED_PIN, HIGH);
} else {
digitalWrite(LED_PIN, LOW);
}
// Output formatted for Arduino Serial Plotter (Space-separated)
Serial.print("Volume:");
Serial.print(volumePercent);
Serial.print(" PeakToPeak:");
Serial.println(peakToPeak);
}
For deeper theory on how the Arduino analogRead function samples the internal capacitor array, refer to the official Arduino language reference.
Debugging: First Three Things to Check When It Fails
Audio circuits are highly susceptible to ground loops, floating pins, and baud rate mismatches. If your build isn't behaving, run through this ranked checklist.
1. Serial Monitor Outputting '??????Y?' (Gibberish)
The Symptom: You open the Serial Monitor and see strings like ??????Y? or ÿÿÿÿ.
The Cause: Baud rate mismatch. The code initializes at 115200, but your Serial Monitor dropdown is set to the default 9600.
The Fix: Change the baud rate dropdown in the bottom right corner of the Arduino IDE Serial Monitor to 115200. Alternatively, change #define BAUD_RATE 115200 to 9600 in the code, though 115200 is preferred for high-speed plotting.
2. ADC Reading Stuck at ~512 (or 0 / 1023)
The Symptom: The Serial Plotter shows a perfectly flat line at 512, regardless of how loud you yell. Alternatively, the onboard LED blinks rapidly on boot, indicating the hardware error trap triggered.
The Cause: A floating analog input or a broken ground. If the GND wire is disconnected, the Arduino's ADC sample-and-hold capacitor cannot discharge, locking the reading. If it's stuck at 512, the MAX9814 might not be receiving power (VCC disconnected), leaving the pin floating at the Uno's internal leakage voltage.
The Fix: Use a multimeter in DC voltage mode. Probe the MAX9814 VCC and GND pads directly. You must read between 4.8V and 5.2V. If you read 0V, reseat your 5V jumper.
3. Audio 'Pumping' or Extreme Distortion in Readings
The Symptom: A loud clap causes the volume reading to spike, but then the readings drop to near-zero for a full second, even if you keep talking.
The Cause: AGC Time Constant and Gain Saturation. The MAX9814's Automatic Gain Control takes time to release. If your gain is set to 60dB, a loud noise forces the AGC to drastically cut the internal amplifier gain, and it takes up to 1 second to ramp back up.
The Fix: Solder the gain jumper to the 40dB setting. This reduces the AGC's dynamic range but prevents aggressive pumping in typical desktop environments.
Extending and Simplifying the Build
Depending on your end goal, you might not need the fidelity of the MAX9814, or you might need far more bandwidth than the Uno can provide.
digitalRead(2). No ADC math required.
Extending (The High-Fidelity Route): If you want to record actual voice audio, perform FFT frequency analysis, or stream audio over WiFi, the Arduino Uno's 16MHz AVR chip and 10-bit ADC are bottlenecks. Upgrade to an ESP32 DevKit v1 and an INMP441 I2S Digital MEMS Microphone (~$4). The ESP32 has a hardware I2S peripheral and dual-core 240MHz processing, allowing you to sample at 44.1kHz (CD quality) and push the audio via MQTT or WebSockets. Note that I2S requires wiring LRCLK, BCLK, and DOUT pins, which is a protocol shift, not just an analog read.
Arduino Microphone FAQ
Can I use an Arduino microphone to record and playback actual voice audio?
Not with a standard Arduino Uno and an analog module. The Uno's ATmega328P lacks a Digital-to-Analog Converter (DAC) for playback, and its ADC maxes out around 9.6kHz, which results in muffled, telephony-grade audio at best. To record and playback voice, you need an Arduino Nano 33 BLE Sense (which has an onboard PDM microphone and DSP) or an ESP32 paired with an I2S microphone and an I2S DAC amplifier like the MAX98357A.
Why is my generic KY-038 microphone module not picking up my voice?
The KY-038 is designed primarily for loud impulse detection (claps, knocks), not continuous voice envelope tracking. Its analog out (AO) pin is highly noisy and lacks the Automatic Gain Control found on the MAX9814. If you must use a KY-038 for voice, you will need to add an external hardware low-pass filter (a simple RC filter with a 1k resistor and 100nF capacitor) between the AO pin and the Arduino analog input to smooth out the high-frequency hash.
How do I wire an I2S digital microphone like the INMP441 to an Arduino Uno?
You cannot. The INMP441 outputs a digital I2S data stream requiring specific clock lines (BCLK, WS) and a hardware I2S peripheral to decode the PDM/PCM data. The Arduino Uno does not have an I2S peripheral. You must use a 32-bit microcontroller like the ESP32, Raspberry Pi Pico (RP2040), or Arduino Nano 33 IoT to interface with digital I2S MEMS microphones.
What is the 'DC Offset' mentioned in the code, and why do I need to remove it?
The MAX9814 outputs an audio signal that oscillates between positive and negative voltages. Because the Arduino's ADC can only read positive voltages (0V to 5V), the module adds a ~1.25V DC bias (offset) to the signal so it sits in the middle of the Arduino's readable range. In 10-bit ADC terms, 1.25V translates to a baseline reading of roughly 255 to 512 (depending on exact VCC). The code calculates the peak-to-peak difference (Max minus Min) rather than absolute values, which mathematically cancels out this DC offset, giving you just the pure audio amplitude.






