I2C Troubleshooting Guide
I2C should be straightforward to get going, particularly if your are not starting from scratch. If this is new to you then there is obviously a learning curve and I suspect you are reading this because you are trying to get some I2C equipment working but it doesn't for some reason.
The biggest temptation is to point the finger at some faulty equipment, if it doesn't work then it has to be faulty right? WRONG, think about it what is the weakest link here the equipment or somebody who is still learning. I have put this article together because I am always being asked the same question that usually starts out, "I have connected the xxx together in accordance with the data sheet but I think it is faulty because it doesn't work". So far with 100% record, it was not the equipment that was faulty.
So here goes, if you have something connected then disconnect and start from scratch, if you have some simple I2C device such as an EEPROM or an I/O expander then use that. The example I am going to use is a BV4221 (USB to I2C) connected to a 24LC512, 64k x 8 bit EEPROM. I have chosen this because it is a read and write device. The datasheets for each are:
Step 1 BV-COM or similar
Connect the BV4221 to BV-COM and get that working, there is an article on how to do this which includes a video. When you press return on BV-COM it should show the 0x42> prompt (or similar the 0x42 may be something else). If you are using Linux then use terminal software such as mini-com. Don't go any further until this prompt is on the screen.
Step 2 Connecting
Connect the 24L512 to the BV4221, the BV4221 already has pull up resistors on board so a simple straight connection will do. The BV4221 can also power the 24L512. If you are not using a BV4221 then pull up resistors will be required somewhere. For further information about this the the article on connecting.

Check the wiring before going on, does SCL go to SCL, make sure it does and it has not been advertently swapped with SDA, easily done. Just check, you know one wire wrong here could cost you hours.
Step 3 Addressing
If there is anything to get wrong this will be it. The address on the BV4221 must MATCH the address on the I2C device, the 24LC512 in this case. Check the datasheet, in section 5 it is very clear on this data sheet that with the WR bit low and the A0-A2 lines low the address of the device is 0xA0, however not all datasheets are as clear as this and only the 7 bit address is given which would be 0x50!!
This needs further explanation. To help, signals from the mater are in red
and
signals from the slave are in blue
. The data
sheet gives the address as follows:

In the above diagram A0-A2 are tied low and so are set to 0. To the letter of the I2C specification the address is 7 bits with an additional RW bit at the end. Looking at the above the 7 bits are:
1010000 = 0x50
Some datasheets specify this as the I2C address and some programs and master devices will also use this address. The ByVac devises' take a different approach and use an 8 bit address where an even address is always write (RW=0) and a read address is always odd (RW=1). For this device then, from a ByVac point of view the address of the 74LC512 is not 0x50 but 0xA0 (incidentally 7 bit address x 2) as the write address is always specified.
This is the main source of error and confusion, if the datasheet specifies and 8 bit address then okay, but if a 7 bit address is specified then multiply it by 2. This could also happen when using a master device, or master software library that uses a 7 bit address and driving say an LCD/Keypad controller (BV4218) with a default address of 0x42 - this is an 8 bit address (ByVac) to convert this to a 7 bit address devide by 2 to give 0x21.
If the correct address is not matched than NOTHING will happen, IT WILL NOT WORK and it is very difficult to diagnose. The only way to be SURE that the addresses match up is by reading the data sheet every very carefully. If you are still having problems then wait a day and read it again.
Stage 4 Testing
At this stage you should check the connections and be very sure about the address. The easiest way to test is by typing commands in at the BV-COM terminal, to assist with this, set the address using the 'A' command to 0xA0 as follows: type Aa0 <enter>(case is important. Also it is easier to work in hex so type H<enter>. The prompt should be exactly:
0xA0>
Writing to the EEPROM consists of specifying an EEPROM (not I2C) address and then wring data to that address. The address is 16 bits so this must be sent as two bytes. Subsequent writes will increment and internal counter and keep writing data. Up to 127 bytes can be written in on go for this chip. To specify a different address the stop condition must be entered to terminate the writing sequence.
Simple Write
To write 0 1 2 to locations 0 1 2 on the EEPROM use the following command (prompt also shown)
0xA0>s 0 0 0 1 2 p
The first two '0' specify the address and the '0 1 2' will be written to locations 0,1 and 2 of the EEPROM, this is because an internal (internal to the EEPROM) address counter is incremented each time some data is written. The astute observer will also notice that the I2C address (0xA0) has not been explicitly typed with this command, this is because the 's' commands sends the start condition AND the I2C address that has been set with the 'A' command and is indicated at the prompt. So 's' will in fact send the start condition and 0xA0 (in this case).
Read 1
If a read was carried out now it would read from EEPROM address 3, because we have just written to location 0,1 and 2 and the EEPROMS internal counter will have incremented to 3. If we want to see what we have just written then the address needs resetting back to 0, this can be done as follows:
0xA0>s 0 0 p
Now we can read the contents of the EEPROM starting at 0 as follows:
0xA0>s-a1 g-3 p
Following this command the returned bytes will be 0,1 and 2. What we have done here is to override the default address set on the prompt by specifying s<hyphen><new address> This will only apply for that line and will revert back to 0xA0 on the next command. 0xA1 is the read address of the EEPROM (odd number) as the RW bit is set high for reading. The g-3 command will get 3 bytes of data.
Read 2 (Restart)
The situation above is very common for I2C devices whereby a command is sent (address in the case of the EEPROM) and then a subsequent read is required, the restart command is implemented for just this occasion and the above command can be abbreviated to:
0xA0>s 0 0 r g-3 p
Here the address is reset to 0 as before by writing 0 0 to the I2C address, 0xA0. The 'r' command is the re-start and this will send the stop condition 'p' followed by a start condition 's' but this time with an address that is one more than specified on the prompt line, (0xA1) thus making it a read.
The above does work with the device given in the data sheet and is a good example as it shows how to read and write using the BV4221 and some of how I2C works.
BV4221 LED Indicators
Just a note about the LED's that are fitted to the BV4221, one monitors the SCL (or SCK) line and the other monitors the SDA line, when they are lit the lines are high, this is the idle state. The only time they will be seen to flash is on a very slow slave device where it is stretching the clock otherwise they do not flash.
Sending a start condition without the subsequent stop condition will result in the SCL LED going out, if everything is okay sending the stop condition 'p' will re-illuminate the LED. Sending a start and stop condition to a non-existent device will result in both LEDS remaining illuminated. If the SDA or SCL or both, go out when sending a command including the stop condition this indicates that the slave has 'hung'. This is more than likely due to sending it commands it does not understand or an incomplete sequence. This is actually a good sign because it means that communication has been established but you have sent the wrong information, it is then just a matter of sending the correct information.
