I am trying to write to an AD5175(link to datasheet Below) and am not entirely sure I understand how. First I need to write to the Write Protection Bit with Command 7 to bit C1. Can someone explain what that means exactly? If I'm not mistaken, C1 is the bit address, but how do I specify the command 7? What would C1 be when I go to use the Wire.write Command and how do I translate that in the future?
Below is what I found from another post on this device, however this did not seem to work properly, or maybe Im just writing the value wrong.
so using you the code you provide I think it should work with the following adjustments:
#define AD5175_WRITE 7 //I assume you know here #define needs to be put! :)
uint16t r_set = 123; //value you and to set the restat to.
uint8_t temp;
Wire.begin();
Wire.beginTransmission(47); //IC address
temp = (r_set >>8) | AD5175_WRITE 7; //MSByte | control bits
Wire.write(temp); //send MSByte
Wire.write( (uint8_t)r_set); //send LSByte
Wire.endTransmission();
sherzaad:
the example Jaba posted is for a 64-Position OTP Digital Potentiometer. since yours is a 1024-Position, Digital Rheostat its slightly different.
If I read the data sheet correctly, to write to the the control bits (C3-C1) should be set to 0b0111 ie 7 in decimal.
If I'm not mistaken this would write a value of 123 to the rheostat? I am not sure I 100% follow why you do | AD5175_WRITE 7; Is this just saying what byte to write to? (Edit: Digging into this further this seems to be exactly what this is, Is the 7 needed though? If I'm not mistaken which I very well could be dont you only need the AD5175_WRITE? It will be replaced the the address of 7?) I'm sorry I don't have a very in depth programming background.
From the top you define bit address, then the unsigned short r_set which is the Value to be written to the rheostat? Then the unsigned char temp which is more or less a place holder for an operation used later on. You begin the wire (no surprises there), then set the temp variable tothe first 8 bits of r_set or The MSB? The next line I'm not sure I follow at all, is that supposed to be temp multiplied by r_set? to give the LSB? Then end the wire (again no surprises).
antleo:
From the top you define bit address, then the unsigned short r_set which is the Value to be written to the rheostat? Then the unsigned char temp which is more or less a place holder for an operation used later on. You begin the wire (no surprises there), then set the temp variable tothe first 8 bits of r_set or The MSB? The next line I'm not sure I follow at all, is that supposed to be temp multiplied by r_set? to give the LSB? Then end the wire (again no surprises).
Another datasheet screen shot (I hope that will explain better the operation in my example and answer your question):
Frame 1 is Wire.beginTransmission(47);
r_set contains the data (10 bits wide ie 0 - 1023) to be written to the rheostat. r_set is 16 bits wide
Frame 2 contains the control bits (e.g to write C3-C0 = 0x07) + D9,D8 (most significant data bits)
r_set >>8 //D9,D8 not in bits position 1 , 0 respectively
temp = (r_set >>8 ) | AD5175_WRITE 7; //MY MISTAKE should be
#define AD5175_WRITE 0b00011100 //0111 is write command
Frame 3 is Wire.write( (uint8_t)r_set); //send D7-D0
Hope that helps. Please let me know if that works. One thing that I am unclear on from the data sheet is the bit order in frames 2 and 3. I think I got it right but if you could test and confirm that would be great!
#include <Wire.h>
#define AD5175_WRITE 0b00011100
uint16_t r_set = 123; //value you and to set the rheostat to.
uint8_t temp;
void setup ()
{
Wire.begin();
//Frame 1
Wire.beginTransmission(46); //IC address
//Frame 2
temp = (r_set >>8) | AD5175_WRITE; //MSByte | control bits
Wire.write(temp); //send MSByte
//Frame 3
Wire.write( (uint8_t)r_set); //send LSByte
Wire.endTransmission();
}
void loop ()
{
}
I did not get any change, the rheostat is still locked in right around 5k ohms which is what the default is(Problem with the write protection bit?). I tried changing the address (took my jumper off from the addr pin to change it to 46) and retried to no avail. Any suggestions?
looking back at the datasheet, there are 2 write cpmmands: 0b00011100(to write to control register) and 0b00000100(to set RDAC). so I think there a couple of of extra write to be added; can you try this?
#include <Wire.h>
#define CONTROL_REG_WRITE 0b00011100
#define RDAC_WRITE 0b00000100
uint16_t r_set = 123; //value you and to set the rheostat to.
uint8_t temp;
void setup ()
{
Wire.begin();
Wire.beginTransmission(47); //IC address
//write to control register to enable update of wiper position
Wire.write(CONTROL_REG_WRITE);
Wire.write(0x02);
//write to RDAC register
//MSByte | control bits
temp = (r_set >> 8) | RDAC_WRITE;
//send MSByte
Wire.write(temp);
//send LSByte
Wire.write( (uint8_t)r_set);
//write to control register to disable 50-TP program
//and freeze wiper position value
Wire.write(CONTROL_REG_WRITE);
Wire.write(0x00);
Wire.endTransmission();
}
void loop ()
{
}
I agree with Sherzaad, and I would try and separate the write protection clearance from the writing of potentiometer values. That is, separate command 7 from command 1.
First, clear the write protect bit in setup(). I think that this will do it
Wire.beginTransmission(46);//please veryify the i2c address with an i2c scanner program
Wire.write (B00011100);//write 1's to C0/C1/C2 command 7
Wire.write (B00000000);//empty values for D0-D7
Wire.endTransmission();
Then to set the potentiometer, you use command 1 with bit set in C0.
You can define the 10 bits of the potentiometer setting with val/256 for the high bits and and %val/256 for the low. With bit shift, the high and low bytes are val>>8 and byte(val);
Wire.beginTransmission(46);
Wire.write(B00000100|(val>>8));//write C0(0x04) and top two bits of value in the high byte
Wire.write(byte(val));//low byte
Wire.endTransmission();
I attempted both of these and still have no change. However I have learned a lot about all this which is great! This all seems like exactly what the data sheet says to do, if you guys have any other suggestions I'm open to trying them out of curiosity, but this project needs to get done so I ordered a different digipot, unfortunately with less resolution and no memory function, but thats not a huge deal in the grand scheme of things. Thank you guys so much! Keep the ideas coming, Ill keep testing them out
First, have you confirmed the i2c address with a scanner program? The address could be 44,46, or 47 decimal.
// I2C Scanner
// Written by Nick Gammon
// Date: 20th April 2011
#include <Wire.h>
void setup() {
Serial.begin (115200);
// Leonardo: wait for serial port to connect
while (!Serial)
{
}
Serial.println ();
Serial.println ("I2C scanner. Scanning ...");
byte count = 0;
Wire.begin();
for (byte i = 8; i < 120; i++)
{
Wire.beginTransmission (i);
if (Wire.endTransmission () == 0)
{
Serial.print ("Found address: ");
Serial.print (i, DEC);
Serial.print (" (0x");
Serial.print (i, HEX);
Serial.println (")");
count++;
delay (1); // maybe unneeded?
} // end of good response
} // end of for loop
Serial.println ("Done.");
Serial.print ("Found ");
Serial.print (count, DEC);
Serial.println (" device(s).");
} // end of setup
void loop() {}
I'm not sure if you tried this before, but based on these two lines in Table 8 of the data sheet these two commands would set the output to 256. Forgive me if you've been here before.
0x1C03 0xXXXX Enable update of wiper position and 50-TP memory contents through digital interface.
0x0500 0x1C03 Write 0x100 to the RDAC register, wiper moves to ¼ full-scale position.