I’ve been tinkering with SparkFun’s MCP4725 I2C Digital to Analog converter or DAC. Buy yours here. I have been reading about the I2C or Two-Wire protocol but this is the first time I’ve used it. I did not see a useful tutorial out there for this breakout board (aka BoB) so I decided to throw one together. This is a 12-bit wide DAC, thus it has resolution equal to Vcc/4096. (2^12 = 4096). 5V/4096 =1.22mV per step. First, the wiring diagram:

The nice thing about the BoB is that it takes care of all the hassle of pullup resistors and filtering capacitors. I have a protoboard afixed to my Arduino, and all the wiring fits comfortably atop. Now for the hard part, software. Digging around the Microchip website, I found the technical documentation on the MCP4725 which was quite useful. Also, the Arduino website helped me understand the TWI/I2C library. The code below produces a 10Hz, 5Vpk square wave. I will do my best to explain what is going on below.

#include

void setup()
{
Wire.begin();
}

byte ON = 255; // All bits high will give maximum output, Vcc, which is 5V.
byte OFF = 0; // All bits low will give minimum output, GND, which is 0V.
byte Program = 64; // See below for more details, but this sets the DAC register to receive new data
byte Device = 96; // This hardwired into the IC and the BoB, in other words, it is a given.

void loop()
{
Wire.beginTransmission(Device);
Wire.send(Program);
Wire.send(ON);
Wire.send(ON); // Needed twice, since the 4 lowest bits (of 12) are in the fourth byte
Wire.endTransmission();

delay(50);

Wire.beginTransmission(Device);
Wire.send(Program);
Wire.send(OFF);
Wire.send(OFF); // Needed twice, since the 4 lowest bits (of 12) are in the fourth byte
Wire.endTransmission();

delay(50);
}

A complete data package on I2C for this DAC is a follows (4 bytes long):

Byte 1 = Device ID (7 bits) and Read/Write command (1 bit)
Byte 2 = Program DAC register and/or EEPROM (3 bits) and power down logic (2 bits)
Byte 3 = 8 bits (MSb) of the 12 bits for this DAC.
Byte 4 = Remaining 4 bits (LSb) for this DAC. The bottom four bits of this byte are ignored.

The first byte is handled for you with the Wire.beginTransmission(Device) function. Remember Device = 96 is a given. Now for the interesting part, the control bits of the second byte. The byte is made of the following bits, X indicates unused and thus don’t care cases.

C2 C1 C0 X X PD1 PD0 X

C2 -> C0 control whether you write to the DAC register (0,1,0) or both the register and EEPROM (0,1,1). Also the bit pattern (0,0,X) changes the DAC register to Fast Mode.

PD1 -> PD0 control how power down is handled.

0,0 is normal operating mode.
0,1 is a power saving mode where all the internal logic is off, there is no Vout. Think of it as sleep mode and will only react to a command to return to normal operating mode. In this case, the output is shunted through a 1k-ohm load.
1,0 is the same, except it is now shunted through a 100k-ohm load.
1, 1 is now a 500k-ohm load.

In my example, the Program byte = 64, which is:

C2 C1 C0 X X PD1 PD0 X = 0 1 0 0 0 0 0 0

This means I am only making changes to the DAC register. I am NOT in fast mode. I am in normal operating mode.

Can you make other waveforms? Sure, you just need to mess with the 3rd and 4th bytes as you go through the loop. Perhaps start high and subtract away 5 or 10 every pass until you get to 0, then starting adding 5 or 10. For me, square waves are just fine for now. Hope this helps, please provide feedback!