🛠 Générer une vraie tension analogique avec les DAC 12 bits (broches 66 et 67)
Objectives
Use what almost no other classic Arduino has: TWO true 12-bit analog outputs (the DACC peripheral), on pins DAC0 = digital pin 66 and DAC1 = pin 67. No more PWM that needs filtering: here the output voltage directly follows the written value, between 0 and 3.3 V. You will generate a ramp and then a sine wave, and uncover the issue with the default resolution (8 bits when writing!).
Hardware
- 1 Arduino Due
- 1 oscilloscope (or a multimeter for the slow version) + ground probe
- Micro-USB cable
- Headphones/piezo possible in a variant (via a 1 µF coupling capacitor)
Complete code
// Rampe + sinusoïde sur DAC0 (broche 66) — DACC 12 bits
#include <math.h>
const uint8_t DAC0_PIN = DAC0; // 66 (PB15). DAC1 = 67 (PB16)
void setup {
analogWriteResolution(12); // sans ça : écritures 8 bits (0..255) par défaut !
SerialUSB.begin(115200);
}
void loop {
// 1) Rampe en dents de scie 0..4095
for (int v = 0; v <= 4095; v += 32) {
analogWrite(DAC0_PIN, v);
delay(2);
}
// 2) Sinusoïde centrée 0..4095 autour de 1,65 V
for (int i = 0; i < 64; i++) {
float t = i * 2.0f * PI / 64.0f;
int v = 2048 + (int)(2000.0f * sinf(t));
analogWrite(DAC0_PIN, v);
delay(2);
}
SerialUSB.println("cycle DAC0 terminé");
}
Expected verification
On the oscilloscope (DC coupling, time base ~50 ms/div), pin 66 shows a true continuous ramp — not PWM square waves — rising from 0 to ~3.3 V, then a sine wave sampled in steps of 32/4096 ≈ 25 mV. With a multimeter in DC mode, a fixed written value (e.g., 2048) gives ~1.65 V immediately, without an RC filter.
Common errors
- Forgetting
analogWriteResolution(12): the core writes in 8 bits by default, your values 0–4095 are clipped to 255 and the voltage caps at ~2/3 of the range… without any error message. - Looking for the DAC on PWM pins 2–13: PWM (12 pins, 8 bits / 1 kHz by default) is NOT the DAC; the only true analog outputs are 66 and 67.
- Measuring with a poorly placed oscilloscope ground and concluding the signal is noisy: place the GND clip as close as possible to DAC0.
- Expecting current: the DACC drives logic, not a loudspeaker; add an operational amplifier or a power transistor for any actuator.
- Confusing DAC0 (66) with a Mega-format digital pin: on a Due, pin 66 is real, but on a shield designed for Mega it is occupied — check the pinout before stacking.
- Outputting out of range: the output never exceeds 0–3.3 V, any 5 V expectation on the receiving side requires an amplifier.
Other tutorials for this board
- Faire clignoter la LED de l'Arduino Due et apprivoiser ses deux ports USB
- Lire un potentiomètre avec le vrai ADC 12 bits de la Due
- Allumer une LED externe en respectant les broches 3,3 V et 9 mA de la Due
- Dialoguer avec un GPS (ou tout module TTL) sur Serial1 sans bloquer la boucle
- Scanner les deux bus I2C de la Due (Wire sur 20/21, Wire1 sur 70/71)
- Monter la Due sur un bus CAN 500 kbit/s avec un transceiver externe
Code examples for this board
clignotante.inoArduinobouton-led.inoArduinodac-onde.inoArduinoadc-12-bits.inoArduinopwm-12-bits.inoArduinogps-serial1.inoArduino