Project

General

Profile

I2C

I2C (pronounced "eye squared cee" or "eye two cee") is a serial protocol using two wires, one for data (labeled SDA) and one for a clock (labeled SCL). It is used to connect a single master, such as a microcontroller, to one or more slaves, such as sensors or other microcontrollers. Many sensor ICs are able to communicate over I2C.

Sending Data

A data transfer is always initiated by the master; slaves cannot initiate communication. Each slave on a bus has a 7-bit address, which must be unique. For sensors or other ICs which use I2C, you can find the slave address in the datasheet. Often there is a way to select one of a few different addresses, in order to resolve two slaves having the same address on your bus. For microcontrollers such as AVRs, you can set the slave address which it will listen for. Again, information about that will be in the datasheet.

The master begins by sending a start bit, followed by the 7-bit address of the slave it wishes to talk to, followed by a 0 (write) if it's sending data to the slave or 1 (read) if it wants data from the slave. At this point, either the slave takes over and sends a byte, or the master sends another byte. The transmission can continue with multiple bytes, or stop.

Connecting Devices

The most important thing to remember is that both SDA and SCL need weak pull-up resistors, usually around 10kOhm to Vcc. Because there are many devices driving the same two lines, it is very bad for one to drive it high (connect it to Vcc) and another to drive it low (connect it to ground); that creates a short circuit and fried ICs. I2C deals with this problem by having ICs either in high-impedance if they aren't using the bus, or driving the lines low. This is known as an "open-drain" configuration. When the bus is not in use, therefore, some external source has to pull it up to Vcc, but with a high enough resistance that driving a line low won't draw much current through the resistor.

If you're using several voltage levels, there are I2C specific level converters that will work. They may require very specific values for pull-up resistors. You can achieve the same thing with a few transistors, as seen on this page: http://playground.arduino.cc/Main/I2CBi-directionalLevelShifter.

Using AVR I2C

There are several C libraries which will handle I2C on the AVR for you. One good one comes with the Arduino library; it works independently without the rest of the Arduino library with just a single line changed. The files are called twi.c and twi.h.