ESP32 · 03-audio
Architecture: ESP32 Voice Hardware
Note: This document was generated by an AI agent.
Overview
Adding voice to the ESP32 robot face requires solving two opposite electrical problems:
- A microphone produces an analog signal too small and noisy for the ESP32 to measure directly.
- A speaker requires far more current, and a smoother waveform, than an ESP32 GPIO can provide.
The project crosses those boundaries with an INMP441 digital microphone and a MAX98357A digital amplifier. Both exchange PCM samples with the ESP32 over I2S, allowing DMA to move audio without consuming the face renderer's 33 ms frame budget.
The two directions are mirror images. Both cross from analog to digital inside a dedicated chip, and everything downstream of that crossing is numbers moving under DMA.
For the firmware boundary and task-level implementation, see ESP32 I2S Audio Runtime. For the timing constraint audio must protect, see Face rendering and effects.
Why a Bare Microphone Does Not Work
Sound pressure is extremely small
Atmospheric pressure in a room is approximately 101,325 Pa. Ordinary speech at about one metre adds a pressure variation of roughly 0.02 Pa. The microphone must reject the static atmospheric load and detect a variation about five million times smaller.
An illustrative electret microphone sensitivity of -44 dBV/Pa is equivalent to approximately 6.3 mV/Pa:
44 / 20 = 2.2
10^2.2 ≈ 158
1 V / 158 ≈ 0.0063 V
= 6.3 mV/Pa
If the decibel notation or the conversion above is unfamiliar, Decibels, from scratch explains both from first principles and walks those four lines one at a time.
At normal speaking pressure:
0.02 Pa × 6.3 mV/Pa ≈ 0.13 mV speaking about one metre away
0.42 mV speaking about 30 cm away
The ESP32 ADC is too coarse and noisy for that signal
An ideal 12-bit conversion across 0 to 3.3 V has 4,096 steps:
3.3 V / 4,096 ≈ 0.8 mV per step
A voice signal around 0.42 mV does not span even one ideal step. Real ESP32 ADC noise is also several steps, so wiring a bare capsule to the ADC produces noise rather than usable quiet speech.
An analog design would therefore require a low-noise preamplifier with roughly 100x to 500x gain before conversion. The INMP441 instead integrates the sensing element, preamplification, and a higher-quality converter, then puts already-digital audio on the wire. This removes the vulnerable low-level analog trace from the ESP32 board and reduces coupling from nearby Wi-Fi activity.
The level ladder
The electret arithmetic above shows why an analogue design would need a preamplifier. The INMP441 avoids that by being digital — but the signal is still weak, and it stays weak right up to the point something deliberately amplifies it. Tracing one voice through the whole system:
The capture half is the one worth following, because it explains a bug report that has now been filed twice.
speech at 1 m 0.02 Pa
94 + 20·log₁₀(0.02) = 60 dB SPL
INMP441 sensitivity −26 dBFS at 94 dB SPL (datasheet)
−26 + 20·log₁₀(0.02) = −60 dBFS
8,388,607 × 10^(−60/20) = 8,409 (24-bit)
narrowed to 16 bits 8,409 / 256 = 33 of 32,767
with MIC_GAIN 8 × 8 = 263 of 32,767
Thirty-three out of 32,767. That is not a quiet recording; it is three thousandths of the available range, which plays back as silence with a noise floor on any speaker you own. The microphone is working exactly to specification, and it sounds broken.
This is the entire justification for the microphone gain setting, and for applying it before the narrowing — at 24-bit width there are still 8,409 counts of real signal to scale, where after narrowing there are 33. Audio diagnostics records how long that took to work out on real hardware, and the I2S runtime covers the arithmetic that does it.
The measured figure on this board — ordinary room ambience peaking near −50 dBFS — sits comfortably above the −60 dBFS this predicts for speech at a metre, which is what a room with a refrigerator in it should look like.
Why a GPIO Cannot Drive the Speaker
For 1 W into an 8-ohm speaker:
RMS voltage = sqrt(1 W × 8 ohm) ≈ 2.83 V
RMS current = 2.83 V / 8 ohm ≈ 354 mA
Peak current = 354 mA × 1.41 ≈ 500 mA
A single ESP32 pin is expected to supply only about 20 mA in this design. The speaker can demand approximately 25 times more. Attempting to source speaker current from a GPIO can damage the chip.
The signal shape is a separate problem. A GPIO normally switches between off and 3.3 V, while speech and music require continuously varying sample amplitudes. Direct toggling produces a square wave, not intelligible playback.
The MAX98357A solves both constraints:
- Its DAC converts PCM sample values into an analog waveform.
- Its power stage supplies the speaker current.
- It can deliver about 1.8 W into 8 ohms from 5 V.
- Its class-D architecture is efficient enough to operate without a heatsink.
Why class-D matters here is thermal, and it follows from how the output stage works. A class-AB amplifier holds its transistors partly on, dropping the difference between the supply and the output across them as heat; efficiency around 50% at best means roughly a watt of heat for a watt of sound. A class-D stage instead switches fully on or fully off at a few hundred kilohertz and varies the duty cycle, then lets the speaker's own inductance average the result back into an analogue waveform. A switch that is fully on drops almost no voltage, and one that is fully off carries almost no current, so either way it dissipates very little — over 90% efficiency in practice.
For a sealed desk object with no airflow and no heatsink, that is the difference between a warm chip and a thermal-shutdown one.
Why Both Devices Use I2S
I2S is a synchronous digital audio bus with three signal roles:
| Signal | Common names | Responsibility |
|---|---|---|
| Bit clock | BCLK, SCK | Advances one transmitted bit per tick |
| Word select | WS, LRC | Marks the left and right sample slots |
| Serial data | SD, DIN, DOUT | Carries sample bits, most-significant bit first |
The ESP32 generates the clocks in both directions. The INMP441 drives its data output toward the ESP32; the ESP32 drives a separate data line toward the MAX98357A.
There is no volume wire and nothing analog anywhere on the bus — just numbers marched across one bit at a time, fast enough that the numbers are the sound.
Digital transport prevents analog noise from entering along these connections. More importantly, the ESP32's I2S peripherals have DMA engines. Audio moves between peripherals and memory without waking the CPU for each bit or sample, so capture and playback do not compete directly with 30 fps animation.
Capture Data Path
The microphone runs at 16,000 samples per second. Each retained PCM sample is signed 16-bit data, or two bytes.
1 sample = 16 retained bits = 2 bytes
16,000 samples/s × 2 B = 32,000 B/s = 32 KB/s
1 sample interval = 1 / 16,000 = 62.5 microseconds
The INMP441 produces 24-bit samples inside 32-bit I2S slots. I2S still clocks a left and a right slot per frame even though the microphone is mono. With the INMP441 L/R pin tied to ground, the microphone occupies the left slot and the right slot is empty.
The wire and stored-data rates differ:
clocked on wire = 16,000 × 64 bits = 1,024,000 bit/s = 128 KB/s
retained audio = 16,000 × 16 bits = 256,000 bit/s = 32 KB/s
Half of the clocked frame is the unused channel, and half of the populated 32-bit slot is precision beyond the selected 16-bit network format. Hardware and DMA discard the unused material; the CPU does not process it sample by sample.
Sixteen-bit signed PCM spans -32768 through 32767, providing 65,536 possible values. The chosen format matches the downstream speech service and uses half the network bandwidth of 24-bit samples.
Playback Data Path
The voice service returns mono speech at 24,000 samples per second. The MAX98357A accepts this rate directly, so the project does not resample it.
1 sample interval = 1 / 24,000 ≈ 41.7 microseconds
24,000 samples/s × 2 B = 48,000 B/s = 48 KB/s
I2S clock = 24,000 × 32 bits = 768,000 bit/s
The mono sample is presented in both I2S slots. The amplifier combines left and right as (L + R) / 2, recovering the original value.
Before a sample reaches I2S, firmware applies a software volume ceiling:
incoming sample = 20,000
volume ceiling = 35%
transmitted sample = 20,000 × 0.35 = 7,000
The MAX98357A can deliver approximately 1.8 W into a speaker rated for 1 W. Scaling every sample protects the speaker by default rather than relying on the user to maintain a safe volume.
End-to-End Data Budget
| Stage | Capture: question leaving | Playback: answer returning |
|---|---|---|
| Physical endpoint | About 0.02 Pa of air pressure | About 1 W of acoustic output |
| Codec or converter | INMP441 at 16 kHz | MAX98357A at 24 kHz |
| I2S clock | About 1.024 MHz | About 768 kHz |
| PCM in memory | 32 KB/s | 48 KB/s |
| Network representation | Approximately 43 KB/s after encoding | Approximately 64 KB/s before decoding |
Only the endpoints handle sound as a physical pressure wave. Between the microphone and amplifier, the system transports integers through I2S, RAM, encryption, Wi-Fi, and the remote service.
Wiring
The source design reserves GPIO 21 and 22 for the OLED, GPIO 4 for the touch pad, and GPIO 34 for battery sensing. The following audio pins were selected because they were free in that design.
INMP441 microphone
| Module pin | Connect to | Purpose |
|---|---|---|
VDD | 3.3 V | Power |
GND | GND | Ground |
SCK | GPIO 32 | I2S bit clock |
WS | GPIO 33 | I2S word select |
SD | GPIO 35 | Audio data from microphone |
L/R | GND | Select left-slot transmission |
MAX98357A amplifier
| Module pin | Connect to | Purpose |
|---|---|---|
VIN | 5 V | Amplifier power and full output range |
GND | GND | Ground |
BCLK | GPIO 26 | I2S bit clock |
LRC | GPIO 25 | I2S word select |
DIN | GPIO 27 | Audio data from ESP32 |
GAIN | Leave floating | Default 9 dB gain |
SD | Leave floating | If the board remains silent, tie to VIN as a diagnostic |
+ / - | 8-ohm speaker | Differential speaker output |
Verify module labels against the actual board revision before applying power. Similar breakout boards can expose different enable, gain, or supply arrangements.
Power Architecture
Peak current is larger than the average consumption suggests:
| Consumer | Expected draw |
|---|---|
| ESP32 with Wi-Fi transmission | About 250 mA, with bursts near 500 mA |
| Amplifier driving the speaker | Up to about 500 mA |
| OLED | About 20 mA |
| Combined peak | Approximately 1,000 mA |
| Typical USB 2.0 computer port | 500 mA |
If a loud sample coincides with a Wi-Fi burst, an undersized supply can sag and reset the ESP32. The symptom resembles a firmware crash.
Use a regulated 5 V supply rated for at least 1 A; a 2 A phone charger provides additional margin. Place a 470-1000 microfarad electrolytic capacitor across amplifier VIN and GND, physically near the board, to cover short current spikes. Observe capacitor polarity.
Component Selection
The reference build uses:
- An INMP441 I2S microphone module with
VDD,GND,L/R,WS,SCK, andSDpins. - A MAX98357A I2S amplifier module rated around 3.2 W into 4 ohms or 1.8 W into 8 ohms.
- A regulated 5 V supply rated for at least 1 A.
- A
470-1000 microfaradelectrolytic capacitor. - Jumper wires and soldered headers appropriate to the modules.
Analog MAX9814 or MAX4466 microphone modules reintroduce the ESP32 ADC and its noise constraints. A PAM8403 analog amplifier requires an analog source, typically the ESP32's limited internal DAC or an external converter. Use those parts only as a fallback when the I2S modules are unavailable and their quality trade-offs are acceptable.
Units Reference
| Unit | Meaning |
|---|---|
| Pa | Pascal, a measure of pressure |
| V / mV | Volt and millivolt, electrical potential |
| A / mA | Ampere and milliampere, electrical current |
| ohm | Resistance; the reference speaker is 8 ohms |
| W | Electrical power, voltage multiplied by current |
| dB | Logarithmic ratio; a negative dBV value is below one volt |
| Hz / kHz | Events per second; audio uses thousands of samples per second |
| bit | One binary digit; bit depth determines the number of sample values |
| byte | Eight bits; one 16-bit PCM sample occupies two bytes |
| KB/s | Thousands of bytes transferred each second |
The safety limit, in watts
The amplifier can deliver more than the speaker is rated for, which is why playback volume is a software limit rather than a trust exercise:
speaker rating 1.0 W into 8 Ω → sqrt(1.0 × 8) = 2.83 V RMS
MAX98357A at 5 V 1.8 W into 8 Ω → sqrt(1.8 × 8) = 3.79 V RMS
the amplifier can exceed the driver by 20·log₁₀(3.79/2.83) = 2.6 dB
Two and a half decibels does not sound like much, and as loudness it is not. As sustained power into a 16 mm driver it is the difference between a speaker and a broken speaker. The playback volume setting at 70% removes 3.1 dB, landing just inside the rating with a little margin, and it is a software limit precisely so that it can be changed without rewiring and cannot be forgotten in hardware.
The amplifier's own GAIN strap is a separate control and does not replace this
one. Raise the software limit first; it needs no power cycle and no soldering.
Failure modes
| Symptom | Cause |
|---|---|
| Device resets when playback gets loud | Supply sag — a loud sample coinciding with a Wi-Fi burst. Looks exactly like a firmware crash |
| Capture is silence with a noise floor | Working as specified; this is the gain setting left at its minimum, at −60 dBFS. See the ladder above |
| Reported microphone peak level permanently exactly zero | The L/R strap disagrees with the configured input channel setting |
| Sudden ~33 dB drop to flatline, wiring still passing continuity | The acoustic port was contaminated; the part is dead. See hardware |
| Amplifier hot enough to notice | Not class-D behaviour — check for a short across the speaker terminals |
| Playback distorts only on loud passages | Clipping above the driver's rating; lower the playback volume setting |
| Hiss or buzz that tracks Wi-Fi activity | An analogue run too close to the radio, or a shared ground return |
| Nothing at all from either device | Voice and I2S support left at its off-by-default setting |
Configuration reference
The electrical choices this page argues for, as the firmware states them.
| Setting | Default | Relevance here |
|---|---|---|
| Voice and I2S support | Off | Set to on only once both parts are wired |
| Input channel selection | Left | Must match the L/R strap |
| Microphone gain | 8x | +18.1 dB; the answer to −60 dBFS |
| Input sample rate | 16,000 Hz | What the speech pipeline expects |
| Output sample rate | 24,000 Hz | What the amplifier is clocked at |
| Playback volume ceiling | 70% | −3.1 dB; the speaker's protection |
Pins are listed in hardware; the driver configuration that uses them is in the I2S runtime.
Referenced Hardware and Documents
| Reference | Responsibility |
|---|---|
| INMP441 datasheet | Microphone sensitivity, digital conversion, I2S timing, and channel selection |
| MAX98357A datasheet | I2S input, gain behavior, supply requirements, and speaker power |
| ESP32 technical reference manual | ADC characteristics, I2S peripherals, and DMA behavior |
| ESP32 I2S Audio Runtime | Firmware tasks, buffers, conversion, and configuration |
| Face rendering and effects | Renderer design and 33 ms non-blocking constraint |