Created
December 1, 2016 15:37
-
-
Save keigezellig/fdbe345bc0df7b895f6048ccfcc62b33 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/*************************************************** | |
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