Arduino Basic Tutorial: I2C Communication in Arduino with Example
What is I2C Communication?
I2C (Inter-Integrated Circuit) is a communication protocol used by microcontrollers to communicate with other devices, such as sensors, memory chips, and other microcontrollers. It is a two-wire serial communication protocol that uses one wire for data transmission and another wire for clock synchronization. So in this article, we learn about I2C communication in Arduino.
Amazon Links:
*Please Note: These are affiliate links. I may make a commission if you buy the components through these links. I would appreciate your support in this way!
Arduino Pins for I2C Communication:
The external view of Arduino UNO R3 is shown below.
The I2C pins are on the upper right of the Arduino uno as you can see in the below figure. It is written as I2C (SCL) and I2C (SDA). Analog inputs A4 and A5 is also available for I2C Communication in Arduino. However, please note that in that case it cannot be used as an analog input.
About I2C communication
I2C communication is a serial communication method developed by Philips for the purpose of communicating between ICs.
What is I2C?
 I2C (Inter-Integrated Circuit) is a communication protocol used by microcontrollers to communicate with other devices, such as sensors, memory chips, and other microcontrollers. It is a two-wire serial communication protocol that uses one wire for data transmission and another wire for clock synchronization. I2C is a popular choice for communication between devices because it requires only a few wires and can support multiple devices on the same bus.
In the Arduino environment, I2C is implemented using the Wire library. The Wire library allows the Arduino to communicate with I2C devices using a simple set of functions. For example, the Arduino can send a request to an I2C device to read a specific register, or it can write data to an I2C device by specifying the device’s address and the data to be written.
I2C is a versatile communication protocol and is widely used in a variety of applications, including temperature sensing, display control, and data logging. It is an important feature of the Arduino and can greatly expand the capabilities of your projects.
features of I2C communication:
The I2C communication protocol is a popular protocol for communication between devices, and it is supported by the Arduino platform. Here are some features of the I2C communication protocol:
- Two-wire interface: I2C communication uses only two wires for communication, a serial data line (SDA) and a serial clock line (SCL).
- Multi-master: I2C is a multi-master communication protocol, which means that multiple devices can act as masters and initiate communication with other devices on the same bus.
- Addressing: Each device on the I2C bus has a unique address, and the address is used to identify the device when it wants to communicate with another device on the bus.
- Speed: I2C has a maximum speed of 3.4 Mbps. The speed can be adjusted by setting the clock frequency.
- Open drain output: I2C uses open drain output, which means that the output transistors are used to pull the signal line low, but they are not able to drive it high. This allows multiple devices to share the same signal line without conflicting with each other.
- Noise immunity: I2C has a built-in noise reduction mechanism, which makes it less susceptible to noise and interference compared to other communication protocols.
- Power consumption: I2C has a low power consumption compared to other communication protocols. This makes it suitable for use in battery-powered devices.
Communication speedÂ
Standard mode
100kbps
Fast mode 400kbps
bps: Bits per second 1kbps = 1000bit/s
In fact, in i2c based component have wires for power supply as well so there are total of  four wires are required for connection, “SCL”, “SDA”, “+ive”, and “-ive”.
Various sensors use the I2C communication method. Â For example.
Temperature, humidity, pressure
IR/Color/Proximity Sensor
etc….
How I2C Component Works:
I2C communication is divided into a ” master ” that controls electronic components and a ” slave ” that is controlled by instructions from the ” master ” .
When using Arduino,
master: Arduino
slave: electronic parts to be controlled.
Also, with the I2C communication method, it is possible to connect multiple electronic components that support I2C. Therefore, each electronic component is assigned a number called ” I2C address “. If you connect multiple devices, you can control the target electronic component by specifying the address assigned to the electronic component from Arduino. Also, I2C-compatible electronic components have an area called a “register” to store data. This area temporarily stores measurement values ​​from sensors, etc. By instructions from the Arduino, it is possible to obtain the sensor readings by retrieving this data from registers. It is also possible to write to registers from Arduino. For example, it is possible to display characters on the display. Data can be read and written by specifying the registered address.
Wire library for  I2C communication in Arduino:
An easy way to use I2C-compatible electronic components with Arduino is to use a library.
Library name: “Wire” library
* Standardly implemented in the IDE environment.
By using this library, each control function of I2C can be used.
#include <Wire.h>
After starting the Arduino IDE environment, you can use it by selecting
“Sketch” ⇒ “Include library” ⇒ “Wire” .
The functions of the Wire library are described below.
command | Description |
Wire.begin(address) | Initial processing of Wire library. Connected as a master or slave to the I2C bus. Parameter address: 7-bit slave address When omitted, it is connected to the bus as a master. |
Wire.reuestFrom(address,count) | Specify the address and data amount of the I2C device to be communicated. Request data from other devices. The data can be obtained using the available() and receive() functions. Parameter address: Address of device requesting data (7 bits) quantity: Number of bytes of data requested stop: true ⇒ Release I2C bus. false ⇒ Do not release the bus. |
Wire.beginTransmission(address) | Start transmission with the specified I2C device. Start transmission processing to the I2C slave of the specified address. After executing the transmission process, send the data to the queue with the write() function and execute the transmission with endTransmission(). Parameter address: Address to send (7 bits) |
Wire.endTransmission() | Finish transmission with the I2C device. Complete the transmission to the slave device. Parameters stop: true ⇒ release I2C bus false ⇒ keep connection Return value 0: success 1: buffer size exceeded 2: slave address sent, received NACK 3: data bytes sent, received NACK 4: other error |
Wire.write(value) Wire.write(string) Wire.write(data,length) |
Write data to an I2C device. Parameter value: Data to send (1 byte) string: Character string (char) data: Array (byte) length: Number of bytes to send (byte) Return value: Number of bytes sent (byte) |
Wire.available() | Get the amount of data that can be read. Returns the number of bytes read by read(). Return value Number of bytes that can be read |
Wire.read() | Data read from I2C device. Return value received data (byte) |
Wire.onReceive(handler) | Specifies the function to call when data is sent from the master. Parameter handler: Function name called when slave receives data |
Wire.onRequest(handler) | Specify the function to call when interrupted from the master. Parameter handler: function name to be called |
How to use Wire Library for I2C:
From here on, we will learn how to use this wire library in a real example.
Initial processing of Wire library
In order to be able to use the control functions for I2C, write the following in the setup() function.
void setup(){
Wire.begin();
}
Writing to I2C device registers
The procedure for sending data to the I2C device is as follows.
- Connect to the target I2C device with the Wire.beginTransmission() function.
- Send register address with Wire.write() function.
- Send the specified data with the Wire.write() function.
- End transmission with the I2C device with the Wire.endTransmission() function.
Wire.beginTransmission( I2C device address );
 Wire.write( register address );
 Wire.write( data to send );
 Wire.endTransmission();
Read I2C device register values
The procedure for receiving data from the I2C device is as follows.
- Connect to the target I2C device with the Wire.beginTransmission() function.
- Send register address with Wire.write() function.
- End transmission with the I2C device with the Wire.endTransmission() function.
- Specify the I2C device address and data amount in the Wire.requestFrom() function.
- Read data with Wire.read() function.
Wire.beginTransmission(I2Cdevice address );
 Wire.write(Register address );
 Wire.endTransmission( );
Address of I2C device
Using I2C you can connect multiple electronic components (devices). Therefore, it is necessary to specify the address of the electronic component to be controlled. You can use “117” addresses from “0x03” to “0x77” in hexadecimal notation. *0x means hexadecimal number. If it is 0b, it matches binary numbers. You can confirm the I2C component Address from the datasheet.Â
Example: How to Print a message on i2c LCD using i2c Communication in Arduino:
An I2C 16×2 LCD is a liquid crystal display (LCD) that is driven by an I2C interface. The “16×2” in the name refers to the fact that the LCD has 16 columns and 2 rows of characters. The LCD is connected to an Arduino microcontroller using the I2C bus, which is a communication protocol that allows multiple devices to be connected to the same bus and communicate with each other. The Arduino can send commands and data to the LCD over the I2C bus, which the LCD can then use to display text or other information.
I2C LCD Circuit Diagram with Arduino
Here is a basic circuit diagram for an I2C 16×2 LCD:
[LCD VCC]—[connect to Arduino VCC +5v]
 [LCD GND]—[ connect to Arduino GND]
[LCD SDA]—[ connect to Arduino SDA(A4)]
[LCD SCL]—[ connect to Arduino SCL(A5)]
The VCC and GND pins on the LCD should be connected to a power supply, such as the 5V and GND pins on the Arduino. The SDA and SCL pins on the LCD should be connected to the SDA(A4) and SCL(A5) pins on the Arduino, which are used for I2C communication.
An I2C LCD backpack is a circuit board that is attached to the back of an LCD display and provides an I2C interface for controlling the display. The backpack connects to the LCD’s data pins (usually D4-D7), control pins (usually RS, RW, and E), and power pins (usually VCC and GND). It also includes an I2C bus connector, which allows the backpack to be connected to an I2C bus on a microcontroller or other device.
Using an I2C LCD backpack can simplify the process of connecting an LCD display to a microcontroller, as it eliminates the need for a separate set of data and control lines for each display. It also allows multiple displays to be connected to a single I2C bus, which can be useful if you want to use multiple displays in a project.
Download library for i2c LCD:
How to add library:
To add the I2C library to your Arduino project, follow these steps:
- Open the Arduino IDE.
- Download the above libraries.
- In the Arduino IDE, go to Sketch > Include Library > Add .ZIP Library.
- Select the .ZIP file for the I2C libraries that you downloaded and click “Open”.
- The I2C library should now be added to your Arduino project and you can use it in your sketches
I2c Lcd Coding:
//libraries download links are given above.
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,16,2);Â //0x27 is the i2c address, while 16 = columns, and 2 = rows.
void setup() {
 lcd.init();                //Init the LCD
 lcd.backlight();           //Activate backlight   Â
 lcd.home();Â
}
void loop() {
 lcd.clear();
 lcd.print(“Fawad khan”);
 delay(10000);
}
Output:
summary
This time, I briefly explained I2C communication in Arduino, Â and we learn how to use i2c communication in real projects. So I hope this article will help you.
Feel free to comment if you have any questions or concerns.