I2C: Reading from Max7311

Hi,

I'm experimenting with relays board using a max7311 i2c port-expander. Low byte is connected to relays, high byte is used as inputs. I manged to write and switching all relays on/off. However, I'm struggling with the inputs - whatever I try, reading always returns 0xFF, which means nothing is on.

Below is my code. During setup I run a test function, which toggles all relays, which works fine. In loop I read every 500ms but whatever I try - always 0xFF.

Does anyone have experience with a max7311 or any similar i2c ic? Any help is appreciated!

thx,
Bruno

#include <Wire.h>

/*
     Max7311 registers.
*/
#define InL       0x0
#define InH       0x1
#define OutL      0x2
#define OutH      0x3
#define PolInvL   0x4
#define PolInvH   0x5
#define DDR_L     0x6
#define DDR_H     0x7
#define TO_Reg    0x8

byte addr = 0x2B;
byte error = 0;

void setup() {
  Serial.begin(57600);
  Wire.begin();
  Wire.setClock(100000L);
  Serial.print("Setup MAX7311 @ 0x");
  Serial.println(addr, HEX);

  // low byte as output
  write(addr, DDR_L, 0);
  // high byte as input
  write(addr, DDR_H, 0xFF);

  read(addr, InH);
  write(addr, OutL, 0);

  test();
}

void loop() {
  read(addr, InH);
  delay(500);
}

void test() {
  Serial.println("*** Test Start ***");
  for (int i = 0; i < 8; i++) {
    write(addr, OutL, 1 << i % 8);
    delay(100);
  }
  write(addr, OutL, 0);
}

/*
 * Write a byte of data to the I2C device.
 */
void write(byte addr, byte reg, byte data) {
  byte error = 0;
  Wire.beginTransmission(addr);
  Wire.write(reg);
  Wire.write(data);
  error = Wire.endTransmission(); 
  if(error > 0) {
    Serial.print("I2C Write Error: ");
    Serial.println(error);
  }
}

/*
 * Reads a byte of data from the I2C device.
 */
byte read(byte addr, byte reg) {
  byte data = 0;
  byte error = 0;
  Wire.beginTransmission(addr);
  Wire.write(reg);
  error = Wire.endTransmission();
  if(error > 0) {
    Serial.print("I2C Write Error: ");
    Serial.println(error);
  } else {
    Wire.requestFrom(addr, (byte)1);
    while(Wire.available() > 0) {
      data = Wire.read();
      Serial.print("data: 0x");
      Serial.println(data, HEX);
    }
  }
  return data;
}

Below is my code. During setup I run a test function, which toggles all relays, which works fine. In loop I read every 500ms but whatever I try - always 0xFF.

What did you connect to the inputs? If you left them floating, 0xFF is about what I would expect to read.

You can check the return value of Wire.requestFrom() or use Wire.available() just once.
The Wire.requestFrom() returns the number of received bytes and should be the same as the number of requested bytes.
If you do get the same number, then you know that the Slave has send a acknowledge to its address and that it probably returned valid data.

int n = Wire.requestFrom(addr, (byte)1);
if( n == 1)
{
  data = Wire.read();
  Serial.print("data: 0x");
  Serial.println(data, HEX);
}
else
{
  Serial.println( "requestFrom failure");
}