For anyone interested in working with the AD5206 DAC, follow the link for my code that controls 4 multicolor LEDs using two AD5206 chips.
The write_LED routine is particularly handy. It is for controlling multicolor LEDs by specifying red, blue & green values. It is designed to work with multiple AD5206s chained together, and will figure out which set of pins on which DAC are assigned to a given LED.
It divides the LED number by the number of LEDs per chip to get the chip number, then uses a small lookup table to map the red, green & blue pins of the LED to the output pins on the DAC.
I use Heather's spi_transfer routine, and all her setup code.
Follow the link for the code...
/*
Multicolor LED driver using AD5206
This program drives 4 multicolor LEDS using the AD5206 digital pot
Gian Pablo Villamil
November 17, 2006
Based on SPI code by Heather Dewey-Hagborg
*/
#define DATAOUT 11//MOSI
#define DATAIN 12//MISO - not used, but part of builtin SPI
#define SPICLOCK 13//sck
#define SLAVESELECT 9//ss
#define POTS_PER_DAC 6
#define LEDS_PER_DAC 2
#define NUM_DACS 2
#define NUM_LEDS 4
byte pot=0;
byte resistance=0;
// map pins to LEDs
// first column is LED selector (0 or 1)
// second column is color selector (Red = 0, Blue = 1, Green = 2)
// refer to http://public.fotki.com/gpvillamil/new_york/itp_classwork/phys_comp/ad5206-pinout-for-final.html
byte pinMap[2][3] = {
{
5,3,1 }
,{
4,0,2 }
};
char spi_transfer(volatile char data)
{
SPDR = data; // Start the transmission
while (!(SPSR & (1<
{
};
return SPDR; // return the received byte
}
void setup()
{
Serial.begin(9600);
byte i;
byte clr;
pinMode(DATAOUT, OUTPUT);
pinMode(DATAIN, INPUT);
pinMode(SPICLOCK,OUTPUT);
for (int i = 0; i < NUM_DACS; i++) {
pinMode(SLAVESELECT+i,OUTPUT);
digitalWrite(SLAVESELECT+i,HIGH); //disable device
}
// SPCR = 01010000
//interrupt disabled,spi enabled,msb 1st,master,clk low when idle,
//sample on leading edge of clk,system clock/4 (fastest)
SPCR = (1<
clr=SPSR;
clr=SPDR;
delay(10);
for (i=0;i<6;i++)
{
write_pot(i,255);
}
}
byte write_pot(byte address, byte value)
{
byte chipNum = address / POTS_PER_DAC ;
byte chipAddress = address % POTS_PER_DAC ;
digitalWrite(SLAVESELECT+chipNum,LOW);
//2 byte opcode
spi_transfer(chipAddress);
spi_transfer(value);
digitalWrite(SLAVESELECT+chipNum,HIGH); //release chip, signal end transfer
}
// Light a 3 color LED
// Takes an LED number, and values for RGB
// Routine will calculate the number of the correct DAC
// and look up the pin number using the pinMap array previously defined.
void write_LED(byte LEDnumber, byte redValue, byte blueValue, byte greenValue)
{
byte chipAddress ;
byte chipNum = LEDnumber / LEDS_PER_DAC ;
byte chipLED = LEDnumber % LEDS_PER_DAC ;
digitalWrite(SLAVESELECT+chipNum,LOW); // activate the selected chip
// set the red value
chipAddress = pinMap[chipLED][0];
spi_transfer(chipAddress);
spi_transfer(redValue);
digitalWrite(SLAVESELECT+chipNum,HIGH); //release chip, signal end transfer
digitalWrite(SLAVESELECT+chipNum,LOW); // activate the selected chip
// set the blue value
chipAddress = pinMap[chipLED][1];
spi_transfer(chipAddress);
spi_transfer(blueValue);
digitalWrite(SLAVESELECT+chipNum,HIGH); //release chip, signal end transfer
digitalWrite(SLAVESELECT+chipNum,LOW); // activate the selected chip
// set the green value
chipAddress = pinMap[chipLED][2];
spi_transfer(chipAddress);
spi_transfer(greenValue);
digitalWrite(SLAVESELECT+chipNum,HIGH); //release chip, signal end transfer
}
void loop () {
for (int i = 0; i < NUM_LEDS; i++) {
write_LED(i,1,0,0); // make white
delay(100);
write_LED(i,255,255,255); // turn off
}
}