I2C 101

I always think that a robot without sensors is not a robot. Its just another computer, albeit in a smaller scale (slower, small memory, etc).

 

There are numerous sensors available on the market today and if you try to put 5 or more sensors on your robot, your MCU will soon be out of I/O pins in no time. For example a Sumovore with the Atmel brain board, can contain 4-5 edge detectors, 2 IR LEDS, 2 IR receivers, 2 motors, and 6 user programmable LEDs. That's already almost half the total pin count for the Atmega8 being used by the brain board. If you'll see its schematics, you'll see only 2 free/spare pins for your use. What if you want to customize your robot and add a compass, a thermometer and a sonar? With only two pins left you can't connect them all at once.

 

There's actually a simple but, relatively, unknown method of interfacing several devices. This is I2C. If you have a TV-set most probably you are already using I2C without even knowing it. Most of the readers might have actually noticed "I2C" on a data sheet of some chip or from a product on an online store, but don't know how to use it.

 

This simple tutorial will try to introduce I2C to the readers with the hope of enabling the reader to use I2C on his/her own robotics projects. Consider this as the culmination of all the research I made when I was studying I2C when trying to interface a third party compass to the SRV-1. If you find any errors kindly inform the author (you'll need an SoR forum account).

[1] Overview

The I2C (Inter IC) bus was developed by Philips in the early '80s, for use in communication of peripheral devices within a TV-set. In some implementations, I2C is called as TWI (Two-Wire Interface) due to royalty issues. I2C is actually pronounced as "i squared c" (I2C), but most pronounce it as "i two c".

 

From its name we can easily deduce that it provides a communication link between ICs (integrated circuits). I2C is multimaster and can support a maximum of 112 devices on the bus. The specification declares that 128 devices can be connected to the I2C bus, but it also defines 16 reserved addresses.

 

Devices that support I2C can be directly connected to the bus. Analog devices can be connected to the I2C bus by using ADCs (ie Philips PCF8591, Analog Devices AD7992) or I/O expanders (ie TI PCF8574, PCF8575) with an I2C interface.

 

Communication speeds of 100kbs (kilobits per sec) in Standard Mode or 400kbs in Fast Mode should be attainable. A new revision of the specification allows for a maximum throughput of 3.4Mbps (megabits per sec) in High-speed Mode. Some documents will state these as 100kHz, 400kHz and 3.4MHz respectively, they are the same.

[2] Devices on the bus

I2C bus

 

Fig 1. The I2C bus, 1 MASTER , 3 SLAVEs, and the required pull-up resistors.

 

There are two kinds of device on the I2C bus:

MASTER - node that always controls the clock line

SLAVE - node that is not in control of the clock line

 

The most common setup is 1 MASTER and multiple SLAVEs on the I2C bus. Both MASTER and SLAVE can transfer data over the I2C bus, but that transfer is always controlled by the MASTER.

[3] Device addressing

So how does the MASTER communicate with the SLAVEs. Every component hooked up to the bus has its own unique address whether it is an MCU, LCD driver, memory, or complex function chip.

 

Manufacturers pay Philips to get a device address. This means only one manufacturer can use the device address. So an EEPROM memory will not have the same device address as a digital temperature IC. This is a good thing when programming because you can specify which device the MASTER wants to communicate with. On the other hand this has a severe drawback, you can not directly put two devices of the same type on the I2C bus without some extra hardware. Some devices provide a simple way of changing its device address which allows up to 8 of the same devices to be connected to the I2C bus.

 

All I2C device addresses are either 7-bit or 10-bit. The use of 10-bit is still rare and will not discussed here.

 

Even if the device address is only 7-bits, data transmitted on the I2C bus is 8-bit. The first 7-bits define the device address. The 8th bit defines the R/W (read/write) mode. For write operations this bit is 0, and 1 for read operations. So the read/write bit just makes the device address an odd or even address. Data is transmitted on the I2C bus MSB first.

[4] Physical Requirements

These electronic requirements must be met or the I2C bus will behave erratically.

The bus physically consists of 2 active wires:

SCL - Serial CLock line (sometimes referred to as SCK)

SDA - Serial DAta line

 

These lines are bi-directional, and open drain thus must be pulled up with resistors. Resistance value should be between 4K7 and 47K ohms. Only one pair of resistors is needed for the whole I2C bus. If the resistors are missing, the SCL and SDA lines will always be low - nearly 0 volts - and the I2C bus will not work.

 

The SCL and SDA lines are connected to all devices on the I2C bus. Two additional wires is also be needed, ground wire and +5V wire to power the devices on the bus.

 

The maximum number of devices that can be connected to the I2C bus is only limited by the available address space but also by the total I2C bus capacitance which must not exceed 400pF.

 Sample setup

Fig 2 Test setup with 3 different I2C devices connected to the bus.

 

Since I2C devices have a maximum SCL clock frequency make sure you set your clock to maximum clock frequency of the slowest device on the I2C bus. Setting it to 100kHz is always a safe bet.

[5] Bus Events

There are many events occurring on the I2C bus but without a logic analyzer or an oscilloscope you won't be able to "see" them.

START - the device (usually the MASTER) issuing the START condition first pulls the SDA line low. And next pulls the SCL line low.

STOP - the bus MASTER first releases the SCL and then the SDA line

ACKNOWLEDGE - the addressed SLAVE device or the MASTER pulls the SDA line low, depending on the current operation

 

START and STOP

Fig 3. START and STOP events

 

The START condition acts as a signal to all connected devices that something is about to be transmitted on the I2C bus. The STOP condition tells the connected devices that the message has been completed.

 

The ACKNOWLEDGE is given by an I2C device (MASTER or SLAVE) after every byte is transmitted.

ACKNOWLEDGE

 

Fig 4. A 1-byte packet on the I2C bus.

 

The MASTER should give an ACKNOWLEDGE after receiving a byte from the SLAVE in a read operation. The SLAVE should give an ACKNOWLEDGE after receiving a byte from the MASTER in a write operation. The SLAVE should give an ACKNOWLEDGE if it is being addressed. If there is no ACKNOWLEDGE the SLAVE is not on the bus.

 

SLAVE addressed in a write operation

SLAVE addressed in a read operation

Fig 5. SLAVE being addressed on the I2C bus. A6...A0 is the 7-bit device address.

 

These events are necessary for the correct operation of the I2C bus. MCUs that have hardware support for I2C perform all this behind the scenes. If you have an MCU that does not support the I2C bus but have 2 extra I/O pins, then all is not lost! You can bit-bang the bus.

[6] Device Registers

So how do you know what you can write or read from the SLAVE device? These are most likely documented in the devices data sheets (it pays to read the data sheet carefully).

 

For example we want to interface with a simple Dallas DS1307 (64x8 Serial Real-Tine Clock). On page 4 of the data sheet, we find the address or register map. These addresses contain the memory locations that we can write to and/or read from.

 

These registers are valid only for that specific device. Different devices will likely have different registers.

[7] Devices to Interface

An incomplete list of I2C devices types that you can interface to:

 

 

Did that get your mouth watering? You now have a new selection of sensors.

[8] Programming

[Theoretically its as easy as 1-2-3]

In its simplest form, the operations on the I2C bus is described below.


MASTER writes to a SLAVE

1) Send a START sequence

2) Send the I2C address of the SLAVE with the R/W bit low (even address)

3) Send the device register you want to write to

4) Send the data byte

5) [Optionally, send any further data bytes]

6) Send the STOP sequence.

 

MASTER reads from a SLAVE

1) Send a START sequence

2) Send I2C address of the SLAVE with the R/W bit low (even address)

3) Send device register you want to read from

4) Send a START sequence again (a repeated start)

5) Send I2C address of the SLAVE with the R/W bit high (odd address)

6) Read data byte from SLAVE

7) Send the STOP sequence.

 

The write operation is very straightforward, the MASTER addresses the SLAVE, sends the register it wants to access, then sends the data that will be written to the register.

 

I2C devices are, relatively, simple and dumb devices, it has no way of knowing what you want from it and this complicates the read operation a little bit. A write operation is performed to specify the register that the MASTER wants to read. Then, another START (known as a repeated start) is given to the SLAVE. The SLAVE is addressed again, and at this point the SLAVE has control the over the SDA line, in which it can transfer the necessary data to the MASTER. Even if there were 2 STARTs, only one STOP event is required to be sent.

 

[The Easy Way]

 

Programming I2C can be, relatively, easy. First time users are encouraged to use freely available code libraries on the Net, and refer to data sheets and sample applications from your chip manufacturer. Procyon armlib and avrlib has several APIs for I2C communications.

 

[SAMPLES]

 

1. I2C Compass sample application

 

2. I2C Real time clock (DS1307) sample application

 

3. I2C Servo controller (Mindsensors I2C-SC8) sample application

The valid commands are:

f : generate 1500ms pulse moving servo forward

c : generete 2500ms pulse moving servo back to center

h : generate 500ms pulse moving servo in a reverse direction

v : get motor controller version

b : get battery charge

 

4. I2C Servo controller (Mindsensors I2C-SC8) and PCF8575 (Sparkfun breakout board) sample application

The valid commands are:

f : generate 1500ms pulse moving servo forward

c : generete 2500ms pulse moving servo back to center

h : generate 500ms pulse moving servo in a reverse direction

s : stop motor, valid for continous rotation servos only

v : get motor controller version

b : get battery charge

6 : toggle LED 6

7 : toggle LED 7

 

 

Serial connection settings is 9600 8-n-1.

 

[The Hard Way]

 

If you have an MCU that has no hardware support for I2C, you can bit-bang two unused ports. Procyon avrlib users are fortunate because avrlib contains an a bit-banged I2C implementation, look for i2csw.c and i2csw.h.

 

Here's some pseudo code that should be able to help you ease the pain. Additional information related to the Microchip's PIC. Also here.

[9] Troubleshooting

So you just finished interfacing your very first I2C device but it doesn't want to work. Here are some things to check:

 

1) Verify pull-up resistors. Check if the resistors are connected from SDA to Vcc and from SCL to Vcc. Most third party I2C sensors readily available on the market do not have pull-up resistors. Also, most MCUs do not have built in pull-up resistors in them.

 

2) Are you using the correct pins for I2C? Check your data sheet and verify.

 

3) Are you sure that you are using an I2C device? Some I2C devices are marketed as serial devices. Some serial devices are not I2C devices, ie use SPI instead, which is another serial protocol.

 

4) Verify that the speed you are using is supported by the I2C device. When all else fails go back to using 100kHz.

 

5) Are you accessing the correct device? Verify the device address you are sending on the I2C bus. Verify that the correct R/W bit is set depending on the operation that you are performing.

 

6) Getting weird or totally incorrect values? Verify if your I2C device requires a delay period before reading the results. Also note that some EEPROMs are slow. So the value for the delay period should be in the ms (millisecond) range. For I2C devices describes as a “24xx series EPROM, with a different I2C address” but is not actually an EEPROM, you likely have an I2C device that needs a delay period before reading (ie. WRITE => DELAY PERIOD (ms)=> READ).

 

An oscilloscope and/or a logic analyzer is good to have when troubleshooting problems on the I2C bus.