Use SoftwareI2C for the digital potentiometer AD5259 - unexplicable behaviour

Hi,

I am struggling using the SoftwareI2C library of todbot to control the digital potentiometre AD5259: I can read just fine the DAC register, and also the EEPROM register, but I can only write to the DAC register (and the write protection’s) and not the EEPROM’s… However I use the same function between those two, and the same identifier between both operations. Finally, neither of the store nor restore commands work.
Is it possible that I, from the outside, can’t communicate somehow with the EEPROM whereas the device always restores sucessfully from the EEPROM when rebooting - or that the EEPROM can be damaged so that it can’t be written to but only read? Have you had a similar problem before?

Here is my code and an example output:

#include "SoftI2CMaster.h"

const uint8_t addr = 0b1001100;

#define EEPROM 0b00100000
#define RDAC 0
#define WPROTECT 0b01000000
#define NOP 0b10000000
#define LOAD 0b10100000
#define STORE 0b11000000

SoftI2CMaster i2c(4,2,false);

//Possible who values: EEPROM, RDAC, WPROTECT
uint8_t writeTo(uint8_t who, uint8_t what) {
  i2c.beginTransmission(addr);
  i2c.send(who);
  i2c.send(what);
  i2c.endTransmission();
  
  return 0;
}

uint8_t readFrom(uint8_t who, uint8_t *what) {
  i2c.beginTransmission(addr);
  i2c.send(who);
  i2c.requestFrom(addr);
  *what = i2c.receiveLast();
  i2c.endTransmission();
  
  return 0;
}

uint8_t command(uint8_t cmd) {
  i2c.beginTransmission(addr);
  i2c.send(cmd);
  i2c.endTransmission();
  
  if(cmd == LOAD) {
    command(NOP);
  }
  
  return 0;
}

void setup() {
  Serial.begin(9600);
}

void loop() {
  uint8_t buf = 0;
  static uint8_t i = 0;
  
  Serial.print("RDAC initially =");
  readFrom(RDAC, &buf);
  Serial.println(buf);
  
  writeTo(RDAC, ++i);
  Serial.print("RDAC after writing =");
  readFrom(RDAC, &buf);
  Serial.println(buf);
  
  Serial.print("EEPROM initially =");
  readFrom(EEPROM, &buf);
  Serial.println(buf);
  
  writeTo(EEPROM, i);
  command(STORE); //Both have the same lack of effect
  Serial.print("EEPROM after storing =");
  readFrom(EEPROM, &buf);
  Serial.println(buf);
  
  writeTo(RDAC, i+1);
  Serial.print("RDAC after 2nd writing =");
  readFrom(RDAC, &buf);
  Serial.println(buf);
  
  command(LOAD);
  Serial.print("RDAC after loading =");
  readFrom(RDAC, &buf);
  Serial.println(buf);
  
  Serial.println("");
  
  if(i >= 255) i = 0;
   
  delay(1000);
}

RDAC initially =29
RDAC after writing =29
EEPROM initially =128
EEPROM after storing =128
RDAC after 2nd writing =30
RDAC after loading =30

Kudos to those who find it - I truly hope this is something stupid.

Skyward

Please provide the schemata or a photo of your setup to check the wiring. Depending on how you wired it a write operation is not possible.

Why are you using a software emulation of the I2C bus if you have it in hardware?

Thank you for your answer.

If I can communicate with the RDAC doesn't that mean the wiring is alright since it's the same interface? If not, I have SCLK and SDA respectively wired to pins 2 and 4, Vdd and Vlogic to the 5V from the Arduino (Mega), GND to its ground, and (A0,A1) to (5V,GND). It's basically the minimum setup, however I do have 5.5k pull up resistors on SCLK and SDA, if you think it can be a timing problem.

I use softwareI2C because ultimately I will be sending requests from a central microcontroller to this subsystem microcontroller (I understand the Arduino can't switch from slave to master on the same bus).

OK here goes.

I didn't really like the way SoftwareI2CMaster was coded, so I tried another one, SoftI2C from rweather. All of a sudden, everything started to work, except the EEPROM reading just after the storage. It made me recall that EEPROM are slow, and after looking in the datasheet I spotted the culprit: 30ms of storing time. Adding 50ms of delay after the STORE command or writeTo EEPROM solved everything.

I hope it will help someone out as well sometime (I am also solving most of my problems browsing the forums after all).