MCP4725 DAC
The MCP4725 12-bit I2C DAC on its breakout: a real analog voltage on VOUT, VCC x code / 4096, with an EEPROM that keeps it.
Aliases: MCP4725, MCP4725A0, MCP4725A1, CJMCU-4725, I2C DAC, 12-bit DAC, digital to analog converter.
An Uno has no true analog output: analogWrite() is PWM. The MCP4725 is the usual
fix, a single 12-bit DAC on I2C. Set a code from 0 to 4095 and VOUT sits at that
fraction of the supply, steady, for an LED, a meter, an op-amp or another board's
analogRead().
#include <Wire.h>
#include <Adafruit_MCP4725.h>
Adafruit_MCP4725 dac;
void setup() {
dac.begin(0x60); // the generic boards; Adafruit's is 0x62
dac.setVoltage(2048, false); // half the supply; true also stores it
}
void loop() {}
Pins
| Pin | What it does |
|---|---|
VCC |
Supply, 2.7 to 5.5 V. It is also the reference: VOUT is a fraction of it. |
GND |
Ground. |
SDA, SCL |
I2C, with 10k pull-ups on the board. |
A0 |
Address bit, pulled down on the board. Wire it to VCC for the second address. |
VOUT |
The output: VCC x code / 4096. |
Properties
model is the part number, which fixes the address: the MCP4725A0 (the default, on
the generic purple boards) answers 0x60, or 0x61 with A0 high; the MCP4725A1, on
Adafruit's board, 0x62 or 0x63. A2 and A3 are 0x64 to 0x67. An I2C scanner finds it
where the real one would be.
Libraries
Adafruit_MCP4725.h: begin(address) and setVoltage(code, writeEEPROM). Its
default address is 0x62, Adafruit's board, so pass 0x60 for a generic one.
MCP4725.h (Rob Tillaart): MCP4725 MCP(0x60);, then Wire.begin() and
MCP.begin(). setValue(), setVoltage(volts) against setMaxVoltage(),
setPercentage(), writeDAC(value, true) for the EEPROM, ready(), readDAC(),
readEEPROM(), the power-down modes, powerOnReset() and powerOnWakeUp().
What the model gets right
Every write command. The fast write (two bytes, repeatable in one transfer), the three-byte write of the DAC register, and the same with the EEPROM. The output moves at the acknowledge, as the datasheet says.
The EEPROM. A new chip starts at mid-scale, 0x800, the factory value. A write to the EEPROM keeps the chip busy for 25 ms: the RDY/BSY bit reads 0 and any write in that time is ignored. At power-on, and at a general call reset, the chip loads the EEPROM into its output, so a value stored before a power cycle comes back after it. The EEPROM lasts for the run; a new run starts from the factory value.
Reads. Five bytes: status with RDY/BSY and the power-down bits, the DAC register, and the EEPROM.
Power-down. Modes 1, 2 and 3 turn the output off and leave 1k, 100k or 500k to
ground on VOUT. A write in normal mode, or a general call wake-up, ends it.
A real output. VOUT is a voltage source behind 1 ohm (the datasheet's output
impedance), so a load on it divides as it would on the bench.
What it does not model
The output amplifier's 25 mA limit and its swing short of the rails under load, offset and gain error, the 6 us settling time and glitches, high-speed I2C mode, EEPROM wear, and the slow power-up that can make a real chip miss loading its EEPROM. An EEPROM write cut short by the supply leaves the old value.
Common mistakes
The wrong address: the Adafruit library defaults to 0x62, the generic boards are at
0x60. Run an I2C scanner, or call begin(0x60).
Writing the EEPROM in a loop: each write takes 25 ms and wears the cell. Store a value once, at the end; set the output with plain writes.