I2C Communication Protocol

Introduction

What is I2C?

I2C (Inter-Integrated Circuit) is a serial communication protocol used for connecting multiple devices on a bus. It was developed by Philips Semiconductor (now NXP Semiconductors) in the 1980s and has become widely adopted in various electronic systems.

Working Principle of I2C

The I2C bus consists of two lines: SDA (Serial Data Line) and SCL (Serial Clock Line). The bus operates in a master-slave architecture, where the master device initiates and controls the communication with the slave devices. The master device generates the clock signal on the SCL line, and the data is transferred bidirectionally on the SDA line.

The communication starts with the master device sending a start condition, which consists of a falling edge on the SDA line while the SCL line is high. After the start condition, the master device sends a 7-bit address (or 10 bits in the case of a high-speed mode) of the slave device it wants to communicate with, followed by a bit indicating whether it wants to read from or write to the slave device.

The slave devices acknowledge their address by pulling the SDA line low during the ninth clock cycle. Then, data is transmitted in 8-bit chunks, with each byte being acknowledged by the receiving device. Multiple bytes can be sent in a single transfer, and the communication is terminated with a stop condition, which consists of a rising edge on the SDA line while the SCL line is high.

Types of I2C

  1. Standard Mode: Supports communication at up to 100 kbit/s.
  2. Fast Mode: Supports communication at up to 400 kbit/s.
  3. Fast Mode Plus: Supports communication at up to 1 Mbit/s.
  4. High-Speed Mode: Supports communication at up to 3.4 Mbit/s.
  5. Ultra-Fast Mode: Supports communication at up to 5 Mbit/s.

Pins of I2C

The I2C bus typically requires four pins

  1. SDA (Serial Data Line): Used for bidirectional data transfer.
  2. SCL (Serial Clock Line): Provides the clock signal for synchronized data transfer.
  3. Vcc (Power Supply): Supplies power to the devices on the bus.
  4. GND (Ground): Common ground reference for the devices.

Applications of I2C

I2C is commonly used for communication between various devices, such as microcontrollers, sensors, memory chips, display modules, and many other integrated circuits. Some common applications of I2C include:

  • Interfacing sensors and actuators with microcontrollers.
  • Controlling and configuring peripheral devices.
  • EEPROM (Electrically Erasable Programmable Read-Only Memory) communication.
  • Real-time clock (RTC) modules.
  • Display interfaces for LCD or OLED screens.
  • Communication with analog-to-digital converters (ADCs) and digital-to-analog converters (DACs).

Example of Arduino connecting to a DHT11 temperature and humidity sensor using I2C

Let’s take the example of connecting an Arduino to an I2C-based temperature and humidity sensor, the DHT11. Here’s the code and explanation:

#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <DHT.h>
#include <DHT_U.h>

#define DHTPIN 2
#define DHTTYPE DHT11

DHT_Unified dht(DHTPIN, DHTTYPE);

void setup() {
  Serial.begin(9600);
  dht.begin();
  sensor_t sensor;
  dht.temperature().getSensor(&sensor);
  dht.humidity().getSensor(&sensor);
}

void loop() {
  sensors_event_t event;
  dht.temperature().getEvent(&event);
  if (isnan(event.temperature)) {
    Serial.println("Error reading temperature!");
  } else {
    Serial.print("Temperature: ");
    Serial.print(event.temperature);
    Serial.println(" °C");
  }
  dht.humidity().getEvent(&event);
  if (isnan(event.relative_humidity)) {
    Serial.println("Error reading humidity!");
  } else {
    Serial.print("Humidity: ");
    Serial.print(event.relative_humidity);
    Serial.println(" %");
  }
  delay(2000);
}

Explanation

  1. Include the necessary libraries: Wire for I2C communication, Adafruit_Sensor, DHT, and DHT_U for the DHT sensor.
  2. Define the pin to which the DHT sensor is connected (DHTPIN) and the type of sensor (DHTTYPE).
  3. Initialize the serial communication and start the DHT sensor.
  4. Obtain the sensor information and set up the sensor objects.
  5. Enter the loop function, where the temperature and humidity values are read and printed.
  6. Use the getEvent function to obtain the temperature and humidity values from the sensor.
  7. Check if the values are valid (isnan) and print the temperature and humidity readings.
  8. Add a delay to provide a time gap between readings.

Specifications of I2C

  • Bit Rates: I2C supports various bit rates depending on the mode, ranging from 100 kbit/s to 5 Mbit/s.
  • Addressing: I2C uses 7-bit or 10-bit addressing, allowing up to 128 or 1024 devices on the bus, respectively.
  • Voltage Levels: I2C typically operates at 3.3V or 5V, depending on the devices connected to the bus.
  • Open-Drain: I2C uses an open-drain configuration, allowing multiple devices to share the bus without conflicts. A pull-up resistor is used to set the idle state of the bus to high.
  • Acknowledgment: Each byte sent on the bus is acknowledged by the receiving device by pulling the SDA line low during the ninth clock cycle.
  • Multi-Master Support: I2C supports multiple master devices on the bus, allowing for more complex communication scenarios.

FAQs about I2C

Q1: Can I connect multiple devices on the same I2C bus? A1: Yes, I2C supports multiple devices on a single bus. Each device must have a unique address to avoid conflicts.

Q2: What is the maximum distance between I2C devices? A2: The maximum distance depends on factors such as bus capacitance and voltage levels. In general, I2C is designed for short-distance communication within a PCB or nearby devices.

Q3: Can I use different voltage levels for I2C devices? A3: It is possible to interface devices with different voltage levels using level shifters or voltage translators to ensure proper communication.

Q4: Can I use I2C with microcontrollers other than Arduino? A4: Yes, I2C is a widely adopted standard, and many microcontrollers support I2C communication. The code may vary depending on the specific microcontroller platform.

Q5: How do I find the I2C address of a device? A5: The I2C address of a device is typically provided in its datasheet or documentation. Alternatively, there are tools and libraries available that can scan the bus and detect connected I2C devices.

Difference between I2C, SPI, UART, CAN and Modbus

FeatureI2CSPIUARTCAN (Controller Area Network)Modbus
CommunicationSynchronousSynchronousAsynchronousAsynchronousAsynchronous
Bus TopologyMulti-master, multi-slaveMulti-master, multi-slavePoint-to-point, multi-dropmulti-master, multi-slaveMaster-slave, multi-drop
Number of Lines2 (SDA, SCL)4 (MISO, MOSI, SCLK, SS)2 (TX, RX)2 (CANH, CANL)2 (RS485+, RS485-)
Data DirectionBidirectionalFull-duplexBidirectionalBidirectionalBidirectional
Maximum SpeedVaries (up to 5 Mbit/s)Varies (up to several tens of Mbit/s)Varies (up to several Mbit/s)Varies (up to 1 Mbit/s)Varies (up to 115.2 kbit/s)
Error DetectionNo built-in error detectionNo built-in error detection
No built-in error detectionBuilt-in error detection and correctionNo built-in error detection
Addressing7-bit or 10-bit addressNo addressingNo addressing11-bit or 29-bit identifierNo built-in error detection
ApplicationsSensors, EEPROM, displays, peripheralsFlash memory, ADC, DAC, displaysSerial communication, GPS, Bluetooth, Wi-FiAutomotive, industrial control, roboticsIndustrial automation, SCADA systems
Hardware PinsSDA, SCL, Vcc, GNDMISO, MOSI, SCLK, SS, Vcc, GNDTX, RX, Vcc, GNDCANH, CANL, Vcc, GNDRS485+, RS485-, Vcc, GND
Industry StandardWidely adoptedCommon in embedded systemsWidely used in serial communicationCANH, CANL, Vcc, GNDWidely used in industrial automation

What is ACK and NACK in I2C?

In I2C (Inter-Integrated Circuit) communication, ACK (acknowledge) and NACK (not acknowledge) are signals used to indicate the successful reception of data between the master and slave devices on the bus.

After the transmission of each byte of data on the SDA (Serial Data Line), the receiver, which can be either the master or a slave device, sends an acknowledgment signal to the transmitter. This acknowledgment signal is called an ACK or NACK.

  • ACK (Acknowledge): When the receiving device successfully receives a byte of data, it pulls the SDA line low during the ninth clock cycle (ACK bit), indicating that it acknowledges the reception. The transmitter, whether it’s the master or a slave device, detects the low level on the SDA line and knows that the byte of data was received successfully. The transmitter can then proceed to send the next byte.
  • NACK (Not Acknowledge): If the receiving device cannot successfully receive a byte of data, it leaves the SDA line high during the ninth clock cycle (NACK bit), indicating that it does not acknowledge the reception. This can happen, for example, if the receiving device is busy, not ready to receive data, or if there was an error during the transmission. When the transmitter detects a high level on the SDA line during the ACK bit, it understands that the byte of data was not acknowledged and can take appropriate action, such as retransmitting the data or terminating the communication.

The ACK/NACK mechanism allows for error detection and flow control in I2C communication. It ensures that the transmitting device knows whether the data was successfully received by the receiving device, enabling reliable data transfer between devices on the I2C bus.

What is read bit and write bit in I2C?

In I2C (Inter-Integrated Circuit) communication, the terms “read bit” and “write bit” refer to the specific bit transmitted on the bus to indicate the direction of data transfer during a transaction.

When a master device initiates communication with a slave device on the I2C bus, it sends a 7-bit or 10-bit address, followed by a single bit that determines whether it wants to read from or write to the slave device.

  • Read Bit: The read bit is set to logic high (1) when the master device wants to read data from the slave device. This indicates that the master expects the slave to transmit data back to it.
  • Write Bit: The write bit is set to logic low (0) when the master device wants to write data to the slave device. This indicates that the master intends to transmit data to the slave.

The read bit and write bit are essential for establishing the direction of data flow in an I2C transaction. They allow the master device to inform the slave device whether it expects to read or write data during the communication.

More: