Zbotic Logo Zbotic Logo
  • Home
  • Shop
  • Sale
  • 3D Print Service
  • PCB Service
  • B2B
  • Blogs
  • Contact Us
0 0

View Wishlist Add all to cart

0 0
0 Shopping Cart
Shopping cart (0)
Subtotal: ₹0.00

View cartCheckout

  • Shop
  • About Us
  • Contact Us
  • Reseller
  • Blogs
020 69134444
1800 209 0998
[email protected]
Help Desk
Facebook Twitter Instagram Linkedin YouTube
Zbotic Logo Zbotic Logo
0 0

View Wishlist Add all to cart

0 0
0 Shopping Cart
Shopping cart (0)
Subtotal: ₹0.00

View cartCheckout

All departments
  • 3D Print Service
  • 3D Printer
  • Batteries & Chargers
  • Development Boards
  • Drone Parts
  • EBike parts
  • Sensor Modules
  • Electronic Components
  • Electronic Modules
  • IoT and Wireless
  • Mechanical Parts and Workbench Tools
  • Motors & Drivers & Pumps & Actuators
  • DIY and Robot Kits
  • Show more
  • Home
  • Shop
  • Sale
  • 3D Print Service
  • PCB Service
  • B2B
  • Blogs
  • Contact Us
Return to previous page
Home Arduino & Microcontrollers

Arduino DAC Output: Generate True Analog Voltage

Arduino DAC Output: Generate True Analog Voltage

March 11, 2026 /Posted byJayesh Jain / 0

If you’ve wondered how to produce a true Arduino DAC analog output — a clean, continuously variable voltage rather than the stuttery approximation of PWM — you’re in the right place. Digital-to-Analog Conversion (DAC) is essential for audio generation, signal synthesis, calibrated voltage sources, and any application where PWM’s switching noise is unacceptable. This guide covers every practical method from low-cost external ICs to native DAC hardware on advanced Arduino boards.

Table of Contents

  • PWM vs True DAC: What’s the Difference?
  • MCP4725: The Go-To External DAC for Arduino
  • MCP4725 Wiring and Complete Code
  • Native DAC on Arduino Due, Zero, and MKR
  • Waveform Generation: Sine, Sawtooth, Triangle
  • Arduino Audio Output with DAC
  • DIY R-2R Ladder DAC
  • Frequently Asked Questions

PWM vs True DAC: What’s the Difference?

When most Arduino tutorials say “analog output”, they mean PWM (Pulse-Width Modulation). PWM rapidly switches a digital pin between 0V and 5V, varying the on-time ratio (duty cycle) to produce an average voltage. An LED or motor responds to this average and behaves as if the voltage is variable. But the actual signal is a square wave switching at 490Hz or 980Hz — not a smooth voltage at all.

A true DAC (Digital-to-Analog Converter) outputs a genuine, steady DC voltage at any value within its range. The output is set digitally (a number written over a bus or to a register) and the DAC produces the corresponding voltage with no switching, no ripple, and no need for filtering. The differences matter enormously in practice:

  • Audio circuits: PWM’s 490Hz switching frequency falls squarely in the audio band and creates audible noise. DAC output is clean.
  • Sensor simulation: Testing an analog sensor input? PWM will interfere with the ADC’s auto-scaling. A DAC gives a stable reference.
  • Precision control: Controlling a variable gain amplifier or an analog potentiometer digitally requires a true DC voltage, not a PWM average that ripples with load.
  • Signal generation: Function generators and arbitrary waveform generators (AWG) require true DAC output to produce clean sinusoids and other waveforms.
Recommended: Arduino Nano 33 IoT with Header — Compact and powerful; pairs beautifully with the MCP4725 DAC over I2C for IoT-connected analog signal generation.

MCP4725: The Go-To External DAC for Arduino

The MCP4725 from Microchip is a 12-bit, single-channel DAC that communicates over I2C. It is the most popular DAC breakout for Arduino, and for good reason: it costs little, needs only 4 wires, has a built-in non-volatile memory (EEPROM) to store a power-on default voltage, and covers 0–VCC output range with 12-bit resolution (4096 steps).

Key Specifications

  • Resolution: 12-bit (4096 steps)
  • Output range: 0V to VCC (0–3.3V or 0–5V depending on supply)
  • Output current: 25mA max (buffer the output for higher currents)
  • Interface: I2C (up to 400kHz fast mode)
  • Supply voltage: 2.7V–5.5V
  • I2C address: 0x60 or 0x61 (configurable via A0 pin)
  • EEPROM: Stores power-on DAC value persistently
  • Update rate: ~250kHz maximum (limited by I2C speed)

Voltage Resolution Calculation

With a 5V supply and 12-bit resolution: each step = 5V / 4095 ≈ 1.22mV. You can set any voltage from 0V to ~4.998V in 1.22mV increments. This is far better than PWM’s effective resolution (~8-bit in practice), and without the switching noise.

MCP4725 Wiring and Complete Code

Wiring

MCP4725 Pin Arduino Uno
VCC 5V
GND GND
SDA A4
SCL A5
OUT To your analog load

Basic Output Code (using Adafruit MCP4725 library)

#include <Wire.h>
#include <Adafruit_MCP4725.h>

Adafruit_MCP4725 dac;

void setup() {
  Serial.begin(115200);
  // 0x60 is default addr; use 0x61 for second module
  if (!dac.begin(0x60)) {
    Serial.println("MCP4725 not found!");
    while (1);
  }
}

void loop() {
  // Ramp output 0V to 5V
  for (uint16_t v = 0; v <= 4095; v += 16) {
    dac.setVoltage(v, false); // false = don't save to EEPROM
    delay(10);
  }
  // Set specific voltage: 2.048V on a 5V supply → 4096 * 2.048/5 = 1678
  dac.setVoltage(1678, false);
  delay(2000);
  
  // Save to EEPROM (power-on default)
  dac.setVoltage(2048, true); // 2.5V default on power-up
  delay(100);
}

Direct I2C for Maximum Speed

For the fastest possible update rate (e.g., waveform generation), skip the library and write directly:

void dac_write_fast(uint16_t value) {
  Wire.beginTransmission(0x60);
  // Fast write mode: C2=0, C1=1, C0=0
  Wire.write(0x40); // Command: Write DAC register, no EEPROM
  Wire.write(value >> 4);         // Upper 8 bits
  Wire.write((value & 0x0F) << 4); // Lower 4 bits
  Wire.endTransmission();
}

With 400kHz I2C, each call takes about 60µs, giving ~16,000 updates per second — adequate for audio up to 8kHz sample rate.

Recommended: Arduino Uno R3 Beginners Kit — Everything you need to start experimenting with the MCP4725 DAC, including the breadboard and jumper wires for the I2C connection.

Native DAC on Arduino Due, Zero, and MKR

Some Arduino boards include a built-in DAC with no external hardware required:

Arduino Due

The Due (SAM3X8E, 84MHz) has two 12-bit DAC channels on pins DAC0 and DAC1. Output range is 0.55V–2.75V (not full rail-to-rail). Use analogWrite() with values 0–4095:

// Due native DAC
analogWriteResolution(12); // Enable 12-bit writes
analogWrite(DAC0, 2048);   // ~1.65V midpoint

The Due’s DAC can update at up to 500kHz — fast enough for high-quality audio output. This makes the Due genuinely useful as a waveform generator or audio player without any additional hardware.

Arduino Zero and MKR Series

The Zero (SAMD21) has one 10-bit DAC on pin A0. Update with:

analogWriteResolution(10);
analogWrite(A0, 512); // 0–1023 range, 0–3.3V output

Arduino Nano RP2040 Connect

The RP2040 does not have a hardware DAC. However, the MCP4725 over I2C or an R-2R ladder DAC via GPIO are both practical options. The RP2040’s two cores allow one core to handle DAC updates continuously while the other handles communication or processing.

Recommended: Arduino Nano RP2040 Connect with Header — Dual-core RP2040 with WiFi; use one core for continuous DAC updates via MCP4725 and the other for processing, giving you a network-connected waveform generator.

Waveform Generation: Sine, Sawtooth, Triangle

Pre-compute a lookup table (LUT) for efficiency. Calculating sin() in real time is far too slow for audio-rate updates:

#include <Wire.h>
#include <Adafruit_MCP4725.h>

Adafruit_MCP4725 dac;

#define SAMPLES 256
uint16_t sineLUT[SAMPLES];

void setup() {
  dac.begin(0x60);
  Wire.setClock(400000); // Fast I2C
  
  // Pre-compute sine LUT (0 to 4095 range)
  for (int i = 0; i < SAMPLES; i++) {
    sineLUT[i] = (uint16_t)(2047.5 + 2047.5 * sin(2.0 * PI * i / SAMPLES));
  }
}

void loop() {
  // Output sine wave at ~62Hz (256 samples × 16kHz/256 ≈ limited by I2C)
  for (int i = 0; i < SAMPLES; i++) {
    dac_write_fast(sineLUT[i]);
  }
}

void dac_write_fast(uint16_t value) {
  Wire.beginTransmission(0x60);
  Wire.write(0x40);
  Wire.write(value >> 4);
  Wire.write((value & 0x0F) << 4);
  Wire.endTransmission();
}

For a sawtooth, replace the LUT generation with: sineLUT[i] = (uint16_t)(i * 4095.0 / (SAMPLES - 1));

For a triangle: sineLUT[i] = (i < SAMPLES/2) ? i * (4095 / (SAMPLES/2)) : 4095 - (i - SAMPLES/2) * (4095 / (SAMPLES/2));

Arduino Audio Output with DAC

Playing 8-bit audio samples through a DAC is a classic project. The key requirements are:

  • Sample data stored in flash as a byte array (use the Python audioconvert tool or Audacity to export raw PCM)
  • A timer interrupt to output samples at a precise rate (8kHz = one sample every 125µs)
  • A low-pass filter and small audio amplifier on the DAC output
// Using Arduino Due native DAC for 22kHz audio
#include "AudioSample.h" // Array of uint16_t samples

volatile uint32_t samplePos = 0;

void TC0_Handler() {
  TC_GetStatus(TC0, 0); // Clear interrupt flag
  if (samplePos < SAMPLE_COUNT) {
    dacc_write_conversion_data(DACC, audioSamples[samplePos++]);
  } else {
    samplePos = 0; // Loop
  }
}

void setup() {
  analogWriteResolution(12);
  // Configure Timer Counter 0 for 22050Hz interrupts
  // (full setup code omitted for brevity — see Arduino Due audio examples)
}

For a complete audio player project on the Due, the ArduinoSound library abstracts much of this complexity and supports I2S output for even better quality.

DIY R-2R Ladder DAC

If you have no I2C DAC and need fast analog output right now, build an R-2R ladder from resistors. An 8-bit R-2R ladder uses 8 digital output pins and a network of R and 2R resistors (typically 10kΩ and 20kΩ) to produce 256 output levels.

The resistor network sums the binary-weighted voltages from each pin. Connect the ladder’s output to any analog circuit. This approach gives an 8-bit DAC with update rates limited only by the speed you can write to the output ports — using direct port manipulation, you can achieve output rates above 100kHz on an Arduino Uno.

// Direct port write for maximum speed (uses PORTD pins 0-7)
void r2r_write(uint8_t value) {
  PORTD = value; // Writes all 8 bits atomically
}

void loop() {
  for (uint16_t i = 0; i < 256; i++) {
    r2r_write(i);
    delayMicroseconds(100); // 10kHz sawtooth
  }
}

Drawbacks: uses 8 GPIO pins, resistor matching tolerances affect linearity, and the output impedance is not negligible. For precision applications, use the MCP4725. For high-speed audio generation where you already have resistors on hand, the R-2R approach is hard to beat in simplicity.

Recommended: Arduino Mega 2560 R3 Board — Plenty of GPIO pins for a multi-bit R-2R DAC ladder, plus multiple hardware timers for precise sample rate generation in audio projects.

Frequently Asked Questions

Does Arduino Uno have a DAC?

No. The Arduino Uno has no native DAC. It only has PWM outputs. For true analog output, add an external DAC like the MCP4725 (I2C) or build an R-2R ladder DAC. The Arduino Due and Zero/MKR boards include native DAC hardware.

What is the difference between analogWrite() and a real DAC?

analogWrite() on standard Arduinos outputs a PWM square wave, not a true analog voltage. The average voltage equals duty_cycle × VCC, but the actual signal switches rapidly between 0V and 5V. A true DAC outputs a steady DC voltage with no switching. For applications sensitive to noise (audio, precision analog, ADC reference), a real DAC is essential.

How many volts can the MCP4725 output?

The MCP4725 output range is 0V to VCC (the supply voltage). If powered from 5V, it outputs 0–5V. If powered from 3.3V, output is 0–3.3V. The output at full scale (DAC code 4095) is approximately VCC – 1 LSB, essentially full rail.

Can I use two MCP4725 modules at the same time?

Yes. The MCP4725 has two address options: 0x60 (default, A0=GND) and 0x61 (A0=VCC). This gives you two independent DAC channels on the same I2C bus. For more channels, use the MCP4728 which provides four 12-bit DAC outputs in a single chip.

What sample rate can I achieve for Arduino audio with the MCP4725?

With 400kHz I2C and the fast write method, approximately 16,000 samples per second (16kSPS). This allows audio bandwidth up to about 8kHz — adequate for voice and simple audio effects. For higher quality audio, use the Arduino Due’s native 12-bit DAC which updates far faster, or use an I2S DAC module.

Ready to generate real analog signals with Arduino? Shop our full range of Arduino boards and accessories at Zbotic — with fast shipping across India.

Tags: Analog Output, Arduino, DAC, Electronics, MCP4725, Waveform Generator
Share Post
  • Facebook
  • Linkedin
  • Whatsapp
Arduino TFT Display: ST7789 an...
blog arduino tft display st7789 and ili9341 graphics guide 594701
blog arduino spi communication how to interface multiple devices 594709
Arduino SPI Communication: How...

Related posts

Svg%3E
Read more

Arduino Batch Programming: Flash Multiple Boards Quickly

April 1, 2026 0
Table of Contents Introduction Components and Hardware Setup Wiring Diagram and Connections Complete Code with Explanation Customization and Improvements Troubleshooting... Continue reading
Svg%3E
Read more

Arduino Based Radar System with Ultrasonic Sensor

April 1, 2026 0
Table of Contents Introduction Components and Hardware Setup Wiring Diagram and Connections Complete Code with Explanation Customization and Improvements Troubleshooting... Continue reading
Svg%3E
Read more

Arduino Automatic Plant Monitor: Sunlight, Moisture, Temperature

April 1, 2026 0
Table of Contents Introduction Components and Hardware Setup Wiring Diagram and Connections Complete Code with Explanation Customization and Improvements Troubleshooting... Continue reading
Svg%3E
Read more

Arduino Lie Detector: GSR Sensor Polygraph Project

April 1, 2026 0
Table of Contents Introduction Components and Hardware Setup Wiring Diagram and Connections Complete Code with Explanation Customization and Improvements Troubleshooting... Continue reading
Svg%3E
Read more

Arduino Metal Detector: Build a Treasure Finder

April 1, 2026 0
Table of Contents Introduction Components and Hardware Setup Wiring Diagram and Connections Complete Code with Explanation Customization and Improvements Troubleshooting... Continue reading

Add comment Cancel reply

Your email address will not be published. Required fields are marked

Facebook Twitter Instagram Pinterest Linkedin Youtube

Get the latest deals and more.

Download on Google Play Download on the App Store

Call us: 020 69134444 / 1800 209 0998

Monday - Saturday 09:30 AM - 06:00 PM
For Technical Supports Email: [email protected]
For Sales / Enquiries Email: [email protected]

  • My Account

    • Cart

    • Wishlist

    • Checkout

    • My Orders

    • Track Order

    • My Account

  • Information

    • FAQs

    • Blogs

    • Career

    • About Us

    • Contact Us

    • Payment Options

  • Policies

    • Privacy Policy

    • Terms & Conditions

    • GST Input Tax Credit

    • Shipping Return Policy

    • E-Waste Collection Points

    • Our Sitemap

© Zbotic.in is registered trademark of Moxie Supply Pvt Ltd – All Rights Reserved
Login
Use Phone Number
Use Email Address
Not a member yet? Register Now
Reset Password
Use Phone Number
Use Email Address
Register
Already a member? Login Now