Skip to content

I2C Communication

Group Work

This week, we tested I2C communication with my instructor Saverio, using two Arduino Uno.

What is I2C? I2C means Inter Integrated Circuit. It is a way for microcontrollers to talk to each other using only two wires:

  • SCL = clock wire
  • SDA = data wire

image01

You can read more about I2C on the CircuitDigest website (we used their guide too).


Step 1: Connect Two Boards

We started by connecting two Arduino boards. One board is the master (it sends data). The other is the slave (it receives data).

We connected:

  • SCL from master → SCL of slave
  • SDA from master → SDA of slave
  • Also connect GND and VCC between them

The slave board also needs to be connected to the computer using USB cable, so we can see the messages on the serial monitor.

image02


Step 2: Upload Code

We used example code from Arduino IDE:

  • For master: master_writer (File > Examples > Wire > master_writer)
  • For slave: slave_receiver (File > Examples > Wire > slave_receiver)

Important: The master must send data to the correct address. The slave must have the same address number in the code.


Some Useful I2C Commands

Here are some simple commands we used (from the tutorial):

#include <Wire.h>      // Add the I2C library

Wire.begin();          // Start as master
Wire.begin(address);   // Start as slave with address

Wire.beginTransmission(address);  // Start sending to slave
Wire.write("message");            // Send message
Wire.endTransmission();           // Finish sending

Wire.onReceive();      // This runs when slave gets data
Wire.read();           // Read data

Example Code: Master

This master sends two messages: one to address 8, one to 7.

#include <Wire.h>

void setup() {
  Wire.begin(); // Master starts
}

void loop() {
  Wire.beginTransmission(8);
  Wire.write("Hello 8");
  Wire.endTransmission();

  Wire.beginTransmission(7);
  Wire.write("Hello 7");
  Wire.endTransmission();

  delay(500);
}

Example Code: Slave

This slave receives messages and prints them on the serial monitor.

#include <Wire.h>

void setup() {
  Wire.begin(7);               // Set address 7
  Wire.onReceive(receiveEvent); // When data comes, run this function
  Serial.begin(9600);           // Start serial
}

void loop() {
  delay(100);
}

void receiveEvent() {
  while (1 < Wire.available()) {
    char c = Wire.read();
    Serial.print(c);
  }
}

Screenshot of the Serial Monitor

image03


More Boards

We also modified the code to receiver code to add a counter for the messages received.

// Based on
// Wire Slave Receiver
// by Nicholas Zambetti <http://www.zambetti.com>

// Modified by Saverio and Huahua May 2025


#include <Wire.h>
int x = 0;    // receive byte as an integer

void setup() {
  Wire.begin(8);                // join i2c bus with address #8
  Wire.onReceive(receiveEvent); // register event
  Serial.begin(9600);           // start serial for output
}

void loop() {
  //Wire.onReceive(receiveEvent); // register event
  delay(100);
}

void receiveEvent() {
  Serial.print("I told you ");         

  while (Wire.available()) { 
    char c = Wire.read(); 
    Serial.print(c);       
    }

      Serial.print(" for ");  
      Serial.print(x);         
      Serial.println(" times");  
x++;
}

Screenshot of the Serial Monitor

image04