Editorial Solution

I2C (Inter-Integrated Circuit) 

  • Uses only two wires for communication.
  • SDA (serial data) wire: Used for data exchange.
  • SCL (serial clock) wire: It is a clock signal. Only the master device has control over this SCL line.
  • The I2C bus has an open drain configuration, meaning it can pull the corresponding signal line low but not drive it high.
  •  Hence, the line will enter an unknown state. Pull-up resistors need to be connected to the SCL and SDA pins to avoid this.
  •  We are going to use Wire.h library which enables the internal pull-up resistor(20k to 50K ) by default for I2C communication. 

Note: While communicating with devices using the I2C communication protocol, pull-up resistors must be used. The value of pull-up resistors may vary depending on the devices used.

  • We use  100KHz speed for I2C communication. It is the default speed for Arduino UNO, we can change this speed using Wire.setClock(frequency);. Maximum frequency is 400KHz for Arduino UNO.
  • When using an Arduino as a slave, we can set the slave address to any 7-bit value between 0x08 and 0x77. Here we use a 0x08 slave address. 

First of all, let's do the hardware connection.

  1. Master(Arduino UNO)
    • Push-Button is connected to any available GPIO pin with an internal pull-up register.
  2. Slave(Arduino UNO)
    • LED is connected using 330Ω to ensure safe current flow through it.
  3. Master and Slave Connection
    • Both communicate with each other via I2C communication, so the I2C  pins(SCL, SDA ) of the master are connected to the corresponding I2C  pins of the slave.
    • And ground should be common.

Circuit Diagram

CODE

We need to develop two codes, one for the master and another for the slave.

Master Arduino Board Code

#include <Wire.h>

#define slaveAddress 0x08  // slave address
#define switchPin 2
uint8_t ledState = 0;  // LED state
uint8_t error;

unsigned long debounce_delay = 50;     // Debounce delay in milliseconds
int last_switch_state = 1;             // Previous switch state
int current_switch_state = 1;          // Current switch state
unsigned long last_debounce_time = 0;  // Timestamp of the last switch state change

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

  pinMode(switchPin, INPUT_PULLUP);
  Serial.begin(9600);
}

void loop() {
  // check if switch is pressed or not
  if (is_debounced_press(switchPin)) {
    ledState = !(ledState);
    Wire.beginTransmission(slaveAddress);    
    Wire.write(ledState);                     // Store the state of LED in i2c buffer
    error = Wire.endTransmission();           // send data to slave
    if (error == 0) {
      Serial.println("Successful data transmission");
    } else {
      Serial.println("ERROR in data transmission");
    }
  }
}



bool is_debounced_press(int switch_pin) {
  int reading = digitalRead(switch_pin);

  // If the button state has changed, reset the debounce timer
  if (reading != last_switch_state) {
    last_debounce_time = millis();
  }

  last_switch_state = reading;  // Update the previous state

  // If the button state is stable for longer than the debounce delay, update the state.
  if ((millis() - last_debounce_time) > debounce_delay) {
    if (reading != current_switch_state) {
      current_switch_state = reading;

      // Return true if the button is pressed (LOW state)
      if (current_switch_state == 0) {
        last_switch_state = reading;
        return true;
      }
    }
  }

  return false;  // No valid press detected
}

 

Slave Arduino board Code

#include <Wire.h>

#define ledPin 8
#define slaveAddress 0x08
void setup() {
  // Initialize arduino as I2C slave (Slave address is 8)
  Wire.begin(slaveAddress);
  Wire.onReceive(receiveEvent);  // Attach a function to handle incoming data

  pinMode(ledPin, OUTPUT);
}

void loop() {
}

// Function to handle incoming data
void receiveEvent(int bytes) {
  while (Wire.available()) {
    int received = Wire.read();  // Read the incoming byte
    if (received == 1) {
      digitalWrite(ledPin, HIGH);
    } else if (received == 0) {
      digitalWrite(ledPin, LOW);
    }
  }
}

 

Understand the code

Master Code

  • is_debounced_press(int switch_pin)This function detects debounced button presses. It returns TRUE if the button press is detected.
  • If a button press is detected, the LED state is toggled (ON or OFF) and the updated state is transmitted to the slave.

Slave Code

  • We first define the slave address as 0x08.
  • After receiving data from the master, void receiveEvent(int bytes) is called, which changes the state of the LED according to the data received from the master.   

 

OUTPUT         

Hardware Setup 


 

Output Video


 

 


 

 

Submit Your Solution