Zbotic Logo Zbotic Logo
  • Home
  • Shop
  • Sale
  • 3D Print Service
  • PCB Service
  • B2B
  • Blogs
  • Contact Us
0 0

View Wishlist Add all to cart

0 0
0 Shopping Cart
Shopping cart (0)
Subtotal: ₹0.00

View cartCheckout

  • Shop
  • About Us
  • Contact Us
  • Reseller
  • Blogs
020 69134444
1800 209 0998
[email protected]
Help Desk
Facebook Twitter Instagram Linkedin YouTube
Zbotic Logo Zbotic Logo
0 0

View Wishlist Add all to cart

0 0
0 Shopping Cart
Shopping cart (0)
Subtotal: ₹0.00

View cartCheckout

All departments
  • 3D Print Service
  • 3D Printer
  • Batteries & Chargers
  • Development Boards
  • Drone Parts
  • EBike parts
  • Sensor Modules
  • Electronic Components
  • Electronic Modules
  • IoT and Wireless
  • Mechanical Parts and Workbench Tools
  • Motors & Drivers & Pumps & Actuators
  • DIY and Robot Kits
  • Show more
  • Home
  • Shop
  • Sale
  • 3D Print Service
  • PCB Service
  • B2B
  • Blogs
  • Contact Us
Return to previous page
Home Arduino & Microcontrollers

Arduino Sleep Modes: Reduce Power Consumption to Microamps

Arduino Sleep Modes: Reduce Power Consumption to Microamps

March 11, 2026 /Posted byJayesh Jain / 0

A battery-powered Arduino running at full speed drains a typical AA cell in hours. But with proper use of sleep modes, that same circuit can run for months or even years on the same battery. Arduino sleep mode low power techniques leverage the microcontroller’s hardware sleep states to cut current draw from 15–20 mA down to 0.1–5 µA — a reduction of 1,000 to 100,000 times. This guide covers every sleep mode on the ATmega328P, how to wake from them, power consumption measurements, and complete code for common low-power sensor applications.

  • Why Sleep Modes Matter for Battery Life
  • ATmega328P Sleep Modes Overview
  • Power Consumption by Mode
  • Using avr/sleep.h
  • Wake-Up Sources
  • WDT-Based Periodic Wake
  • Interrupt-Based Wake
  • LowPower Library: The Easy Way
  • Additional Power Reduction Techniques
  • Frequently Asked Questions

Why Sleep Modes Matter for Battery Life

Consider a typical remote temperature sensor checking readings every 60 seconds. With a 1000 mAh battery at the Arduino’s active current of 15 mA, that’s about 66 hours of runtime. The same device using Power-Down sleep between readings, drawing 0.4 µA asleep and 15 mA active for 50 ms per wake cycle, has an average current of:

Average = (15000 µA × 0.05s + 0.4 µA × 59.95s) / 60s ≈ 13.0 µA

That’s 1000 mAh / 0.013 mA ≈ 77,000 hours — about 8.8 years on the same battery. Sleep modes aren’t an optimisation; for battery-powered devices, they’re a fundamental design requirement.

The savings are available for any periodic sensor — weather stations, GPS trackers, soil moisture monitors, water leak detectors, livestock trackers, and smart home sensors all benefit dramatically from sleep modes.

ATmega328P Sleep Modes Overview

The ATmega328P supports six sleep modes, progressively shutting down more hardware subsystems:

Mode CPU I/O Clk Flash WDT Timer/Counter Wake Sources
Idle Stop Run Run Run Run Any interrupt
ADC Noise Reduction Stop Stop Stop Run ADC only ADC, external INT, TWI, WDT
Power-Save Stop Stop Stop Run T2 only WDT, T2 overflow, external INT, TWI
Power-Down Stop Stop Stop Run Stop WDT, external INT, TWI
Standby Stop Stop Run Run Stop WDT, external INT, TWI
Extended Standby Stop Stop Run Run T2 only WDT, T2 overflow, external INT, TWI

For most low-power projects, Power-Down is the right choice. It stops everything except the WDT and external interrupt logic, achieving the lowest possible current draw while still allowing periodic wake-up.

Power Consumption by Mode

Measured at 5V, 25°C on an ATmega328P (bare chip, not full Arduino board):

Mode Typical Current (5V) Notes
Active (16 MHz) ~12 mA Bare chip; full Arduino Uno adds ~5 mA for regulators, LEDs
Idle ~5 mA CPU stopped, peripherals still running
ADC Noise Reduction ~1.1 mA ADC active for accurate conversion
Power-Save ~1.1 µA Timer2 running; BOD disabled
Power-Down ~0.1–0.5 µA BOD disabled; only WDT osc. running

Important note: measurements above are for the bare ATmega328P chip. A complete Arduino Uno board draws ~4–5 mA more due to the USB-Serial chip (ATmega16U2 or CH340), onboard LED, and voltage regulator quiescent current. For true low-power deployments, use bare ATmega328P on a minimal PCB, an Arduino Pro Mini (no USB chip), or a 3.3V board with a low-quiescent regulator.

Recommended: Arduino Pro Mini 328 – 3.3V/8 MHz — No USB chip, no power LED by default, runs at 3.3V/8 MHz — the go-to board for battery-powered projects requiring true low-power sleep. In Power-Down mode draws under 1 µA at 3.3V.

Using avr/sleep.h

The AVR libc sleep library provides a clean API for entering sleep modes:

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

void goToSleep() {
  // Choose sleep mode
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);

  // Optional: disable ADC to save more power
  power_adc_disable();

  // Enable sleep, then sleep
  sleep_enable();
  sleep_cpu();       // CPU halts here; resumes after wake

  // Code resumes here after wake-up interrupt
  sleep_disable();   // Always disable sleep after waking
  power_adc_enable();
}

Available sleep mode constants:

  • SLEEP_MODE_IDLE
  • SLEEP_MODE_ADC
  • SLEEP_MODE_PWR_SAVE
  • SLEEP_MODE_PWR_DOWN
  • SLEEP_MODE_STANDBY
  • SLEEP_MODE_EXT_STANDBY

Wake-Up Sources

In Power-Down mode, the processor can only wake from:

  1. External Interrupt (INT0 / INT1): Level-triggered LOW level, or edge (rising/falling) depending on interrupt configuration. These are digital pins D2 (INT0) and D3 (INT1) on the Uno.
  2. Pin Change Interrupt (PCINT): Any change on enabled PCINT pins (all Arduino pins can be PCINT sources). Level change detection — less precise timing than INT0/INT1.
  3. Watchdog Timer interrupt
  4. TWI (I2C) address match — if the device is acting as an I2C slave

Key limitation: in Power-Down mode, the INT0/INT1 pins can only detect a LOW level (not rising or falling edge) unless the BOD (Brown-Out Detector) is active. To wake on a rising edge with minimal power, keep BOD disabled and use a LOW-level interrupt with a pull-up resistor — when a button is pressed pulling the pin low, the interrupt fires.

WDT-Based Periodic Wake

The most common pattern for sensor devices: sleep in Power-Down mode, wake every N seconds via WDT interrupt, read sensor, sleep again.

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

volatile bool wdtWake = false;

// WDT ISR — just set flag, no Serial here
ISR(WDT_vect) {
  wdtWake = true;
}

void enableWDT_interrupt(uint8_t timerBits) {
  cli();
  WDTCSR |= (1 << WDCE) | (1 << WDE);
  // Interrupt-only mode (no reset), with specified period
  WDTCSR = (1 << WDIE) | timerBits;
  sei();
}

void sleepNow() {
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  power_adc_disable();
  power_spi_disable();
  power_twi_disable();
  power_timer0_disable();
  power_timer1_disable();
  power_timer2_disable();
  power_usart0_disable();

  sleep_enable();
  sleep_cpu();
  sleep_disable();

  // Re-enable needed peripherals after wake
  power_all_enable();
}

void setup() {
  Serial.begin(9600);
  // WDT interrupt every 8 seconds (WDTO_8S bits = WDP3|WDP0)
  enableWDT_interrupt((1 << WDP3) | (1 << WDP0));
}

void loop() {
  if (wdtWake) {
    wdtWake = false;
    // Read sensor
    float temp = readTemperature();
    Serial.print("Temp: ");
    Serial.println(temp);
    Serial.flush(); // Ensure Serial transmits before sleep
    // Re-arm WDT interrupt for next cycle
    enableWDT_interrupt((1 << WDP3) | (1 << WDP0));
  }
  sleepNow();
}

For intervals longer than 8 seconds (the WDT maximum), count WDT cycles:

volatile uint8_t wdtCount = 0;
#define SLEEP_CYCLES 8  // 8 × 8s = 64 seconds between readings

ISR(WDT_vect) { wdtCount++; }

void loop() {
  if (wdtCount >= SLEEP_CYCLES) {
    wdtCount = 0;
    doSensorReading();
  }
  sleepNow();
}
Recommended: DS18B20 Programmable Resolution — A perfect low-power sensor companion: the DS18B20 draws only 1 µA in parasitic power mode while idle, and completes a 9-bit conversion in 93.75 ms — making it ideal for sleep-wake sensor nodes that minimise active time.

Interrupt-Based Wake

For event-driven applications (a PIR motion sensor, a door contact, a button), wake on external interrupt rather than WDT:

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

#define WAKE_PIN 2  // INT0 = D2

volatile bool triggered = false;

ISR(INT0_vect) {
  triggered = true;
}

void sleepUntilEvent() {
  // Configure INT0 for LOW level wake
  EICRA &= ~((1 << ISC01) | (1 << ISC00));  // LOW level
  EIMSK |= (1 << INT0);   // Enable INT0
  sei();

  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  sleep_enable();
  sleep_cpu();
  sleep_disable();

  EIMSK &= ~(1 << INT0);  // Disable INT0 after wake
}

void setup() {
  Serial.begin(9600);
  pinMode(WAKE_PIN, INPUT_PULLUP);  // Pull-up: LOW when PIR triggers
}

void loop() {
  sleepUntilEvent();
  if (triggered) {
    triggered = false;
    Serial.println("Motion detected!");
    // Process event...
    delay(5000);  // Active window: 5 seconds
    Serial.flush();
  }
}

LowPower Library: The Easy Way

The LowPower library by Rocket Scream wraps all the avr/sleep.h complexity into a clean one-liner API:

#include "LowPower.h"

void setup() {
  Serial.begin(9600);
}

void loop() {
  // Read sensors
  float temp = readTemperature();
  Serial.println(temp);
  Serial.flush();

  // Sleep for 8 seconds: Power-Down, ADC off, BOD off
  LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);

  // Execution resumes here after 8 seconds
}

Install via Arduino Library Manager: search for “Low-Power” by Rocket Scream Electronics. Available sleep periods: SLEEP_15MS, SLEEP_30MS, SLEEP_60MS, SLEEP_120MS, SLEEP_250MS, SLEEP_500MS, SLEEP_1S, SLEEP_2S, SLEEP_4S, SLEEP_8S, SLEEP_FOREVER.

For SLEEP_FOREVER (wake on external interrupt only):

void loop() {
  // Attach interrupt before sleeping
  attachInterrupt(digitalPinToInterrupt(2), wakeISR, LOW);
  LowPower.powerDown(SLEEP_FOREVER, ADC_OFF, BOD_OFF);
  detachInterrupt(digitalPinToInterrupt(2));
  // Handle event
  processEvent();
}
Recommended: DHT11 Digital Relative Humidity and Temperature Sensor Module — A simple, affordable sensor for sleep-wake weather station projects. At 500 µA active current during a 25 ms reading and 0 draw asleep (when powered off by a mosfet), it fits well in duty-cycled low-power sensor nodes.

Additional Power Reduction Techniques

Sleep modes alone don’t capture all available savings. Additional techniques compound the reduction:

1. Disable the Brown-Out Detector (BOD)

The BOD constantly monitors supply voltage, drawing ~20 µA. In Power-Down mode, disabling BOD via MCUCR before sleeping saves significant current. The LowPower library’s BOD_OFF parameter handles this automatically.

2. Lower the Supply Voltage

ATmega328P power draw scales roughly linearly with voltage and quadratically with clock speed. Running at 3.3V instead of 5V reduces active current by ~33%. Running at 8 MHz instead of 16 MHz halves dynamic power in active mode. The Pro Mini 3.3V/8 MHz combines both.

3. Power Peripherals via a Mosfet

Sensors and modules draw quiescent current even when not actively reading. A P-channel mosfet (like 2N7000 or SI2307) controlled by an Arduino output pin can completely cut power to a peripheral between readings:

#define SENSOR_POWER_PIN 5  // Controls mosfet gate

void readSensor() {
  digitalWrite(SENSOR_POWER_PIN, HIGH); // Power on sensor
  delay(100);   // Allow sensor to stabilise
  float reading = sensor.read();
  digitalWrite(SENSOR_POWER_PIN, LOW);  // Power off
  return reading;
}

4. Disable Unused Arduino Peripherals

The power.h library lets you disable individual hardware peripherals:

#include <avr/power.h>

void setup() {
  power_adc_disable();    // ADC: ~300 µA saved
  power_spi_disable();    // SPI: ~1.5 mA at 16 MHz
  power_twi_disable();    // TWI/I2C
  power_timer1_disable(); // Timer1 (if not using PWM or Servo)
  power_timer2_disable(); // Timer2 (if not using tone())
  power_usart0_disable(); // UART (if not using Serial)
}

5. Remove Onboard LEDs

The Uno’s power LED draws ~2 mA permanently. For long-term battery deployments, physically remove this LED (D1 on the board) or cut its trace. The TX/RX LEDs are only active during serial communication.

Recommended: Arduino Nano RP2040 Connect with Header — Features onboard WiFi/BT with dedicated sleep modes for the RP2040 and the NINA-W102 module, suitable for low-power IoT projects requiring occasional wireless transmissions between deep sleep intervals.

Frequently Asked Questions

Does millis() still work after sleeping?

Partially. Timer0 (which drives millis()) is stopped during Power-Down sleep. millis() will not increment while the CPU is asleep. After waking, millis() resumes from where it left off — it does not account for time spent sleeping. If you need accurate elapsed time tracking across sleep cycles, track the expected sleep duration manually and add it to a software clock counter, or use an external RTC module like the DS3231.

Will Serial.print() work after waking from sleep?

Yes, but always call Serial.flush() before entering sleep to ensure any pending transmission completes. UART transmission in progress when you enter sleep will be interrupted. After waking, the UART peripheral is re-enabled and Serial works normally. If you disabled the USART with power_usart0_disable(), re-enable it with power_usart0_enable() after waking.

What is the minimum achievable current draw with an Arduino Pro Mini?

With the Pro Mini 3.3V version: remove the power LED (saves ~1 mA), disable BOD, enter Power-Down mode — typical measured current is 0.1–0.2 µA at 3.3V. The main residual draw is the voltage regulator’s quiescent current (~50 µA for the common MIC5205). Bypass the regulator and power the 3.3V pin directly from a LiPo or regulated supply to achieve the sub-µA chip current.

Can I use sleep modes with the Arduino Nano 33 IoT or Nano RP2040?

These boards use different microcontrollers (SAMD21 and RP2040 respectively) with their own sleep/dormant modes. The avr/sleep.h library is AVR-specific and won’t compile for these boards. Use the Arduino Low Power library (by Arduino SA) for SAMD21 boards, or the RP2040’s SDK dormant mode for the RP2040. Concepts are identical — the API differs.

How do I measure the actual sleep current of my circuit?

The current in sleep mode (sub-µA range) is too low for most standard multimeters to read accurately. Use a dedicated power profiler like the Nordic PPK2, Current Ranger by Low Power Lab, or a precision microammeter. Alternatively, measure the voltage across a 100 kΩ resistor in series with the power supply — at 0.1 µA, this gives a 10 mV drop readable by a standard multimeter set to mV.

Ready to build battery-powered Arduino projects? Browse our selection of Arduino boards optimised for low-power applications at Zbotic — including the Pro Mini, Nano Every, and Nano RP2040 Connect, plus sensors and modules suitable for long-life battery-powered deployments across India.

Tags: arduino battery life, arduino low power, arduino power down, arduino sleep mode, arduino wdt sleep, avr sleep
Share Post
  • Facebook
  • Linkedin
  • Whatsapp
Arduino Waveform Generator: Bu...
blog arduino waveform generator build a function generator with dds 594823
blog arduino rs485 serial communication long distance data transfer tutorial 594827
Arduino RS485 Serial Communica...

Related posts

Svg%3E
Read more

Arduino Batch Programming: Flash Multiple Boards Quickly

April 1, 2026 0
Table of Contents Introduction Components and Hardware Setup Wiring Diagram and Connections Complete Code with Explanation Customization and Improvements Troubleshooting... Continue reading
Svg%3E
Read more

Arduino Based Radar System with Ultrasonic Sensor

April 1, 2026 0
Table of Contents Introduction Components and Hardware Setup Wiring Diagram and Connections Complete Code with Explanation Customization and Improvements Troubleshooting... Continue reading
Svg%3E
Read more

Arduino Automatic Plant Monitor: Sunlight, Moisture, Temperature

April 1, 2026 0
Table of Contents Introduction Components and Hardware Setup Wiring Diagram and Connections Complete Code with Explanation Customization and Improvements Troubleshooting... Continue reading
Svg%3E
Read more

Arduino Lie Detector: GSR Sensor Polygraph Project

April 1, 2026 0
Table of Contents Introduction Components and Hardware Setup Wiring Diagram and Connections Complete Code with Explanation Customization and Improvements Troubleshooting... Continue reading
Svg%3E
Read more

Arduino Metal Detector: Build a Treasure Finder

April 1, 2026 0
Table of Contents Introduction Components and Hardware Setup Wiring Diagram and Connections Complete Code with Explanation Customization and Improvements Troubleshooting... Continue reading

Add comment Cancel reply

Your email address will not be published. Required fields are marked

Facebook Twitter Instagram Pinterest Linkedin Youtube

Get the latest deals and more.

Download on Google Play Download on the App Store

Call us: 020 69134444 / 1800 209 0998

Monday - Saturday 09:30 AM - 06:00 PM
For Technical Supports Email: [email protected]
For Sales / Enquiries Email: [email protected]

  • My Account

    • Cart

    • Wishlist

    • Checkout

    • My Orders

    • Track Order

    • My Account

  • Information

    • FAQs

    • Blogs

    • Career

    • About Us

    • Contact Us

    • Payment Options

  • Policies

    • Privacy Policy

    • Terms & Conditions

    • GST Input Tax Credit

    • Shipping Return Policy

    • E-Waste Collection Points

    • Our Sitemap

© Zbotic.in is registered trademark of Moxie Supply Pvt Ltd – All Rights Reserved
Login
Use Phone Number
Use Email Address
Not a member yet? Register Now
Reset Password
Use Phone Number
Use Email Address
Register
Already a member? Login Now