Write value to dual reostat I2C

Hi I have a small problem, Im trying to write value from 1-127 to digital reostat MCP4632-502E, I have 2 of them on one bus (A1 and A0 are connected to GND on first one and VCC and GND on the other one), when I run I2C scanner I can see both of them with adresses 0x2E and 0x2C.

This is write sequence that Im trying to understand, so ... I started with
Wire.beginTransmission(44); to write to the first reostat
but now I tried general call adress as well as the slave adress (0101 1 + A1 + A0 + 0) than followed by command bit (Write Next Byte (Third Byte) to Volatile Wiper 0 Register = 1000 00) than followed by my value from 0x01 to 0x7F ... but nothing works, the output resistance is still same (half from the max by default) ... any ideas how to make this work?

Manufacturer's page of the MCP4632: MCP4632 - Digital Potentiometers.

The "General Call Address" is always I2C address 0x00. I think the "General Call Address" is turned off by default. It is an extra option which does not behave like normal I2C communication. I think you better not use that.

Can you show a sketch (not using the General Call Address) that writes and read to and from the MCP4632 ?

I just need to write into MCP ... here is that part where Im trying to write 4 values into 2 dual reostats.

 if (readString.indexOf("5V1val=") >= 0) {
            data = readString.substring(b1 + 1, a1);
            A = data.toInt();
            Wire.beginTransmission(44); //zápis na adresu #44 (0x2c)
            Wire.write(byte(0x90));            //zápis inštrukčného bytu pre Wiper0/1
            Wire.write((lowByte(A));             //zápis hodnoty do reostatu
            Wire.endTransmission();     //koniec prenosu
          }
          if (readString.indexOf("5V2val=") >= 0) {
            data = readString.substring(b2 + 1, a2);
            B = data.toInt();
            Wire.beginTransmission(44);
            Wire.write(byte(0x80));
            Wire.write((lowByte(B));
            Wire.endTransmission();
          }
          if (readString.indexOf("12Vval=") >= 0) {
            data = readString.substring(b3 + 1, a3);
            C = data.toInt();
            Wire.beginTransmission(46);
            Wire.write(byte(0x90));
            Wire.write(lowByte(C));
            Wire.endTransmission();
          }
          if (readString.indexOf("24Vval=") >= 0) {
            data = readString.substring(b4 + 1);
            D = data.toInt();
            Wire.beginTransmission(46);
            Wire.write(byte(0x80));
            Wire.write((lowByte(D));
            Wire.endTransmission();
          }

Could you make a very small sketch that only sends a few values.
That part is far to complex, you don't even know if 'A', 'B', 'C' and 'D' have any meaningful value.

You could check the return value of Wire.endTransmission() to see if it is an error.

Are you trying to rush towards the end result ? Even an advanced software engineer does not do that. He or she makes small parts and test those and only if they work then they are combined.

No the problem is that rest of the code works as it should, only thing that does not work is this writing values to reostats, their resistance determines the output current on my power supply

here is whole source code, those ABCD values are just values from 4 slider where you can set output current … switching on and off all of my 6 outputs works fine but they cant handle bigger loads because of that current limiting that is stuck on default ~50% because I dont know how to write new value into those reostats

SMPS.ino (8.77 KB)

Which Arduino board do you use ?

Do you use pullup resistors ?

There is a glitch in the timing in the Wire library for AVR boards (Arduino Uno, Mega, Nano, Leonardo) and the reostat works also with a 3.4MHz I2C. It might be fast enough to capture that glitch.
There is a note in the datasheet: “A Master Transmitter must provide a delay to ensure that difference between SDA and SCL fall times do not unintentionally create a Start or Stop condition”.
The Arduino Due has problems with the I2C bus.

You should therefor not use the Arduino Due and the glitch can be avoided with the SoftwareWire library.

But first you need a minimal sketch that investigates the problem.
However, reading the datasheet, I don’t understand it :confused:
Sometimes it seems as if only one databyte can be written and read, and in other parts there are more bits needed.
I’m sorry, but I really don’t understand the datasheet.

Can you try this to write and read a single byte?

#include <Wire.h>

const int rheostatAddress = 0x2E;  // as found by the I2C Scanner

void setup()
{
  Serial.begin( 9600);
  Serial.println( "Started");
  
  Wire.begin();
}

void loop()
{
  int n, error;
  byte data;
  
  Wire.beginTransmission( rheostatAddress);
  Wire.write( 0);     // register address
  Wire.write( 0x20);  // value;
  error = Wire.endTransmission();
  if( error == 0)
    Serial.println( "0x20 written to register 0");
  else
    Serial.println( "Error writing 0x020 to register 0");


  Wire.beginTransmission( rheostatAddress);
  Wire.write( 0);     // register address
  error = Wire.endTransmission( false);   // false for a repeated start
  if( error == 0)
    Serial.println( "register 0 selected");
  else
    Serial.println( "Error selecting register 0");

  n = Wire.requestFrom( rheostatAddress, 1);
  if( n == 1)
  {
    data = (byte) Wire.read();
    Serial.print( "Read: 0x");
    Serial.println( data, HEX);
  }
  else
  {
    Serial.println( "Error reading register 0");
  }

  delay( 2000);
}

I will try your test sketch tomorrow, and no I dont have Arduino Due its standalone ATMega 328P same package as on Nano/Pro Mini boards ... and also I dont understand that datasheet, when I looked up other digital reostats the instruction how to write all sequences were pretty straight forward.

So it seems like it does not work that waya, it says that the 0x20 value is written to register 0 with register 0 selected but read spits out 0x0

0x20 written to register 0
register 0 selected
Read: 0x0

It does not give warnings, so it is accepting the data and something can be read from it.

I tried to find existing code for the MCP4632, and perhaps three or four bytes should be read and written.
You could start a new topic: "Can not understand datasheet of MCP4632" and give a link to this topic.
Or read the datasheet 5 times or more until it starts to make sense.

I'm sure that there are others on this forum, who eat datasheets for breakfast, that can make sense of it. You have to get their attention.

Yep, thanks for the advice ... I will try to start new new topic if someone ever encountered those MCP.