TI’s TLV5620 is a budget 4-channel 8-bit DAC. While it is designed primarily for running with a power supply between 3V and 3.6V, it can be powered by 5V as well given its wide supply voltage range. With a TL431 voltage reference (2.5V), the DAC output can cover 0-5V with the RNG bit set.
It is very easy to interface TLV5620 with an Arduino. The code below illustrates how this is done:
const int PIN_DATA = 2; const int PIN_CLK = 3; const int PIN_LOAD = 4; const int PIN_LDAC = 5; void setup() { setupTLV5620(); } void setupTLV5620() { pinMode(PIN_DATA, OUTPUT); pinMode(PIN_CLK, OUTPUT); pinMode(PIN_LOAD, OUTPUT); pinMode(PIN_LDAC, OUTPUT); } void setDAC(byte channel, byte val) { shiftOut(PIN_DATA, PIN_CLK, MSBFIRST, channel << 1); // A1 A0 RNG (where RNG=0, X1 output) shiftOut(PIN_DATA, PIN_CLK, MSBFIRST, val); digitalWrite(PIN_LOAD, LOW); digitalWrite(PIN_LOAD, HIGH); digitalWrite(PIN_LDAC, LOW); digitalWrite(PIN_LDAC, HIGH); } void loop() { //This example outputs a staircase signal with 8 steps for (int i = 0 ; i < 8; i++) setDAC(1,i*32); }
TLV5620’s control signal consists of 11 bits:
A1 A0 RNG D7 D6 D5 D4 D3 D2 D1 D0
And they are shifted out using 2 bytes of data. The setDAC method above outputs 0V to Vref for an input value between 0 and 255. As mentioned earlier, when using a 2.5V voltage reference, we can use the x2 feature (by setting the RNG bit) to cover the entire 5V Vcc range. All we need to do is to change the first line of code in setDAC to:
shiftOut(PIN_DATA, PIN_CLK, MSBFIRST, channel << 1 | 1); // A1 A0 RNG (where RNG=1, X2 output)
If the outputs from multiple channels need to be synchronized, we can load all channels first and then latch the data onto the DAC outputs at the end. The following example for instance, outputs to two DAC channels simultaneously:
void setDAC2(byte cn1, byte cn2, byte val1, byte val2) { shiftOut(PIN_DATA, PIN_CLK, MSBFIRST, cn1 << 1); // A1 A0 RNG (where RNG=0, X1 output) shiftOut(PIN_DATA, PIN_CLK, MSBFIRST, val1); digitalWrite(PIN_LOAD, LOW); digitalWrite(PIN_LOAD, HIGH); shiftOut(PIN_DATA, PIN_CLK, MSBFIRST, cn2 << 1); // A1 A0 RNG (where RNG=0, X1 output) shiftOut(PIN_DATA, PIN_CLK, MSBFIRST, val2); digitalWrite(PIN_LOAD, LOW); digitalWrite(PIN_LOAD, HIGH); digitalWrite(PIN_LDAC, LOW); digitalWrite(PIN_LDAC, HIGH); }