Skip to content

Instantly share code, notes, and snippets.

@keigezellig
Created December 1, 2016 15:37
Show Gist options
  • Save keigezellig/fdbe345bc0df7b895f6048ccfcc62b33 to your computer and use it in GitHub Desktop.
Save keigezellig/fdbe345bc0df7b895f6048ccfcc62b33 to your computer and use it in GitHub Desktop.
/***************************************************
Arduino Low Power processing
How to use the low power mode with watchdoge timer on Arduino
Based on:
'Example 2: Arduino Power Down Sleep and CC3000 Shutdown
Created by Tony DiCola (tony@tonydicola.com)
Designed specifically to work with the Adafruit WiFi products:
----> https://www.adafruit.com/products/1469
Adafruit invests time and resources providing this open source code,
please support Adafruit and open-source hardware by purchasing
products from Adafruit!
Based on CC3000 examples written by Limor Fried & Kevin Townsend
for Adafruit Industries and released under a BSD license.
All text above must be included in any redistribution.'
****************************************************/
#include <SPI.h>
#include <avr/sleep.h>
#include <avr/power.h>
#include <avr/wdt.h>
int sleepIterations = 0;
volatile bool watchdogActivated = false;
// Define watchdog timer interrupt.
ISR(WDT_vect)
{
// Set the watchdog activated flag.
// Note that you shouldn't do much work inside an interrupt handler.
watchdogActivated = true;
}
void sleep()
{
// Set sleep to full power down. Only external interrupts or
// the watchdog timer can wake the CPU!
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
// Turn off the ADC while asleep.
power_adc_disable();
// Enable sleep and enter sleep mode.
sleep_mode();
// CPU is now asleep and program execution completely halts!
// Once awake, execution will resume at this point.
// When awake, disable sleep mode and turn on all devices.
sleep_disable();
power_all_enable();
}
void setup()
{
doOtherSetupStuff()
setupWatchdog()
}
void doOtherSetupStuff()
{
//Add code to do other setup stuff, like initialize ports, sensor etc.
}
void loop()
{
// Don't do anything unless the watchdog timer interrupt has fired.
if (watchdogActivated)
{
watchdogActivated = false;
// Increase the count of sleep iterations and take a sensor
// reading once the max number of iterations has been hit.
sleepIterations += 1;
if (sleepIterations >= MAX_SLEEP_ITERATIONS) {
// Reset the number of sleep iterations.
sleepIterations = 0;
doStuffWhenAwake()
}
}
// Go to sleep!
sleep();
}
void doStuffWhenAwake()
{
//Add code to do when awake, e.g. sending sensor data
}
void setupWatchdog()
{
// Setup the watchdog timer to run an interrupt which
// wakes the Arduino from sleep every 8 seconds.
// Note that the default behavior of resetting the Arduino
// with the watchdog will be disabled.
// This next section of code is timing critical, so interrupts are disabled.
// See more details of how to change the watchdog in the ATmega328P datasheet
// around page 50, Watchdog Timer.
noInterrupts();
// Set the watchdog reset bit in the MCU status register to 0.
MCUSR &= ~(1<<WDRF);
// Set WDCE and WDE bits in the watchdog control register.
WDTCSR |= (1<<WDCE) | (1<<WDE);
// Set watchdog clock prescaler bits to a value of 8 seconds.
WDTCSR = (1<<WDP0) | (1<<WDP3);
// Enable watchdog as interrupt only (no reset).
WDTCSR |= (1<<WDIE);
// Enable interrupts again.
interrupts();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment