In the previous tutorial, we covered how to interface a NEO-6M GPS module with Raspberry Pi (RPi). The module communicates with RPi over the universal asynchronous receiver/transmitter or UART protocol.
The UART is the most common point-to-point data communication protocol. But, it’s not the only serial communication protocol. In embedded electronics, I2C and SPI protocols are also widely used for serial data communication. Unlike UART, I2C and SPI are master-slave-type synchronous serial data standards.
In this tutorial, we’ll discuss the basics of the I2C protocol.
What is an I2C?
An inter-integrated circuit (I2C) or two-wire interface (TWI) is a synchronous serial protocol originally developed by Philips Semiconductors (now NXP). It’s a multi-master, multi-slave serial bus for low-speed devices that only requires two wires for serial data communication between multiple devices. It can easily be implemented with two digital input/output channels on a device.
An I2C bus has just two wires over which hundreds of devices can communicate serial data.
As a master-slave type communication standard, at least one device connected to the bus should be the master. It’s the master device that generates a clock signal for synchronous serial communication.
The slave devices can transfer data to and from the master device(s), which access slave devices by their I2C addresses. The address of each slave device on an I2C bus must be unique. However, the I2C slave devices still must obtain their addresses from NXP.
There are only two wires in I2C where devices can be connected:
1. Serial data (SDA) – the line over which the master and slave devices communicate serial data
2. Serial clock (SCK) – the line over which master device(s) generate the clock signal.
The I2C is a half-duplex type of communication. Note: a master device can only read or write data to the slave at one time. Also, the clock signal and the read and write operations are all controlled by the master device(s).
Although there can be an unlimited number of master devices connected to the I2C bus, the maximum number of slave devices can be 112 (in 7-bit addressing) or 1008 (in 10-bit addressing).
The I2C bus drivers are open drain, which means the devices can pull the I2C signal line low but cannot drive it high. By default, both the lines are pulled high by pull-up resistors until the bus is accessed by a master device. This is useful to avoid bus contention.
Since master devices can only pull the signal line low, there can be no conflict between multiple masters — such as one master pulling the line low while the other drives it high. If at any time, the signal line is low, it means it’s in access to a master device.
Therefore, only one master can access the I2C bus at a time. And the bus master can only read or write data with one slave at a time.
The serial data communicated over the I2C is split into 8-bit data packets. The data transfer rate depends on the clock frequency. In the standard mode, the clock frequency is 100 to 400 kHz.
The clock frequency is:
- 1 MHz in fast mode I2C
- 3.4 MHz in high-speed mode
- 5 MHz in ultra-fast mode
Advantages of an I2C
The UART is the most common serial interface but it does have drawbacks. When using the UART, data communication is only possible between two devices. These devices must also agree to a common protocol and should have nearly the same clocking.
It’s possible to connect more than two devices to UART lines, but that carries a high risk of bus contention. Practically, the maximum data rate achievable with the UART is 230400 bps. And in every 8-bit data transmission, there’s an overhead of 2 bits.
It’s also not easy to implement the UART in software. A feasible UART communication requires an external or built-in UART chip.
On the other hand, a serial peripheral interface (SPI) allows for only one master device but multiple slave devices. To connect a slave device, four lines are required. For each slave device, one extra line is needed for the chip select. So, despite a high data rate (of up to 10 Mbps) and full-duplex communication, it’s not practical to connect multiple slave devices over an SPI due to the extra lines required for each slave. This limitation is more evident when the entire circuit is laid out on a PCB.
An SPI is typically only good for the high-speed, full-duplex data communication of a master device (such as a microcontroller or embedded computer) with a limited number of slave peripherals (say two or three). However, an SPI is an alternative to the UART for high-speed full-duplex data communication with more than one peripheral device.
Essentially, an I2C represents the best of both the UART and SPI. Although it allows for half-duplex communication, by using an I2C, an unlimited number of master devices can communicate serial data with hundreds of slave devices over just two wires.
Since the master devices can only drive the lines low, bus contention is not a concern. The data rates fall in between those of the UART and the SPI (up to 5 Mbps), and there’s an overhead of only 1 bit (ACK/NACK) for every byte transmitted through the I2C protocol.
An I2C does still require some complex hardware in comparison to an SPI, but it’s not as complex as with the UART. Also, the software implementation of an I2C is quite feasible.
Additionally, an I2C is particularly useful when low-speed data communication is required with multiple devices or by multiple masters over just two wires. That’s why it’s commonly used by embedded sensors and modules. When using an I2C, a microcontroller (such as Arduino), or an embedded computer (such as Raspberry Pi) can connect and communicate with hundreds of sensors over just two wires while engaging only their two channels/pins.
Disadvantages of an I2C
An I2C allows serial data communication with multiple devices and multiple masters using only two wires, but it has low data-transfer rates and lacks full-duplex capabilities. The I2C is simply not an option when full-duplex communication is required or high data speed is needed.
- The UART is good for basic, full-duplex communication between two devices with a similar clock.
- An SPI is good for full-duplex, high-speed data communication with two or more peripherals.
- An I2C is good for slow-speed data communication with multiple devices, among multiple masters over a 2-wire bus.
The I2C hardware
The implementation of an I2C requires two open-drain (open-collector in TTL terminology) output drivers. Both the wires on an I2C bus must be pulled high with a suitable resistor. The I2C channels on most of the sensors and modules communicate serial data successfully over two to three meters of wire.
For longer-distance data transmission, dedicated I2C breakout boards are required.
Most of the microcontrollers and embedded computers have dedicated I2C hardware, which they can operate as an I2C master and an I2C slave. As an I2C slave means they also have an I2C address. With I2C hardware, they can generate start and stop conditions, receive an I2C address, and send and receive serial data over the protocol.
If the I2C address is implemented by the software, the data bits must be sampled at least twice per clock pulse. Most of the microcontrollers have sufficient clock frequency that they can easily sample the I2C data using an internal timer/counters with or without a pre-scaler.
The I2C voltage levels
Typical voltages used for the I2C are +5 and +3.3V. The I2C is flexible, however, and can maintain data communication with devices/interfaces with other voltage levels, too.
When connecting a higher-voltage device with a lower-voltage one over an I2C, caution is required. Sometimes pulling the I2C bus to a lower-voltage device level is sufficient. But there’s still a chance that the higher-voltage device can damage the lower-voltage one. It’s recommended to connect the two devices with different voltage levels over the I2C bus by using a suitable I2C level shifter board.
The I2C addresses
Master devices on an I2C bus do not need to have an address as they generate the clock signal on an SCL line. The slave devices need to have unique addresses on an I2C bus.
The I2C addresses of slave devices can be 7-bit or 10-bit. Some of these devices have fixed addresses while others have address lines that can be wired to set the address of the device over an I2C interface.
As there are a limited number of I2C addresses (only 112 addresses in 7-bit and 1008 addresses in a 10-bit), there’s a chance that two I2C devices may have the same one. More than one I2C device with the same address can be connected to a controller/computer using an I2C hub.
The I2C protocol
By default, both I2C lines (SDA and SCL) are high. There can be one or more master devices connected to an I2C bus. The data communication is initiated by a master device.
A master device generates a start condition that’s followed by the address of the slave device. The address of the slave device should be unique. In 7-bit addressing, the bit 0 of the address byte indicates whether the master reads or writes to the I2C slave. If the bit 0 of the address byte is 0, the master device writes the data to the I2C slave. If it’s 1, the master device reads data from the I2C slave.
After selecting a slave device, the data frames consisting of 8-bit data and acknowledgment bit are transferred between the master and slave. There can be repeated start conditions from a master to read and write the serial data with one or more I2C slaves.
Once the data communication is complete, the master device must generate a stop condition to end the communication over the I2C bus.
The I2C bus is also free to be used by other master devices. In fact, there can be an unlimited number of master devices connected to an I2C bus, provided the bus capacitance doesn’t exceed 400 pF.
The start condition
To generate the start condition, a master device has to pull an SDA low while leaving the SCL high.
If two master devices try to access the I2C at the same time, whichever pulls the SDA low first gets the ownership of the bus. This is called arbitration.
Once there’s a high-to-low transition on an SDA line, the I2C slaves are alerted that a transmission is about to begin. Once the bus is controlled by a master, it can read and write data to one or more of the slave devices by generating repeated start conditions.
Until the stop condition is generated by the current bus master, other master devices cannot gain control of the I2C bus.
The data is communicated over the I2C bus in 8-bit frames (data-packets). The first frame after the start condition is always an address frame. This frame identifies the slave device that the I2C bus master must communicate with.
In this frame, the 7-bit address of a slave device is transmitted by the master, starting with the MSB of the I2C address. It’s followed by an R/W bit, which determines whether the master will read from or write data to the slave. If the R/W bit is 0, the master device writes data to the I2C slave. If it’s 1, the master device reads data from the I2C slave.
After the start condition, the bus master has to pull the SCL line low. The bits are sampled whenever the SCL line goes high. The data (bits) on the SDA line should remain stable when the SCL is high, otherwise, it will be interpreted as a repeated start or stop condition. The data bits can only change when the SCL is low. After the start condition, the SCL is pulled low by the master, and the data is put on the SDA line. Following this, the data is sampled by the slave at each low-to-high transition of the SCL signal.
Each 8-bit data frame ends with an ACK/NACK bit. After 8 bits are transferred, the receiving device gets control of the SDA line. If the receiving device pulls the SDA line low before the ninth clock pulse, this means that it has successfully received the 8-bit data frame.
If this does not occur, this means it has failed to receive the data frame or is unable to parse the data according to the I2C protocol. In this case, the receiving device does not pull the SDA line low but, rather, it’s up to the master to end data communication by generating a stop condition or a repeated start condition.
In the case of an address frame, the receiving device is always a slave device.
After sending an address frame, the bus master will continue sending clock pulses. Depending on the R/W bit, the data is either read or written by the master device. After each 8-bit frame, the receiving device pulls the SDA line low in the ninth clock pulse.
There can be any number of data frames exchanged between a master and slave — after the master selects a slave and the read/write operation by sending the start signal and then an address frame.
To release the bus, the master must generate a stop condition. The stop condition is generated by pulling the SDA line from high to low, while the SCL line is high.
This is why, the data bits should never change when the clock pulse on SCL line is high. Otherwise, it will be interpreted as a false stop condition or a false repeated start.
If a slave device is not ready or is unable to process the received data, it can pull the SCL line low to indicate that it needs time to receive/process the data. Once the device is ready, it can drive the SCL line high, indicating that the master can restart serial communication. This is called clock stretching.
The data bits are always sampled at a low-to-high transition of the clock pulse on an SCL line. The slave devices can only pull the SCL line low after the I2C bus is released by the master. When the SCL line is pulled low by a slave device, the master devices on the I2C bus refrain from generating clock pulses or putting data on an SDA line until the SCL line is released by the slave.
The 10-bit I2C addressing
Advanced I2C devices have 10-bit addresses. These can be used with 7-bit address devices as the address frame for 10-bit devices always begins with the 5-bit sequence, 11110.
This sequence indicates a 10-bit address from the master device. For selecting an I2C slave with a 10-bit address, the master device must send two address frames to write the data to the slave, or three address frames to read data from the slave.
When the master has to write data to a 10-bit address slave, it must send two address frames. The first address frame contains the 5-bit sequence 11110, followed by two bits of the slave address and the R/W bit. The R/W bit must be 0 in this case.
After sending the first frame, it must wait for the ACK at the ninth clock pulse. If the acknowledgment bit (an SCL line pulled low by the receiving device) is successfully detected by the master, it sends the remaining 8 bits of the slave address in the next frame.
When a master has to read the data from a 10-bit address slave, the R/W bit in the first address frame is still 0, but the second address frame is followed by a repeated start condition.
After the repeated start condition, the first address frame is resent to the slave with the R/W bit set to 1.
Advanced I2C protocol
Most of the I2C devices have 7-bit addresses and use standard mode, where the data transfer rate is 100 Kbps. Advanced I2C devices operate in fast, high-speed, or ultra-fast mode and generally have 10-bit addresses.
Fast-mode I2C devices have downward compatibility and can also work with slower I2C controllers. High-speed I2C devices use two clock states, SCLH and SCLL, and have spike suppression circuits on both lines of the I2C bus.
The high-speed devices do not use clock stretching or arbitration because they have enhanced line output drivers.
In the next tutorial, we’ll discuss synchronous serial communication when using the I2C protocol in Raspberry Pi.
Filed Under: Microcontroller Projects, Raspberry pi