What is the I2C communication protocol

What is the I2C communication protocol-Uncategorized

If you’ve been in a maker world for a bit, you’ve likely heard the term I2C communication being used somewhere. It is one of the most common communications used in connecting integrated circuits to a board. If you’ve never encountered I2C, it might seem a bit overwhelming at first. No need to worry. After this short tutorial, you will have a better understanding of working with the I2C circuits.

I2C’s history in a few words

I2C (sometimes abbreviated as I²C or IIC) stands for the inter-integrated circuit. It was developed by Phillips in 1982 for many of its chips. Originally, I2C allowed for only 100kHz communications to be used. Only 7-bit addresses were provided, and thus only 112 devices could be connected on the bus. Ten years later, 400kHz fast-mode was added. The number of devices that could be connected on the bus was increased to 1008 due to the 10-bit addresses. This was the first standardized I2C version.

Auto Draft

Why is I2C used?

Compared to protocols like USB, ethernet, Wi-Fi, or Bluetooth, I2C is much slower. However, it is a lot simpler and uses significantly less hardware and system resources. This makes it ideal for communication between microcontrollers or microcontrollers and sensors. Much like the SPI (Serial Peripheral Interface) , I2C is intended only for short distances.

 

Common uses of I2C where speed is mostly out of the equation, while simplicity and low cost are prioritized, include:

  • Turning the power supply on and off
  • Reading sensors’ data (e.g. speed of a fan)
  • Changing the volume in speakers
  • Controlling smaller OLEDs or LCDs
  • Changing the hue, color balance, contrast, and brightness settings in monitors
  • Accessing the RTCs (real-time clocks)
  • Accessing low-speed DACs (digital-to-analog converters) and ADCs (analog-to-digital converters)
  • etc.

If you ever work on projects using OLEDs  or barometric pressure sensors,  you’ll likely be using I2C.

How I2C works

Have you ever wondered how do devices talk to each other once they’re connected? How do they understand each other? Devices, like humans, need to speak the same language to understand each other. In the world of electronics, these languages are called communication protocols. These protocols are very important because they create universality and consistency in transferring the messages.

 

There are a handful of communication protocols, but when building most electronic projects, you’ll need to know only a few. I2C is one of them, and we’re big fans of it.

 

One of the biggest I2C’s strengths is the ability of a microcontroller to control a lot of devices with just two general-purpose I/O pins and software. The two wires used are SDA (serial data) and SCL (serial clock) lines. All I2C devices on a bus are connected using only those two wires. Many other similar bus technologies use more pins to connect multiple devices.

 

Every I2C device can be a transmitter (sending the data), receiver (receiving the data), or both. Some of the devices are the so-called controllers (formerly known as masters). They generate the bus clock, start and stop the communication processes, and send I2C commands. There can be more than one controller on a bus. Most of the other devices are the so-called peripherals (formerly known as slaves). They respond to the commands on the bus and are addressed by the controllers.

 

For a controller to communicate with specific devices, each peripheral must have a unique address on the bus. Controllers (usually microcontrollers) don’t need addresses since no peripheral will send commands to them.

Parts of a message

With the I2C communication protocol, data is transferred in messages. Each message is broken up into frames of data. A message will begin with the start condition, followed by the address frame made of 7 or 10 bits. The Read/Write bit comes after that. Next is the ACK/NACK bit, or the “acknowledge/no acknowledge” bit. Data frames made of 8 bits follow next. There is no limit to the number of data frames. Each one is followed by an ACK/NACK bit. The message will end with the stop condition.

 

To illustrate this more clearly, let’s take a look at the image below.

What is the I2C communication protocol

The address frame sequence is unique to each peripheral device. It is used to identify them when the controller wants to talk to them.

 

Read/Write bit indicates whether the controller is sending data to the peripheral or if it’s requesting data from it. When the controller is sending the data (write or 0), it operates at a low voltage level. When the controller is requesting data from the peripheral (read or 1), it operates at a high voltage level.

 

After the address and every data frame, an “acknowledge” bit is sent in the other direction. If the peripheral successfully received a sent address or a data frame, an ACK (0) bit will be sent back. If the data was not successfully sent or received, NACK (1) will be sent back, meaning it was not acknowledged.

 

Once the controller receives the ACK bit from the peripheral, it’s time for the data frame to be sent. Unlike the address frame which can be 7 or 10 bits, the data frame is always 8 bits long. The data bits are sent in order of importance, with the most significant being sent first, and the least last. After every data frame, an ACK/NACK bit is sent to verify if the frame was successfully acknowledged. The ACK bit must be received before the next data frame gets sent.

 

In layman’s terms, the address frame will say to whom the message will be sent. Read/Write bit will say what type of message it is. Data frames will contain “spoken” parts of the message. The ACK/NACK bits say whether the message was understood up to that point or not.

 

Each message will begin with a start condition and finish with a stop condition. To understand how that works, we have to go into a bit more technical details.

Start and Stop condition

To send the data among the devices, the controller will first generate a clock signal through the SCL line. This will synchronize the data transfer between the devices on the I2C bus. The controller will generate a clock pulse on the clock line for all data bits, even the acknowledge bit. A clock pulse means that the SCL line will go from high to low and back in sequence. The data will be carried through a single SDA line.

 

These two lines are open-drain, meaning they need to use pull-up resistors . Commonly used values of resistors range from 2K for higher speeds at about 400 kbps, up to 10K for lower speeds at about 100 kbps.

 

Both SCL and SDA lines can be either low or high. The start condition (marked S) will occur when the SDA line drops low while the SCL line is still high. At the end of the message, the stop condition (marked P) will occur when the SCL line goes or is high, and the SDA line goes high after that. Start and stop bits are unique signals that can only be generated by a controller, and never by a peripheral.

What is the I2C communication protocol

 

Data transfer

Data is sent between the start and stop conditions. It is transferred in bytes, the 8-bit packets. There is no limit on the number of bytes that can be sent. All of them must be followed by an ACK/NACK bit. This bit signals whether the device is ready to work with another data frame or not.

What is the I2C communication protocol

After the start condition, the controller will start sending pulses on the SCL line. For each clock pulse a controller sends, one bit of data is transferred. The SDA line can only change when the SCL line is low. When it is high, the SDA line will remain stable, either high or low.

 

If the SDA line is low on the Read/Write bit, the controller will write to the peripheral. If it’s high, it will request to read data from the peripheral.

 

When it comes to the acknowledgment bit, if the SDA line is low, the peripheral successfully understood the frame. If the SDA line is high, the peripheral didn’t understand and acknowledge the frame.

Repeated start

A controller will sometimes need to exchange more than one message at once. Since there can be multiple controllers on one bus, it must be ensured that exchange doesn’t get interrupted. Otherwise, another controller could interfere and take control of the bus, and the initial message would be lost. This is why a repeated start condition was defined.

 

As the name suggests, repeated start does the start condition again. To perform it, the SDA line is allowed to go high while the SCL line is low. Then the SCL line goes high as well. Once both lines are high, a new start condition begins the same way as the first one. The structure of this new message is the same as any other. An address frame is specified with data frames following. Since there was no stop condition up to that point, the previous message hadn’t truly ended. Thus, the current controller is still in control of the bus.

 

The image below shows an example of a message with a repeated start condition.

What is the I2C communication protocol

We’ve talked about how a peripheral must send back information whether the frame was acknowledged or not. If it’s acknowledged, everything will continue normally until the controller initiates the stop condition. But what if the peripheral doesn’t acknowledge the frame? You guessed it, the repeated start condition will be used until the message gets acknowledged.

 

A repeated start condition is essentially the same as a start condition, with the only difference being it can be initiated indefinitely. The controller will maintain control of the bus until it issues a stop condition, no matter the number of repeated starts.

 

A message can have only one stop condition. After it, another controller can take control of the bus and start its message.

easyC

We mentioned earlier that we are big fans of the I2C communication protocol. We love working with it and what it enables us to do. That’s why we created the easyC connectivity based on it.

 

With easyC, you can very simply connect multiple devices on the same bus without soldering. The easyC cables use JST 4-pin connectors, which are polarized so there’s no way to attach your devices wrong. The four signals on the easyC cables are GND, 3.3V, SCL, and SDA.

 

If you want to learn more about our easyC connectivity, be sure to check out the tutorial about it !

Pros and cons of I2C

I2C might sound complicated compared to other protocols, which might deter you from using it. There are some pros to using I2C, as well as some cons. We listed a few so you can make an easier decision whether to use it or not.

Pros:

  • Uses only two wires
  • Supports multiple controllers and peripherals
  • Easy to add new devices on the bus
  • ACK/NACK bit after every byte of transfer
  • Widely used protocol

Cons:

  • Data frame size limited to 8 bits
  • Slow data transfer rate
  • Requires more complicated hardware to implement than SPI

Working with I2C

Now that you understand how I2C works, the next step is to get some hands-on experience. It is rather complex, but it doesn’t have to be. We’ve developed the easyC connectivity system based on I2C. Learning I2C is much easier with a couple of easyC devices. You don’t need any soldering as you can connect them with cables of various lengths. Because of this, you’re less likely to make a mistake when connecting the devices.

 

We have some tutorials on I2C devices using easyC you can check out. We’re constantly adding new easyC devices to our Github repository, and all of them have well-written documentation. Be sure to keep an eye out on our tutorials page  to see more fun projects in the future!

 

We would also recommend reading up on UART  and SPI  protocols as well. Understanding these three protocols will help you when working with more complicated things in the future.

Leave a Reply