Sunday, 23 September 2012

Raspberry PI Digital to Analogue Conversion (DAC)

In this tutorial I will be detailing how to generate analogue voltages using a Raspberry Pi and an external Digital to Analogue Converter (DAC) to control the brightness of an LED.
Although the Raspberry Pi can interface with various low-level hardware using it's GPIO lines, SPI, I2C and serial UART interface, it does not have an DAC interface for generating analogue voltage levels. Instead the user must use an external DAC device controlled by one of the available low-level hardware interfaces, such as SPI and I2C.
I will be using the MCP4725 I2C DAC Breakout board as described here to control the brightness of the LED.


You will need the following components to complete this tutorial:
  • A Raspberry Pi with internet access, keyboard, power supply, etc.
  • An SD card with Raspbian “wheezy”.
  • A mini breadboard (example here).
  • Some Male to Female jump wires (example here).
  • A Breakout Board for MCP4725 I2C DAC (example here). You will need to solder on some break away headers onto the breakout board so you can mount it on your breadboard.
  • A 200 ohm resistor (example here).
  • An LED (example here).
(Please note that I have no affiliation with Proto-Pic other than being a regular customer.)

MCP4725 I2C DAC Breakout Board
The datasheet for the MCP4725 can be found on Microchip's website here. Suffice it to say that the DAC has a single analog output that can drive up to 25mAmps. This will be sufficient to power our LED.
To configure the voltage output that appears on the ANALOGUE pin, the user must send the appropriate '12 bit DAC Input Data' value to the DAC over the I2C bus. The user can also set this value into the device's EEPROM (permanent storage) so that a particular output voltage will be automatically set when the DAC is powered on, otherwise the DAC defaults to 0Volts output at power on.

The following gives the equation for input data value/code and output voltage, in our case Vdd will be 3.3volts:
Input Code and Output Voltage
Configuring the MCP4725 DAC is slightly different to the likes of the TMP102 I2C device as it does not have a register (data address) that you specify.
Instead, you simply write the configuration to the device without specifying a register number.
We will be setting the output voltage using the 'Fast Mode' configuration, which means when the DAC is power cycled our value will be lost.

This 'Fast Mode' I2C command takes the following structure:
1st Byte (Standard I2C Device Addressing with write) 2nd Byte 3rd Bye
0x60
0x0Y
Where Y is the most significant 4 bits of our output voltage setting.
0xZZ
Where ZZ is the lower byte of our output voltage setting.

Circuit
So, we are going to connect our I2C device to the appropriate pins on the Pi's GPIO header:
Raspberry Pi GPIO Header MCP4725 Breakout board Description
Pin1/3V3 Vcc This will provide power and Vref to the MCP4725 device.
Pin6/Ground GND  Device power rail ground.
Pin3/SDA SDA Data line for the Pi's I2C interface 0.
Pin5/SCL SCL Clock line for the Pi's I2C interface 0

We then need to connect the LED to the ANALOGUE pin on the breakout board and put the 200 ohm resistor in series between the LED and ground.

Enabling I2C on your Raspberry Pi
Please follow my instructions here to enable I2C on your Raspberry Pi.
Verify you can see the DAC on bus zero using the i2cdetect command:

pi@raspberrypi ~ $ i2cdetect -y 0
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: 60 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
70: -- -- -- -- -- -- -- --           

Here we can see our device at address 0x60.

Controlling the LED Brightness

We will use the linux i2cset command to configure the DAC output voltage and therefore the brightness of the LED:

Full brightness (3.3volts, 0xFFF input code):
pi@raspberrypi ~ $ i2cset -y 0 0x60 0x0f 0xff b

Low Brightness (1.86volts, 0x900 input code):
pi@raspberrypi ~ $ i2cset -y 0 0x60 0x09 0x00 b

Note we are not really using i2cset as it was designed. Looking at the man page for i2cset, the command takes the following basic form:
i2cset -y i2cbus chip-address data-address [value] ...  [mode]
We are using the data-address (register) field as the 2nd byte in the command and our third byte is the first [value] in the command. A little bit confusing, but important to be aware of.

Conclusion
So, in this tutorial we have shown how to setup and control the brightness of an LED using the Raspberry Pi's I2C bus and an external I2C DAC.

1 comment: