1

I'm trying to read from an MCP23008 I/O expander using the Wire library over I2C. The MCP23008 is wired to address 0x04, giving an effective device address of 0x24. Writing to the device GPIO seems to work fine, and I'm a bit confused on how to read from the GPIO.

So I set it up for read as follows:

#define MCP23008_DEVICE_I2C_ADDRESS 0x20
#define MCP23008_SLAVE_I2C_ADDRESS  0x04

#define MCP23008_REGISTER_IODIR     0x00
#define MCP23008_REGISTER_GPIO      0x09

#define IO_ALL_PINS_INPUT           0xFF

inline void eeprog::_read_enable()
{
    Wire.beginTransmission(MCP23008_DEVICE_I2C_ADDRESS | MCP23008_SLAVE_I2C_ADDRESS);
    {
        Wire.write(MCP23008_REGISTER_IODIR); // Set I/O direction
        Wire.write(IO_ALL_PINS_INPUT);       // Set all pins as input
    }
    Wire.endTransmission();
}

after which I attempt to read from it, by first addressing the GPIO register and then requesting a byte to read:

inline uint8_t eeprog::_read()
{
    Wire.beginTransmission(MCP23008_DEVICE_I2C_ADDRESS | MCP23008_SLAVE_I2C_ADDRESS);
    {
        Wire.write(MCP23008_REGISTER_GPIO); // Select the GPIO register
    }
    Wire.endTransmission();

    Wire.requestFrom(MCP23008_DEVICE_I2C_ADDRESS | MCP23008_SLAVE_I2C_ADDRESS, (uint8_t)1);

    return Wire.read();
}

Looking at my logic analyzer this is what I get:

I2C read from MCP23008

The NACK seems to indicate that the read went wrong.. actually a bit unsure what "Data read: 07" means in this context, did it read the value 7, or did it try read address 07?

Any ideas what I could be doing wrong? Am I missing something obvious from the documentation?

1

Everything is fine and nothing is wrong.
You are reading the GPIO register and its contents is 0x07.

The NACK at the end is not an error, it is a way to communicate between the Master and Slave.

When the Master reads data, the Master gives an ACK after each databyte from the Slave. The Master is not trying to tell the Slave that it was received, but rather it tells the Slave that another byte is going to be read.
After the last databyte, the Master send a NACK and after that a STOP.

Since only one byte is read, the Master sends a NACK and a STOP. The Master is telling the Slave that no more data is needed.

The I2C bus is only two wires. There are START, STOP, ACK and NACK conditions and the clock pulse can be stretched by a Slave. The possibilities are limited. For example when the Master wants to read 6 bytes and the Slave has only 1 byte. The Slave has no way to tell the Master that it has only 1 byte, and the Master will read those 6 bytes, valid or not.

1
  • Thank you. I just assumed that the NACK condition indicated an error since I previously had written my "write" code wrong and got NACK on the bus.
    – tobier
    Apr 8 '19 at 6:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.