Create a gist now

Instantly share code, notes, and snippets.

Arduino Pro Mini Low power Sleep Example
/**
* Arduino Pro Mini Low power Sleep Example
*
* @license BSD Open Source License
* Copyright (c) 2004-2021 Abhijit Bose < salearj [at] hotmail [dot] com >
* If you require a license, see
* http://www.opensource.org/licenses/bsd-license.php
*
* @note
* This example show how to properly enter sleep mode and wake up
* the Arduino Pro Mini board using Watchdog Timer.
* Additionally this example reads a LDR sensor connected to A6 Pin
* and a DHT22 sensor connected to the D8 pin of the Pro Mini board.
* In case you would like to remove the DHT Portion you can remove
* the necessary code.
* The design is such that the code within the WDT flag guarded `if`
* is only executed ones after which the board sleeps for the desired
* time and then wakes up back to continue.
* Good part of using Watchdog Timer is that it remains enabled even
* in the lowest of the power modes.
* Here are the Connected items to the Pro Mini Board:
* A6 = LDR sensor
* D8 = DHT22 (Dout pin)
* D9 = Indicator LED (Active Low)
*
* @warning At the end of all serial sequences it needs some delay else
* even before the transmission could complete the board might get reset
* or garbage data starts flowing out due to misalignments in the serial
* shift register in the UART during sleep entry.
*
* Attributions:
* This work extends the examples provided by Donal Morrissey.
* His article: https://donalmorrissey.blogspot.com/2010/04/sleeping-arduino-part-5-wake-up-via.html
*/
#include <Arduino.h>
#include <avr/interrupt.h>
#include <avr/sleep.h>
#include <avr/power.h>
#include <avr/wdt.h>
// DHT Library
#include <dht.h>
//////////////////////////////////////////////////////////////////////////
// DHT Sensor Pin Declaration
#define DHT22_PIN 8
// Instance of SHT Sensor connected to Pin 8 of Pro Mini
dht DHT;
// WDT entry Flag
volatile uint8_t f_wdt=1;
//////////////////////////////////////////////////////////////////////////
// WDT Interrupt
ISR(WDT_vect)
{
if(f_wdt == 0)
{
f_wdt=1; // Reset the Flag
}
else
{
Serial.println(F("WDT Overrun!!!"));
}
}
//////////////////////////////////////////////////////////////////////////
// Sleep Configuration Function
// Also wake-up after
void enterSleep(void)
{
WDTCSR |= _BV(WDIE); // Enable the WatchDog before we initiate sleep
//set_sleep_mode(SLEEP_MODE_PWR_SAVE); /* Some power Saving */
set_sleep_mode(SLEEP_MODE_PWR_DOWN); /* Even more Power Savings */
sleep_enable();
/* Now enter sleep mode. */
sleep_mode();
sleep_bod_disable(); // Additionally disable the Brown out detector
/* The program will continue from here after the WDT timeout*/
sleep_disable(); /* First thing to do is disable sleep. */
/* Re-enable the peripherals. */
power_all_enable();
}
//////////////////////////////////////////////////////////////////////////
// SETUP FUNCTION
void setup() {
/*** Setup the WDT ***/
cli();
/* Clear the reset flag. */
MCUSR &= ~(1<<WDRF);
/* In order to change WDE or the prescaler, we need to
* set WDCE (This will allow updates for 4 clock cycles).
*/
WDTCSR |= (1<<WDCE) | (1<<WDE);
/* set new watchdog timeout prescaler value */
WDTCSR = 1<<WDP1 | 1<<WDP2; /* 1.0 seconds */
//WDTCSR = 1<<WDP0 | 1<<WDP1 | 1<<WDP2; /* 2.0 seconds */
//WDTCSR = 1<<WDP3; /* 4.0 seconds */
//WDTCSR = 1<<WDP0 | 1<<WDP3; /* 8.0 seconds */
/* Enable the WD interrupt (note no reset). */
//WDTCSR |= _BV(WDIE); // Not here but when we go to Sleep
sei();
pinMode(9, OUTPUT);
digitalWrite(9,LOW);
Serial.begin(9600);
Serial.println(F("Initialization complete."));
delay(10); //Allow for serial print to complete.
}
//////////////////////////////////////////////////////////////////////////
// LOOP FUNCTION
void loop() {
// Only Execute this part One time
if(f_wdt == 1) {
//////////////////////////
// PROCESSING BEGIN
digitalWrite(9,LOW); // LED Indication ON
Serial.print(analogRead(A6)); // Read and Print the Analog Input Pin used for LDR
// Read and Print the DHT pin
if (DHT.read22(DHT22_PIN) == 0) {
Serial.print(F(" Humidity: "));
Serial.print(DHT.humidity);
Serial.print(F(" Temp: "));
Serial.print(DHT.temperature);
}
Serial.println(); // Line Separator
digitalWrite(9,HIGH); // LED Indication OFF
delay(20); //Allow for serial print to complete.
// PROCESSING END
//////////////////////////
/* Don't forget to clear the flag. */
f_wdt = 0;
/* Re-enter sleep mode. */
enterSleep();
}
}
//////////////////////////////////////////////////////////////////////////
// END OF FILE
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment