I am trying to control two Analog Devices AD5293 digital potentiometers http://www.analog.com/static/imported-files/data_sheets/AD5293.pdf
I receive commands for how to adjust the wiper position in the AD5293 chips from matlab, and I store the commands as Ycomd and Xcomd. My code is pretty incomplete right now, but I have posted it bellow to help clarify what I am trying to do. Unfortunately I will not have any hardware until late next week, so I can not test anything right now. Also, for my I/O pins, I just put the numbers 1-16 for now, I have not decided which pins I will actually use yet, so don't read too much into the pin numbers.
// variable declerations
int incomingByte = 0; // variable for incoming serial data
unsigned long Ycomd=0, Xcomd=0; // variables for Y command and X command (values should range from 0 to 1023)
int YRESET = 9; // Digital pin, Hardware Reset Pin. Sets the RDAC register to midscale. RESET is activated at the logic high transition. Tie RESET to VLOGIC if not used.
int YDIN = 10; // Digital pin, Serial Data Input. This part has a 16-bit shift register. Data is clocked into the register on the falling edge of the serial clock input.
int YSLCK = 11; // Digital pin, Serial Clock Input. Data is clocked into the shift register on the falling edge of the serial clock input. Data can be transferred at rates up to 50 MHz.
int YSYNC = 12; // Digital pin, Falling Edge Synchronization Signal. This is the frame synchronization signal for the input data. When SYNC goes low, it enables the shift register, and data is transferred in on the falling edges of the following clocks. The selected register is updated on the rising edge of SYNC, following the 16th clock cycle. If SYNC is taken high before the 16th clock cycle, the rising edge of SYNC acts as an interrupt, and the write sequence is ignored by the DAC.
int YSDO = 13; // Digital pin, Serial Data Output. This open-drain output requires an external pull-up resistor. SDO can be used to clock data from the serial register in daisy-chain mode or in readback mode.
int YRDY = 14; // Digital pin, Ready Pin. This active-high, open-drain output identifies the completion of a write or read operation to or from the RDAC register.
int Ypos = 15; // Analog pin, Y position signal from FSM
int Yerr = 16; // Analog pin, Y error signal from FSM
int XRESET = 1; // Digital pin, Hardware Reset Pin. Sets the RDAC register to midscale. RESET is activated at the logic high transition. Tie RESET to VLOGIC if not used.
int XDIN = 2; // Digital pin, Serial Data Input. This part has a 16-bit shift register. Data is clocked into the register on the falling edge of the serial clock input.
int XSLCK = 3; // Digital pin, Serial Clock Input. Data is clocked into the shift register on the falling edge of the serial clock input. Data can be transferred at rates up to 50 MHz.
int XSYNC = 4; // Digital pin, Falling Edge Synchronization Signal. This is the frame synchronization signal for the input data. When SYNC goes low, it enables the shift register, and data is transferred in on the falling edges of the following clocks. The selected register is updated on the rising edge of SYNC, following the 16th clock cycle. If SYNC is taken high before the 16th clock cycle, the rising edge of SYNC acts as an interrupt, and the write sequence is ignored by the DAC.
int XSDO = 5; // Digital pin, Serial Data Output. This open-drain output requires an external pull-up resistor. SDO can be used to clock data from the serial register in daisy-chain mode or in readback mode.
int XRDY = 6; // Digital pin, Ready Pin. This active-high, open-drain output identifies the completion of a write or read operation to or from the RDAC register.
int Xpos = 7; // Analog pin, X position signal from FSM
int Xerr = 8; // Analog pin, X error signal from FSM
int i = 0, j = 0; // variables used for counting
int delay1 = 100;
int delay2 = 1000;
void setup()
{
Serial.begin(9600); // opens serial port, sets data rate to 9600 bps
// pin declerations
pinMode(YRESET, OUTPUT); // specifies pins as outputs
pinMode(YDIN, OUTPUT);
pinMode(YSLCK, OUTPUT);
pinMode(YSYNK, OUTPUT);
pinMode(YSDO, INPUT); // specifies pins as inputs
pinMode(YRDY, INPUT);
pinMode(Ypos, INPUT);
pinMode(Yerr, INPUT);
pinMode(XRESET, OUTPUT);
pinMode(XDIN, OUTPUT);
pinMode(XSLCK, OUTPUT);
pinMode(XSYNK, OUTPUT);
pinMode(XSDO, INPUT);
pinMode(XRDY, INPUT);
pinMode(Xpos, INPUT);
pinMode(Xerr, INPUT);
}
void loop()
{
if (Serial.available() > 0) // check to see if there is data in the bus
{
// read the incoming byte:
Serial.print("DEBUG: loop1\r\n");
for(i=0; i<4; i++) //read four bytes in sequence from serial port and
{ //put them together into one unsinged long variable which is four bytes.
while(Serial.available()==0) // Wait until the next byte becomes available
{
}
incomingByte = Serial.read(); // Get a byte
Ycomd = Ycomd | (incomingByte << (8*i)); // Compile a variable from the bytes you got
}
for(i=0; i<4; i++)
{
while(Serial.available()==0)
{
}
incomingByte = Serial.read();
Xcomd = Xcomd | (incomingByte << (8*i));
}
// say what you got (for testing):
Serial.print("I received: ");
Serial.print(", ");
Serial.print(Ycomd, DEC);
Serial.print(", ");
Serial.println(Xcomd, DEC);
Serial.print(", ");
int bit0 = bitRead(Ycomd,0); // sets bit0 to the LSB of Ycomd
int bit1 = bitRead(Ycomd,1);
int bit2 = bitRead(Ycomd,2);
int bit3 = bitRead(Ycomd,3);
int bit4 = bitRead(Ycomd,4);
int bit5 = bitRead(Ycomd,5);
int bit6 = bitRead(Ycomd,6);
int bit7 = bitRead(Ycomd,7);
int bit8 = bitRead(Ycomd,8);
int bit9 = bitRead(Ycomd,9);
int bitarray[] = {bit0, bit1, bit2, bit3, bit4, bit5, bit6, bit7, bit8, bit9}; // array of bits
/// Y Command Sequence
digitalWrite(YSYNK ,LOW); // The write sequence begins by bringing the SYNC line low
delayMicroseconds(delay2); // not sure how long this delay should be
/// Command 4 in table 10 in AD5293 manual, enables update of wiper position
for(i=0; i<3; i++)
{
digitalWrite(YDIN, LOW);
delayMicroseconds(delay1); // not sure how long this delay should be
}
for(i=0; i<2; i++)
{
digitalWrite(YDIN, HIGH);
delayMicroseconds(delay1);
}
for(i=0; i<9; i++)
{
digitalWrite(YDIN, LOW);
delayMicroseconds(delay1);
}
digitalWrite(YDIN, HIGH);
delayMicroseconds(delay1);
digitalWrite(YDIN, LOW);
delayMicroseconds(delay1);
///////////////////////////////////////////////////////////////////////
digitalWrite(YSYNK, HIGH); // When SYNC returns high, the serial data-word is decoded
delayMicroseconds(delay2);
digitalWrite(YSYNK ,LOW);
delayMicroseconds(delay2);
/// Command 1 in table 10 in AD5293 manual, writes contents of serial register data to RDAC
for(i=0; i<5; i++)
{
digitalWrite(YDIN, LOW);
delayMicroseconds(delay1);
}
digitalWrite(YDIN, HIGH);
delayMicroseconds(delay1);
for (i = 9; i>-1; i--)
{
if bitarray[i] == 1
{
digitalWrite(YDIN, HIGH);
delayMicroseconds(delay1);
}
if bitarray[i] == 0
{
digitalWrite(YDIN, LOW);
delayMicroseconds(delay1);
}
}
///////////////////////////////////////////////////////////////////////
digitalWrite(YSYNK, HIGH);
delayMicroseconds(delay2);
digitalWrite(YSYNK ,LOW);
delayMicroseconds(delay2);
/// command 2 in table 10 in AD5293 manual, Read RDAC wiper setting from SDO output in the next frame
for (i=0; i< 4; i++)
{
digitalWrite(YDIN, LOW);
delayMicroseconds(delay1);
}
digitalWrite(YDIN, HIGH);
delayMicroseconds(delay1);
for (i=0; i<11; i++)
{
digitalWrite(YDIN, LOW);
delayMicroseconds(delay1);
}
///////////////////////////////////////////////////////////////////////
digitalWrite(YSYNK, HIGH);
delayMicroseconds(delay2);
digitalWrite(YSYNK ,LOW);
delayMicroseconds(delay2);
/// command 0 in table 10 in AD5293 manual, NOP command. Do nothing
for (i=0; i< 16; i++)
{
digitalWrite(YDIN, LOW);
delayMicroseconds(delay1);
}
///////////////////////////////////////////////////////////////////////
digitalWrite(YSYNK, HIGH);
delayMicroseconds(delay2);
Serial.flush(); //Flush serial input buffer before the next cycle
}
}
As far as the clock goes. I really don't know what I am doing. I was hoping that there is a way to provide the clock input to the AD5293 chips from the ATmega168. I have not been able to get into this at all yet.