ESP32 DAC True Analog Output Guide: dacWrite vs “Fake PWM”

Prerequisite: PWM Complete Guide. PWM dimming is really “switching fast enough to fool the load” — the pin only ever sits at 0V or 3.3V. This article covers the DAC: genuine continuous voltage output.


1. DAC vs PWM: one letter apart, fundamentally different

AspectPWM (duty cycle)DAC (true analog)
Output levelsOnly 0V / 3.3V (fast switching)Any intermediate voltage (continuous)
PrincipleTime-averaging “fools” the loadResistor ladder divides directly
PinsAny GPIOGPIO25/26 only (classic ESP32)
ResolutionUp to 16 bits theoretically8 bits (256 steps)
Filtering neededDepends on the loadNo
Typical usesLED brightness, motor speedWaveform generation, bias voltage, audio

One-liner: PWM is duty-cycle art; DAC is voltage direct out. LEDs want PWM; sine waves and op-amp bias voltages want a DAC.


2. Per-chip availability (important)

ChipDACNotes
Classic ESP32✅ 2 channels (GPIO25/26)8-bit
ESP32-S2✅ 2 channels (GPIO17/18)8-bit
ESP32-S3❌ no DACUse an external DAC (e.g. MCP4725 over I2C)
ESP32-C3/C6❌ no DACSame

New project on S3/C3 that truly needs analog out: the MCP4725 module (12-bit, I2C, ~¥3) is the standard answer — wiring covered in the buses guide.


3. dacWrite in five minutes

#define DAC_PIN 25   // must be 25 or 26!

void setup() { /* DAC needs no pinMode setup */ }

void loop() {
  dacWrite(DAC_PIN, 0);     // 0V
  delay(1000);
  dacWrite(DAC_PIN, 128);   // ~1.65V
  delay(1000);
  dacWrite(DAC_PIN, 255);   // ~3.3V
  delay(1000);
}

4. Project: generating a sine wave

#define DAC_PIN 25

void setup() {
  Serial.begin(115200);
}

void loop() {
  // 100Hz sine: 100 points per cycle, 100µs each
  for (int i = 0; i < 100; i++) {
    float v = (sinf(i * 2 * PI / 100) + 1) / 2 * 255;
    dacWrite(DAC_PIN, (int)v);
    delayMicroseconds(100);
  }
}

Replacing delayMicroseconds with a hardware timer yields a rock-stable frequency — the four-layer selection from the timers guide applies directly.

Ceiling: DAC conversion takes ~8µs → theoretical max square wave ~1MHz, practical sines in the tens of kHz. Voice-grade audio: fine. HiFi: no.


5. Primer: audio in half a page

DAC + amp (MAX98357A) is the simplest ESP32 audio chain. The modern approach is I2S digital audio (higher precision, doesn’t consume the DAC) — an L3 topic with its own article. DAC audio’s value is understanding the principle: looping dacWrite over PCM samples at the sample rate is bare-metal audio output.


6. Pitfall cheat sheet

ScenarioVerdict
Calling dacWrite on S3/C3No DAC — may compile but outputs nothing; use MCP4725
Wanting ADC on GPIO25/26These are also ADC2 channels — conflict once Wi-Fi starts
DAC can’t drive the loadHigh output impedance — add an op-amp follower
Wobbly waveform frequencydelay jitter — drive from a hardware timer
Need 12-bit precisionExternal MCP4725 (I2C); the built-in one is 8-bit
Should LEDs use the DAC?No — PWM is enough and works on any pin

7. Further reading


License: CC BY-SA 4.0. Repost & remix with attribution: ESPDIY Maker Lab - espdiy.com