From the task, we understand that,
The Arduino UNO (ATmega328P) supports six sleep modes, each offering different power-saving levels:
For best power efficiency, use Power-down Mode with TWI address match interrupt for wake-up.
Here is a comparison of all sleep modes available in the Arduino UNO (ATmega328P):
Slave:
Master
NOTE: USB also provides power to both boards.
#include <avr/sleep.h>
#include <avr/power.h>
#include <avr/wdt.h> // Include WDT library
#include <Wire.h> // Include the Wire library for TWI/I2C communication
#define ADC_PIN A0 // ADC Input Pin
#define TWI_ADDRESS 0x08 // Set the TWI (I2C) address
volatile bool isRequest = false;
void wakeUpISR() {
// Empty ISR, just needed to wake the microcontroller on address match interrupt
}
void setup() {
pinMode(13, OUTPUT);
digitalWrite(13, LOW); // Turn off the onboard LED for power saving
// Disable Watchdog Timer
cli(); // Disable global interrupts
wdt_reset(); // Reset WDT
MCUSR &= ~(1 << WDRF); // Clear WDT reset flag
WDTCSR |= (1 << WDCE) | (1 << WDE); // Enable WDT configuration mode
WDTCSR = 0x00; // Disable WDT
sei(); // Enable global interrupts
// Disable External Interrupts (INT0 and INT1)
EIMSK = 0;
// Start the TWI (I2C) communication and set the address
Wire.begin(TWI_ADDRESS);
Wire.onRequest(requestEvent); // Register the request handler for address match
power_twi_enable(); // Enable TWI
}
void enterSleepMode() {
set_sleep_mode(SLEEP_MODE_PWR_DOWN); // Set sleep mode
cli(); // Disable interrupts to avoid race conditions
sleep_enable();
sleep_bod_disable(); // Disable Brown-Out Detector for lower power
sei(); // Re-enable interrupts
sleep_mode(); // Enter sleep mode (Execution stops here)
// Code resumes here after wake-up
sleep_disable();
delay(10); // Wait a short time for stability
}
void requestEvent() {
// Respond to the master's request for data (ADC value)
uint16_t adcValue = analogRead(ADC_PIN); // Read ADC value
Wire.write(adcValue & 0xFF); // Send lower nibble
Wire.write((adcValue >> 8) & 0xFF); // Send higher nibble
}
void loop() {
enterSleepMode(); // Sleep until an address match occurs
// The requestEvent() function will be triggered automatically when address match occurs
}
This Arduino I2C slave program minimizes power consumption by entering power-down sleep mode and waking up only when an I2C master requests data.
NOTE: During sleep mode, the TWI module stays active. When the TWI address match event occurs, it wakes up the Slave from sleep mode.
Key Functionalities:
0x08
. requestEvent()
to handle data requests.enterSleepMode
):requestEvent
):A0
.Working Flow: