I connected an IO expander (PCA6416A) to Arduino using I2C bus. I used I2C Scanner script to find the address. I tried clock speeds from 30 to 100 kHz and used 2k and 10k resistors on bus lines. Whaterver I do the script always detects expander IC at address 0x40 while according to datasheet the expander IC is either 0x80 or 0x82 ( actually in my board it must be 0x80). Interestingly I can read IC registers without error but with some noise. So my questions is why I2C master consistently detects slave at a wrong address?


3 Answers 3


You have misread the datasheet. As you can see from the page in question:

I2C address

The slave address is a 7-bit field which the I2C scanner is reporting as 0x40 (or 0x41 depending on the ADDR pin).

To be honest, though, I don't see where you are getting 0x80 from. That isn't mentioned in the datasheet, and the "8-bit" address shown in the graphic would be 0x40 (or 0x42) and the 7-bit address would be 0x20 (or 0x21).

Notice how the high-order bit is zero? There is no way that is going to be 0x80.


What you are confusing is the 7 bit I2C address field (which is not an 8 bit or HEX field) with the 8 bit registers used by an MCU to build the logical address and direction flag. I wrote some coverage of this for a Raspberry pi book which might help you:

enter image description here

Note: there is a mistake in the graphic above....the Slave address is 0x69 as shown in the bit values.

The register contents for you to begin a transaction with the first PCA6416A in your system using the software library would be 0x40 to write and 0x41 to read. For the second PCA6416A (ADDR=1) your register values would be 0x42 to write and 0x43 to read. And since the scanner software (which scans using only writes, and validates when it sees ACK from the slave) simply returns the ACK'd address in the upper 7 bits so you end up dealing with those HEX register values. Notice that in the datasheet they studiously avoid using HEX representation of data, and stay with bit values in 8 bit fields to avoid any confusion.

The whole of Chapter 6 on I2C is here on Google books may perhaps help you.

There are two addressing schemas, 7 bit and 10 bit.
You can read up on the I2C addressing standards from http://www.i2c-bus.org/addressing/ or from NXP (Phillips) who developed the first devices, http://www.nxp.com/documents/user_manual/UM10204.pdf

There is also a slow speed (100, 400, 1 Mbps) relaxed specification called SMBUS (and a similar PMBUS) which is used in virtually all PC motherboards for management tasks (power supplies, fans, temp sensors etc). You will see many implementations of these buses from 10k - 400k bps, but all are limited to 7 bit addressing.

  • \$\begingroup\$ Shouldn’t the slave address in your example be 0x69? 0x68 is 1101000. \$\endgroup\$
    – Sean Dever
    Commented Dec 6, 2019 at 7:11
  • 1
    \$\begingroup\$ @SeanDever Wow....you are absolutely correct ....I can't tell you have many reviewers looked at the and no one caught it. Thanks. \$\endgroup\$ Commented Dec 6, 2019 at 16:54

I think you are being confused as to how they are reported:

from https://www.arduino.cc/en/Reference/Wire,

There are both 7- and 8-bit versions of I2C addresses. 7 bits identify the device, and the eighth bit determines if it's being written to or read from. The Wire library uses 7 bit addresses throughout. If you have a datasheet or sample code that uses 8 bit address, you'll want to drop the low bit (i.e. shift the value one bit to the right), yielding an address between 0 and 127. However the addresses from 0 to 7 are not used because are reserved so the first address that can be used is 8.

The Arduino Wire library drops the R/W bit, whereas the datasheet includes it.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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