Write value into MCP4632

Hi, I have a small problem, I need to write 4 values into 2 dual reostats, but I dont understand the datasheet for those reostats, I can see them on I2C bus but I dont know how to write command sequence with value ... here is my previous post but there we managed just to write something into the reostat but value that was read from it is wrong.

Previous post: https://forum.arduino.cc/index.php?topic=690148.0

Could you please try the following examples? I have created them based on the datasheet but I do not have hardware to test it.

According the datasheet page 37 Register 4-1 all bits of the TCON register have a power-on value of 1 (see R/W-1 above each bit).

TCON bit 8 states 1 - Enable Device to “Accept” the General Call Address (0000h)

Example 1: I would expect the following sequence to increment Wiper 0 of all POTs connected to the I2C using the General Call.
The values in the second line come from table 6-3 on page 48.

Wire.beginTransmission(0x00); //I2C General Call
Wire.write(byte(0x84)); // 8(b1000) Wiper 0 , 4(b0100) Increment Wiper + last bit 0 to form 8 bit
Wire.endTransmission();

Example 2: Decrement Wiper 1 of all POTs connected to the I2C using the General Call.

Wire.beginTransmission(0x00); //I2C General Call
Wire.write(byte(0x98)); // 9(b1001) Wiper 1 , 8(b1000) Decrement Wiper Register
Wire.endTransmission();

Example 3: Set Wiper 0 of all POTs to lowest value connected to the I2C using the General Call.

Wire.beginTransmission(0x00); //I2C General Call
Wire.write(byte(0x80)); // 8(b1000) Wiper 0 , 0(b0000) D8 bit(0x0) + last bit 0 to form 8 bit
Wire.write(byte(0x00)); // D[7:0] all 0 so set to lowest value
Wire.endTransmission();

Example 4: Set Wiper 0 of all POTs to highest value connected to the I2C using the General Call.

Wire.beginTransmission(0x00); //I2C General Call
Wire.write(byte(0x82)); // 8(b1000) Wiper 0 , 2(b0010) D8 bit(0x1) + last bit 0 to form 8 bit
Wire.write(byte(0xFF)); // D[7:0] all 1 so set to highest value
Wire.endTransmission();

So your example actually worked, if now I understand this correctly, replacing generall I2C with selected reostat adress I can just write those values into selected reostat, same goes for the wiper 1 but with (b1001) initial command in second byte, but now Im little confused, last bit in second byte is always 0 for me and value that I need to write into is stretched to 9 bits? ... 8 in third byte and one bit in 7 position of second bit ... now that I have value from those slider ranging from 1-127 how Im, supposed to convert it into corresponding 9 bits. (slider have range 127 because the reostat is 128 steps)

homodel:
So your example actually worked

Great, Thank you for the confirmation.

homodel:
(slider have range 127 because the reostat is 128 steps)

According the datasheet

  • page 2 the MCP4632 has 129 steps.

homodel:
how Im, supposed to convert it into corresponding 9 bits.

According the datasheet

  • page 53 7.2: Command Byte format supports up to 9-bits of data so that the 8-bit resistor network can be set to Full-Scale (100h or greater).
  • page 51 7.1: 7-bit devices utilize D7 (from the data byte) as it’s MSb. (MSb is Most Significant bit)
  • page 51 7.1: Currently only one of the data bits is defined (D8).

This means

  • you can ignore bits D8 and D9
  • writing 0 into D9 and D8 will make your code move the slider to the lower end when you exchange the POT for one with 257 steps in the future
  • writing 1 into D9 and D8 will make your code move the slider to the higher end when you exchange the POT for one with 257 steps in the future
  • writing your code in a way that D9 and D8 will be computed correctly when you send the corresponding values will make your code more future proof but more complicated for now

According the datasheet

  • page 46 6.2.4: Address pins that are not present on the device are pulled up (a bit value of ‘1’).
  • page 46 Figure 6.9: Control Byte Bit 0: R/W=0=Write, R/W=1=Read
    For the examples I assume no A2 pin and I choose D9 and D8 to be set to 0x0
    You choose
  • A1 and A0 are connected to GND on first POT
  • A1 connected to VCC and A0 are connected to GND on second POT

Example 5: Set Wiper 0 of POT(1 of 2) to some value

Wire.beginTransmission(0x58); //  5(b0101) fixed   8(b1000) A2=1,A1=0,A0=0,Write=0
Wire.write(byte(0x00)); // 0(b0000) Address 0x0 , 2(b0000) WriteData Command=00 D[9:8]bits=00
Wire.write(byte(0x1F)); // D[7:0] set to 1/4 value = 31 = 0x1F 
Wire.endTransmission();

Example 6: Set Wiper 1 of POT(2 of 2) to maximum value

Wire.beginTransmission(0x5C); //  5(b0101) fixed   C(b1100) A2=1,A1=1,A0=0,Write=0
Wire.write(byte(0x10)); // 1(b0001) Address 0x1 , 2(b0000) WriteData Command=00 D[9:8]bits=00
Wire.write(byte(0x80)); // D[7:0] any value greater than 0x80 will set to maximum on the MCP4632
Wire.endTransmission();

I tried your examples but now with no success …

   Serial.println(B);
            Wire.beginTransmission(0x58);
            Wire.write(byte(0x10));
            Wire.write(byte(B));
            Wire.endTransmission();

where B is defined as uint8_t so 1 byte = 8 bits in size ranging from 0-255 … after I change value on sliders I can see the value in serial monitor but the output current doesnt change so the value is not written into reostat … it worked with that general call but is general call and it has different memory adress for wipers …

There is a function in the \Wire\src\utility\twi.c called TWI_MasterWriteRead. Inside the address gets shifted left and then the write bit is added. This would explain why the address you see are 0x2C and 0x2E but the bits from the datasheet combined in my example are 0x58 and 0x5C.

Can you try this?

Example 5: Set Wiper 0 of POT(1 of 2) to some value

Wire.beginTransmission(0x2C); //  b0101100 0101=fixed,A2=1,A1=0,A0=0
Wire.write(0x00); // 0(b0000) Address 0x0 , 2(b0000) WriteData Command=00 D[9:8]bits=00
Wire.write(0x1F); // D[7:0] set to 1/4 value = 31 = 0x1F 
Wire.endTransmission();

Example 6: Set Wiper 1 of POT(2 of 2) to maximum value

Wire.beginTransmission(0x2E); //  b0101110 0101=fixed,A2=1,A1=1,A0=0
Wire.write(0x10); // 1(b0001) Address 0x1 , 2(b0000) WriteData Command=00 D[9:8]bits=00
Wire.write(0x80); // D[7:0] any value greater than 0x80 will set to maximum on the MCP4632
Wire.endTransmission();

Such a strange reaostat ... but thanks to you it works now.