What is thei2c protocol?
I2C (Inter-Integrated Circuit), pronounced I-squared-C, is a synchronous, multi-master, multi-slave, packet switched, single-ended, serial communication bus invented in 1982 by Philips Semiconductor (now NXP Semiconductors). It is widely used for attaching lower-speed peripheral ICs to processors and microcontrollers in short-distance, intra-board communication. Alternatively, I2C is spelled I2C (pronounced I-two-C) or IIC (pronounced I-I-C).
Source: Wikipedia
The two-wired protocol consists of the Serial Data Line(SDA) and Serial Clock Line(SCL). The start/stop conditions ensures the data start and end of the transmission, respectively.
i2c Dataframe
- Start Bit: The SDA is made 0 -> 1 while SCL is HIGH.
- Stop Bit: The SDA is made 1 -> 0 while SCL is HIGH.
- Device Address Bits( 7-10 bits): The device addresses gives access to all unique slave devices. A 7-bit device address gives access to 2^7 devices or 128 devices, An ACK bit '0' is sent to the master from a specific slave device to confirm its presence in the signal line.
- Read/Write Bit: '0' is sent to the slave when the master is writing to the slave device and vice-versa for a read operation.
- ACK/NACK Bit: If the address frame or data frame is successfully received, the receiver sends a bit '0' to the sender.
- Data Frame (8 Bits): The data frame for i2c protocol is 8 bits long which is sent after the ACK bit is acknowledged by the sender on receiving the receiver confirmation. An ACK bit of '0' is sent again by the receiver upon the successful reception of the data.
i2c speed modes
Bidirectional bus:–
- Standard-mode 100 kbit/s
- Fast-mode 400 kbit/s
- Fast-mode 1 Mbit/s
- High-speed mode 3.4 Mbit/s
Unidirectional bus:–
- Ultra Fast-mode 5 Mbit/s
Source: NXP i2c bus specification
Major Advantages and Disadvantages:
Pros:
- Multi Slave and Multi-Master protocol.
- Error handling with ACK bit.
- Clock stretching gives the flexibility to work with slow ICs.
Cons:
- Slow transmission speed because of overheads.
- Half duplex.
- Complexity increases with a higher number of master and slave devices.
- The size of the data frame is limited to 8 bits.
The Wire.h library establishes i2c communication between master and slave devices.
#include <Wire.h>
Following the pin diagrams of master and slave devices(micro-controllers), define the SDA and SCL lines.
#define SDA D1
#define SCL D2
The master and slave addresses are kept in constant variables.
const int16_t i2c_rpi=0x00; //master
const int16_t i2c_node=0x01; // slave 1
const int16_t i2c_ard=0x02; // slave 2
const int16_t i2c_disco=0x03; // slave 3
const int16_t i2c_esp32=0x04; // slave 4
const int16_t i2c_blue=0x05; // slave 5
In the setup, all the devices are joined with their specific SDA, SCL lines with the addresses of the devices.
Wire.begin(SDA,SCL,i2c_address); /* slave or master address depending on the slave or the master device respectively */
For Slave read/write, a specific request function is set up as well.
Wire.onRequest(requestEvent); /* for slave write request */
Wire.onReceive(receiveEvent); /* for slave read request */
Following this, the master sends the request or receive events to its slave devices with their unique addresses.
/*For read*/
Wire.requestFrom(i2c_slave_addr,data_size); /* slave address along with data bits requested. */
while(Wire.available())
{
char c=Wire.read();
Serial.println(c);
}
/*For Write*/
Wire.beginTransmission(i2c_slave_addr);
Wire.write("xyz");
Wire.endTransmission();
Configuring the pi for i2cTo implement the i2c communication using a raspberry pi, smbus2 library is a suitable one to establish the master-slave connection.
Few initial set up is required for the i2c interface in raspberry pi.
After logging in to the pi, enter this command and enable the i2c from the interface dropdown. reboot the pi.
sudo raspi-config
Install the smbus2 package and i2c tools.
sudo pip install smbus2
sudo apt-get install i2c-tools
To check the slave devices that have established the i2c interface.
sudo i2cdetect -y 1
Thesmbus2 library
from smbus2 import SMBus, i2c_msg
Read some data
with SMbus(1) as bus:
msg=i2c_msg.read(i2c_slave_addr,data_size)
bus.i2c_rdwr(msg)
Write some data
with SMbus(1) as bus:
msg=i2c_msg.write(i2c_slave_addr,data)
bus.i2c_rdwr(msg)
Interfacing with various micro-controllers- Raspberry Pi 3B Master
- Node MCU Slave1
- Arduino UNO Slave 2
- Blue-Pill(STM32F103C8T6) Slave 3
- DISCO-L475VG-IOT01A Slave 4
- ESP-32 Slave 5
Comments