AD5175 i2C Write Protection Bit and Other Questions

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.

Wire.begin();
  Wire.beginTransmission(47);
Wire.write((1) | 0x01);  // Disable write protect on RDAC
Wire.write(0xC2);  //
Wire.endTransmission();

Is this how you would write the Value(also Stolen From other Post)?

Wire.beginTransmission(47); 
  Wire.write((Value / 256) | 0x04);  
  Wire.write(Value % 256); 
  Wire.endTransmission();

Data Sheet:

Have you seen this?

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.

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.

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();

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).

Thank you so much for the help!!

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):
Capture.PNG

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

temp = (r_set >>8 ) | AD5175_WRITE; //temp therefore equal to 0b000111(D9)(D8)


Frame 2 is Wire.write(temp);

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!

Capture.PNG

Thank you for explaining that further sherzaad that makes a lot more sense now. I’ll try it later tonight and report back.

The code I used is:

#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?

antleo:
Any suggestions?

you might be on to something…

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 will give that a shot tonight and see what happens. Will report back after. Thanks guys!

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.

Try

Wire.beginTransmissino(46);
Wire.write(0x1C);//B00011100
Wire.write(0x03);//B00000011
Wire.endTransmission();

Wire.beginTransmission(46);
Wire.write(0x05);
Wire.write(0x00);
Wire.endTransmission();