Introduction

I2C (Inter-Integrated Circuit) is a serial communication bus used to connect peripherals to a microcontroller, such as the Arduino. Created by Philips Semiconductor in the 1980s, I2C allows multiple peripherals to be connected with just two wires: one for data (SDA) and one for clock (SCL).

Each device on the I2C bus has a unique address, enabling the master to communicate individually with each slave.

How it works

The I2C link is a half-duplex link, i.e. you can’t listen and send data at the same time. The I2C link has an average data rate of 100 kilo-hertz to 1 Mega-hertz.

As shown in the diagram below, the I2C link is non-exclusive, meaning that a master can talk to several slaves.

A wide range of electronic components can communicate with each other using just 2 wires:

  • Data signal: SDA
  • Clock signal: SCL

I2C pin on Arduino board

To use I2C with an Arduino board, you need to know which pins are dedicated to I2C communication. The pins vary slightly depending on the Arduino model, but generally they are :

  • Arduino Uno: A4 (SDA) and A5 (SCL).
  • Arduino Mega: 20 (SDA) and 21 (SCL).
  • Arduino Leonardo: 2 (SDA) and 3 (SCL).

For the Arduino Uno board, these can be found in the image below:

Writing on the I2C

To write a message on the I2C you first need to know the I2C address on which you want to send the message. Here’s the program for sending data over the I2C:

#include <Wire.h>

void setup() {
  Wire.begin(); // Initialize as master
}

void loop() {
  Wire.beginTransmission(0x3C); // Start transmission with device at address 0x3C
  Wire.write(“Hello”); // Send data
  Wire.endTransmission(); // End transmission
  delay(500);
}

Reading on the I2C

Here’s an example of how to read the Arduino board’s I2C at address 0X3C:

#include <Wire.h>

void setup() {
  Wire.begin(0x3C); // Initialize as slave with address 0x3C
  Wire.onReceive(receiveEvent); // Register a receive function
  Serial.begin(9600);
}

void loop() {
  delay(100); // Leave time for other tasks
}

void receiveEvent() {
  while (Wire.available()) {
    char c = Wire.read(); // Read data sent by master
    Serial.print(c); // Display received data
  }
}

Conclusion

If you’d like to see an example of an Arduino project using I2C, take a look at our course on the RTC module.

If you’d like to learn about other communication buses, you’ve got UART and SPI.