64. I2C Slave with Sleep Mode

Design a power-efficient I2C-based Slave using an Arduino UNO board with the following functionalities:

  • The I2C slave is in sleep mode to save power.
  • A push button is connected to the I2C master. When pressed, it wakes up the slave via I2C.
  • A potentiometer is connected to a slave Arduino. Upon waking up, the slave reads its ADC value, sends it to the master, and then goes back to sleep mode.
  • The slave responds to every switch press by repeating this process.


NOTE: Use any I2C-supported microcontroller as I2C master.

Below given code is the sample code for Arduino UNO as a Master that receives ADC values from the I2C slave and prints on the serial monitor. 

This code can be used for demonstration.

#include <Wire.h>

#define SWITCH_PIN 3  // Pin connected to the switch

unsigned long debounce_delay = 50;     // Debounce delay in milliseconds
int last_button_state = 1;             // Previous button state (1: not pressed, 0: pressed)
int current_button_state = 1;          // Current button state
unsigned long last_debounce_time = 0;  // Timestamp of the last button state change

void setup() {
  Serial.begin(115200);                                                     // Initialize serial communication
  pinMode(SWITCH_PIN, INPUT_PULLUP);                                        // Set SWITCH_PIN as input with internal pull-up resistor
  Serial.println("Master is ready");                                        // Print setup message
  Serial.println("Press the pushbutton to read the ADC value form slave");  // Print setup message
  Wire.begin();                                                             // Join I2C bus as Master
}

void loop() {
  // Check if the switch is pressed with debounce handling
  if (is_debounced_press(SWITCH_PIN)) {
    // Request 2 bytes from Slave with address 0x08 (ADC value)
    Wire.requestFrom(0x08, 2);

    uint16_t receivedData = 0;  // Variable to store the received data
    if (Wire.available() >= 2) {
      // Read the low and high bytes of the received data
      uint8_t lowByte = Wire.read();   // Read the low byte
      uint8_t highByte = Wire.read();  // Read the high byte

      // Combine the high and low byte into a 16-bit value
      receivedData = (highByte << 8) | lowByte;  // Combine the two bytes

      // Print the received ADC value from the slave
      Serial.print("Received ADC value from slave: ");
      Serial.println(receivedData);
    } else {
      Serial.println("Read failed !!!");
    }
  }
}

// Function to handle debouncing of the button press
bool is_debounced_press(int button_pin) {
  int reading = digitalRead(button_pin);  // Read the current state of the button

  // If the button state has changed, reset the debounce timer
  if (reading != last_button_state) {
    last_debounce_time = millis();  // Update the last debounce time
  }
  last_button_state = reading;  // Save the current button state for the next loop

  // If the button state is stable for more than the debounce delay
  if ((millis() - last_debounce_time) > debounce_delay) {
    // If the button state has changed after the debounce delay
    if (reading != current_button_state) {
      current_button_state = reading;

      // Return true if the button is pressed (LOW state)
      if (current_button_state == 0) {
        return true;  // Valid press detected
      }
    }
  }

  return false;  // No valid press detected (debounced press)
}

 

 

Submit Your Solution