74. Sleep Mode with Button Press Wake-Up

From the task, we understand that,

  • Low-power operation: The system stays in a low-power state, waking up only when the push button is pressed.
  • Minimal power consumption: Ensures the system consumes very little power during idle periods.
  • Power-down Sleep Mode: Utilizes the highest power savings available on the ATmega328P (Arduino UNO).
  • User interaction: The system wakes up and processes data only when the user interacts via the button press.

The Arduino UNO (ATmega328P) supports six sleep modes, each offering different power-saving levels:

  1. IDLE Mode – Lowest power saving, CPU stops but peripherals (Timer, ADC, Serial, etc.) keep running. Fast wake-up.
  2. ADC Noise Reduction Mode – Reduces noise for ADC conversions by stopping the CPU and some peripherals.
  3. Power-down Mode – Maximum power saving; Only an external reset, watchdog reset/interrupt, brown-out reset, 2-wire serial interface match, INT0/INT1 level interrupt, or pin change interrupt can wake the MCU. All generated clocks halt, except for asynchronous modules.
  4. Power-save Mode – Similar to Power-down but allows Timer2 to keep running for periodic wake-ups.
  5. Standby Mode – Like Power-down, but with an active oscillator for faster wake-up.
  6. Extended Standby Mode – Same as Standby, but keeps Timer2 running for periodic tasks.

For best power efficiency, use Power-down Mode with external interrupts for wake-up.

Here is a comparison of all sleep modes available in the Arduino UNO (ATmega328P):

 

Hardware connection

  1. Connect the Arduino UNO board to the PC using a USB cable to establish communication with the Serial Monitor.
  2. Push Button:
    • Connected to D2 (INT0) for an external interrupt.
    • One terminal is connected to GND.
    • The other terminal is connected to D2 with an internal pull-up resistor (avoiding an external pull-up).
  3. Potentiometer:
  • Terminal 1 → Vcc.
  • Terminal 2 → Pin A0.
  • Terminal 3 → GND.

Circuit Connection

Firmware

Before writing the firmware, let’s break down the key functionalities:

  • Sleep Mode Implementation
    • The Arduino UNO (ATmega328P) supports various sleep modes.
    • SLEEP_MODE_PWR_DOWN is the lowest power mode, turning off everything except external interrupts.
    • The sleep_bod_disable() function disables the Brown-Out Detector (BOD), further reducing power consumption.
  • External Interrupt for Wake-Up
    • The system remains in sleep mode and wakes up when the button is pressed.
    • Interrupt 0 (INT0) on pin D2 is configured to trigger on a falling edge (when the button is pressed).
  • ADC Measurement After Wake-Up
    • After waking up, the system reads the ADC value from the potentiometer (A0).
    • The value is printed to the Serial Monitor for monitoring.
  • Returning to Sleep Mode
    • After printing the ADC value, the system re-enters sleep mode, waiting for the next button to press.

 

Code

#include <avr/sleep.h>
#include <avr/power.h>
#include <avr/interrupt.h>

#define INT0_PIN 2  // External Interrupt (D2)
#define ADC_PIN A0  // ADC Input Pin
#define DEBOUNCE_DELAY 50

bool isPressed = false;

void wakeUpISR() {
  // Empty ISR, just needed to wake the microcontroller
}

void setup() {
  pinMode(13, OUTPUT);
  digitalWrite(13, LOW);  //Turning off the on board LED for power saving
  pinMode(INT0_PIN, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(INT0_PIN), wakeUpISR, FALLING);
}

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(DEBOUNCE_DELAY);
  if (digitalRead(2) == LOW)
    isPressed = true;
}

void loop() {
  enterSleepMode();  // Sleep until button press
  if (isPressed) {
    Serial.begin(115200);  // Restore Serial after wake-up
    Serial.print("ADC value: ");
    Serial.println(analogRead(ADC_PIN));  // Print ADC value after waking up
    delay(10);                            // Allow time for stability
    isPressed = false;
  }
}

 

Code Explanation

Setup Function (setup()):

  • Configure Pin D2 as INPUT_PULLUP.
  • Attach External Interrupt (INT0) to wakeUpISR() with a FALLING edge trigger on Pin D2.

Sleep Mode (enterSleepMode()):

  • Set Power-down sleep mode for power savings.
  • Temporarily disable interrupts with cli().
  • Enable sleep mode and disable BOD for further savings.
  • Re-enable interrupts with sei() and enter sleep using sleep_mode().

Debouncing Handling:

  • delay(DEBOUNCE_DELAY): Handles button debounce.
  • digitalRead(2) == LOW: Checks if button is pressed.
  • isPressed = true: Flags a valid button press.

Loop Function (loop()):

  • Call enterSleepMode() to enter low-power state.
  • After wake-up, read ADC value from potentiometer and print.
  • Add a small delay for stability before repeating the cycle.

 

Output

Power Saving Analysis

  • Active Mode Consumption25-30 mA.
  • Sleep Mode Consumption14-17 mA.
  • Power Reduction: Significant decrease in the current draw by enabling sleep mode.
  • Conclusion: Implementing sleep mode enhances energy efficiency.

 

Hardware Setup

Serial Monitor Output

Video


 

Submit Your Solution

Note: Once submitted, your solution goes public, helping others learn from your approach!