SimpleSleep
An Arduino library for simple means of putting your Arduino into low power sleep modes.
|
An Arduino library for simple means of putting your Arduino into sleep modes in order to save power when you are not doing much, supports a variety of common microcontrollers used with Arduino...
Upload the example to your Arduino and stand back in awe of the results.
Sleeping forever is the simplest type of sleep and uses the least power, but only a RESET (or power-cycle of course) will wake you up. This can be very useful for "hit the button to do a thing" type devices, "hit the button play a sound", "hit the button light a light"... you just stick your button between RESET and Ground then in your code sleep forever when you have done the thing you want to do every time you hit the button...
#include <SimpleSleep.h> SimpleSleep Sleep; void setup() { } void loop() { /* Do something interesting here */ /* After you are done, sleep forever. */ Sleep.forever(); }
Note that sleep forever does not alter your pin states, a HIGH pin will still be HIGH, a LOW pin will still be LOW, pullups will still be on if so configured. So you should also disable those (set to INPUT is often best for minimising power consumption, but it depends on your devices).
#include <SimpleSleep.h> SimpleSleep Sleep; const uint8_t ledPin = 13 void setup() { pinMode(ledPin, OUTPUT); } void loop() { digitalWrite(ledPin, HIGH); Sleep.deeplyFor(1000); digitalWrite(ledPin, LOW); Sleep.deeplyFor(1000); }
The difference between sleeping deeply and sleeping lightly is chip dependant (and may be no practical difference at all), but generally SimpleSleep determines to leave Brown-Out-Detection ON in light sleeping, but turns it off in deep sleeping.
#include <SimpleSleep.h> SimpleSleep Sleep; const uint8_t ledPin = 13 void setup() { pinMode(ledPin, OUTPUT); } void loop() { digitalWrite(ledPin, HIGH); Sleep.lightlyFor(1000); digitalWrite(ledPin, LOW); Sleep.lightlyFor(1000); }
Using lightly/deeply generally is going to stop your serial communications and your millis count will not count during sleeping. The simplest way around this (there are others) is to use "idle" mode, which basically leaves everything running as much as possible, including serial and timers.
#include <SimpleSleep.h> SimpleSleep Sleep; const uint8_t ledPin = 13 void setup() { pinMode(ledPin, OUTPUT); Serial.begin(9600); } void loop() { // Ask the user a question... Serial.println(F("How many times to flash 0-99: ")); // Wait using low-power idle... while(!Serial.available()) { Sleep.idle(); } // Read their answer... char buf[4]; Serial.readBytesUntil('\n', buf, sizeof(buf)-1 ); // And do a thing... for( int8_t x = atoi(buf); x >= 0; x--) { digitalWrite(ledPin, HIGH); Sleep.deeplyFor(1000); // (we don't need to listen to serial here) digitalWrite(ledPin, LOW); Sleep.deeplyFor(1000); // (we don't need to listen to serial here) } }
Doing a calibration, which takes up to a few hundred milliseconds, can make for more accurate timing...
#include <SimpleSleep.h> SimpleSleep Sleep; SimpleSleep_Cal SleepCal; const uint8_t ledPin = 13 void setup() { SleepCal = Sleep.getCalibration(); pinMode(ledPin, OUTPUT); } void loop() { digitalWrite(ledPin, HIGH); Sleep.deeplyFor(1000, SleepCal); digitalWrite(ledPin, LOW); Sleep.deeplyFor(1000, SleepCal); }
Only LEVEL type interrupts generally work and they must be longer than usual so if you connect a button between the interruptPin and ground, hold it down
#include <SimpleSleep.h> SimpleSleep Sleep; const uint8_t ledPin = 13 const uint8_t interruptPin = 2; void setup() { pinMode(ledPin, OUTPUT); pinMode(interruptPin, INPUT_PULLUP); attachInterrupt(digitalPinToInterrupt(interruptPin), interruptHandler, LOW); } void interruptHandler() { // In this example, do nothing we will just wakeup and continue from where-ever // we went to sleep. } void loop() { // Blink once then sleep until an external interrupt happens digitalWrite(ledPin, HIGH); delay(50); digitalWrite(ledPin, LOW); Sleep.deeply(); }
Sleeping lightly ( Sleep.lightly()
) can also be used, which again typically leaves Brown-Out Detection on while deeply disables that.
I recommend to just look at the examples which show you how to use all the features, but if you want the nitty-gritty then here is the full class reference