A Digital-to-Analog Converter (DAC) translates discrete digital binary numbers into continuous analog voltage or current signals. In a real circuit, a DAC changes your microcontroller's rigid 0V or 3.3V logic pins into smooth, variable voltages, bridging the gap between digital code and the physical world to enable audio playback, precise motor control, and programmable power supplies.
Without a DAC, a microcontroller can only shout in binary—either fully on or fully off. With one, it can whisper at exact voltage levels. But choosing the right DAC, and understanding its limitations, is where most hobbyist builds either succeed or end up with noisy, distorted outputs.
The Core Mechanism: Translating Bits to Volts
Internally, a DAC uses a network of precision resistors (like an R-2R ladder) or switched capacitors to sum fractional voltages based on the binary input. When you send a digital word to the DAC, it closes specific internal switches to tap into a reference voltage, outputting the exact corresponding analog level.
Let us look at a concrete numeric example using a standard 12-bit I2C DAC like the MCP4725. If your reference voltage (VREF) is 3.3V, the DAC divides that range into $2^{12}$ (4,096) discrete steps.
2048, the DAC outputs exactly 1.65V. If it sends 2049, the output bumps to 1.6508V.
This step size is your resolution. You cannot output 1.6504V with this chip; it will round to the nearest 0.8mV increment. This rounding error is called quantization noise, and it is the primary reason high-fidelity audio requires 16-bit or 24-bit DACs.
PWM vs. True DAC: The Most Common Bench Confusion
The most frequent mistake makers make is assuming Pulse Width Modulation (PWM) is the same as analog output. When you use analogWrite() on an Arduino Uno, you are not using a DAC. You are outputting a 5V/0V digital square wave and varying the duty cycle.
To turn PWM into a usable DC voltage, you must add an external RC low-pass filter (a resistor and a capacitor) to average the square wave. A true DAC, however, outputs the actual target voltage instantly from its pin without requiring a smoothing filter for DC applications.
| Feature | True DAC (e.g., MCP4725) | PWM + RC Filter |
|---|---|---|
| Output Type | Steady DC voltage | Ripple-heavy averaged DC |
| Component Count | DAC IC + decoupling caps | Resistor + Capacitor |
| Update Speed | Fast (up to MHz I2S rates) | Slow (limited by RC time constant) |
| Audio Quality | High (with proper bit depth) | Poor (high noise floor) |
Where You Meet DACs in Practice (and Which Chip to Choose)
You will encounter DACs in several common embedded scenarios. Picking the right architecture depends entirely on your bandwidth and precision requirements.
- Audio Generation: Audio requires high update rates (44.1kHz to 96kHz) and 16-bit+ resolution. You will use an I2S DAC like the PCM5102A. I2S is a dedicated clock-and-data protocol designed specifically to stream audio samples without timing jitter.
- Control Voltage (CV) & Synths: Analog synthesizers use 1V/octave control signals. A 12-bit or 16-bit I2C/SPI DAC like the MCP4725 or AD5683 is perfect here because update speeds are low, but DC precision is critical.
- Programmable Power Supplies: If you are building a bench power supply and need to set a precise voltage limit via a microcontroller, you use a DAC to feed the feedback pin of a buck converter or linear regulator.
- Internal Microcontroller DACs: Chips like the ESP32, STM32, and SAMD21 have built-in DACs. These are convenient for basic function generation (sine/triangle waves) but usually lack the drive strength and linearity required for professional audio.
Bench Scenario: Why Your ESP32 Audio Output Sounds Like a Buzzsaw
Let us walk through a real-world failure scenario that catches almost everyone the first time they try to play audio on an ESP32.
The Setup
You wire the internal 8-bit DAC of an ESP32 DevKit v1 (GPIO 25) directly to the input of a 3W PAM8403 Class-D amplifier, which drives a small speaker. You write an Arduino sketch using a timer interrupt to push an 8kHz sine wave array to the dacWrite() function.
The Numbers
The ESP32 internal DAC is 8-bit. That means 256 steps across a 3.3V range. Your step size is 12.8mV. You are sampling at 8,000 times per second.
The Outcome
Instead of a clean sine wave tone, the speaker emits a harsh, distorted buzzing sound. When the sketch starts, there is a loud, speaker-popping thump.
What Went Wrong
- Quantization Noise: 12.8mV steps are massive in the audio world. The staircase approximation of your sine wave introduces heavy harmonic distortion.
- Missing Reconstruction Filter: The DAC is updating at 8kHz. According to the Nyquist theorem, this creates imaging frequencies at 8kHz and above. Without an analog low-pass filter (reconstruction filter) between the ESP32 and the amp, the amplifier is trying to reproduce high-frequency digital switching noise, which sounds like a buzz.
- Rail Non-Linearity: As documented in Espressif hardware guides, the internal ESP32 DAC is highly non-linear near 0V and 3.3V. When your sine wave hits its peaks and troughs, the voltage flattens out, causing severe clipping.
- The Startup Pop: GPIO 25 defaults to 0V. When the DAC initializes, it jumps to the first value in your sine array (which might be mid-scale, 1.65V). That instant 1.65V DC offset step is amplified into a loud pop.
Frequently Asked Questions
Can I use a DAC to drive a DC motor directly?
No. A DAC outputs a low-current voltage signal (usually maxing out at 10mA to 20mA). A motor requires hundreds of milliamps or more. You must use the DAC to generate a reference voltage, and feed that voltage into the control pin of a dedicated motor driver IC or an operational amplifier configured for high current.
What is the difference between I2C and I2S for DACs?
I2C is a general-purpose, low-speed control protocol used to send configuration commands or slow-changing DC voltage values to a DAC. I2S (Inter-IC Sound) is a high-speed, continuous streaming protocol with dedicated clock lines designed specifically to push thousands of audio samples per second without timing jitter.
Why does my DAC output read 0.1V when I send a value of 0?
Many DACs cannot swing perfectly to the ground rail (0V) due to the internal transistor architecture. This is known as the 'zero-scale error' or 'headroom limitation'. If you need true 0.000V output, you must select a DAC specifically advertised as 'rail-to-rail output' or use a negative supply rail to pull the output fully to ground.






