Convert I2C address to hex

I have 2 I2C I/O Expanders that I need to determine the hex address for:

First address: 0100 A1 A2 A3 where A1, A2, and A3 are connected to +5v (http://ww1.microchip.com/downloads/en/DeviceDoc/21919b.pdf)
Second address: 0111 A1 A2 A3 where A1, A2, and A3 are also connected to +5v (http://www.nxp.com/documents/data_sheet/PCF8574.pdf)

How do I convert these to hex?

I have 2 I2C I/O Expanders that I need to determine the hex address for:

First address: 0100 A1 A2 A3 where A1, A2, and A3 are connected to +5v (http://ww1.microchip.com/downloads/en/DeviceDoc/21919b.pdf)
Second address: 0111 A1 A2 A3 where A1, A2, and A3 are also connected to +5v (http://www.nxp.com/documents/data_sheet/PCF8574.pdf)

How do I convert these to hex?

Well normally for simple 8 bit binary to hex conversion you just take the 8 bits formed (the I2C standard assumes a bit 0 read/write bit 0=read, 1= write:

first example: 0100 1110 into two 4 bit nibbles and look up the HEX value of those four bit nibbles = 0x8E
second example 0111 1110 = 0x7E

However if you are programming an Arduino using the wire I2C library code, it only wants a 7 bit address as the lowest bit 0 is a read/write bit that the wire library handles internally and is not included as part of the adress you use in your calls to the library. So for Arduino I2C code the two hex address would be 0x27 and 0x3F respectively.

At least I think I got that right. Getting I2C addresses straight can be a picky problem at times and it's been a few months sense my last sketch using I2C :wink:

Lefty

The code sample I have shows the address for the first one as 0xa7. This works, but I'm still puzzled as to how it was calculated.

I am using the wire library.

address for the first one as 0xa7

Humm, that doesn't make any sense to me, but then again I'm easily confused with software. :wink:

Lefty

Well,0xa7 is 1 0100 111. The I2C address bits are the last three bits; don't add a trailing zero.

The Wire library uses 7 bit I2C addresses. I suspect it is ignoring the MSB when you give it 0xa7. If I am right 0x27 should work as well.

The Wire library uses 7 bit I2C addresses. I suspect it is ignoring the MSB when you give it 0xa7. If I am right 0x27 should work as well.

Yes, that makes sense and explains my confusion. :wink:

Edit: Looking at twi.c from the library code it does take the address you give it in the call and shifts it left one bit and then ORs the R/W bit, so 0x27 is correct but 0xa7 works also, by chance.

Lefty

I suspect it is ignoring the MSB when you give it 0xa7. If I am right 0x27 should work as well.

No the 7 bit address goes the other way. The least significant bit in the 8 gives you read or write. So for the Arduino you should shift the address 0xA7 one place to the right to give you 0x53.

No the 7 bit address goes the other way. The least significant bit in the 8 gives you read or write. So for the Arduino you should shift the address 0xA7 one place to the right to give you 0x53.

I don't think so. See my edit in last post.

Lefty

So for the Arduino you should shift the address 0xA7 one place to the right to give you 0x53.

The address is 0x53, no matter where it goes. That address does make the first byte of the I2C transmission look like 0xA7, but 0xA7 ain't the address.

This tendency by many sources (not picking on Mike and lefty here) to use the first byte of the I2C transmission including the R/W bit as the address causes serious confusion for I2C newbies.

I'm personally thankful that the Wiring authors chose to use the actual address for the address, so that my code and the datasheet for the peripheral I'm using match.

-j

I'm personally thankful that the Wiring authors chose to use the actual address for the address, so that my code and the datasheet for the peripheral I'm using match.

The confusion is that many manufacturers datasheets specify an address that includes the read/write bit and that is not what the Arduino wire library wants to have passed to it. From the Arduino playground site:

"An I2C device address is seven bits. The I2C section of your datasheet will talk about the eight-bit address byte including the data direction bit (R/W), but this is a trick. ("Get an axe.") The Wire library will take care of the data direction bit for you automatically on each operation you perform, so you need to give it only a seven-bit address."

So the trick is to try and determine if the specific device datasheet is stating it's device address as a 8 bit number, which includes the R/W bit or a 7 bit number. The one I played with (an EEPROM chip) used a full 8 bit address in their data sheet (which included the R/W bit) and would not work until I shifted the address one bit right and used that as the address variable to the wire library call. So for the case of that device, the address they stated in their datasheet was not the one that would work directly with the Arduino wire library.

Here is an code snippet example of the address conflict from one of the wire library example sketches in the Arduino IDE, notice the comment statements about the I2C address to use:

// I2C SRF10 or SRF08 Devantech Ultrasonic Ranger Finder 
// by Nicholas Zambetti <http://www.zambetti.com>
// and James Tichenor <http://www.jamestichenor.net> 
.
.
.
// step 1: instruct sensor to read echoes
  Wire.beginTransmission(112); // transmit to device #112 (0x70)
                               // the address specified in the datasheet is 224 (0xE0)
                               // but i2c adressing uses the high 7 bits so it's 112
  Wire.send(0x00);             // sets register pointer to the command register (0x00)  
  Wire.send(0x50);             // command sensor to measure in "inches" (0x50) 
                               // use 0x51 for centimeters
                               // use 0x52 for ping microseconds
  Wire.endTransmission();      // stop transmitting

So in that case the datasheet showed 0xE0 but what you send to the wire library call is 0x70, which is 0xE0 shifted one bit right.

Lefty

0xa7 is the address being passed successfully to wire. The data sheet shows the address as 0100111(0). 0xa7 = 10100111. So when you shift to the right to you add a 1 on left?

The address for the second expander is shown as 0111111(0). Will the address to pass to wire be 10111111, 0xbf, or should it be 0111111, 0x3f, or neither of these?

The data sheet shows the address as 0100111(0). 0xa7 = 10100111.

OK

So when you shift to the right to you add a 1 on left?

No shift in a zero.

The address for the second expander is shown as 0111111(0). Will the address to pass to wire be 10111111, 0xbf, or should it be 0111111, 0x3f,

0x3F

See my article:-
http://www.thebox.myzen.co.uk/Hardware/Transistor_Tester.html

The confusion is that many manufacturers datasheets specify an address that includes the read/write bit and that is not what the Arduino wire library wants to have passed to it.

I guess I've been lucky in my choice of devices, then, with the exception of a Devantech sensor. They don't really count as an IC manufacturer, though; the device I used was a PIC and an available analog sensor packaged into a sensor board.

-j