Hi, thanks a lot. What to do you think of this sketch that JOINS the extended watchdogtimer and LowPower library for sleep the board ?
Thanks a lot for your comments. Any comments will be very usefull for me and for everybody
Hope your answer.
/* Try to use watchdogtimer for:
1. Use LowPower library for sleep the ATMEGA (link: http://www.rocketscream.com/blog/2011/07/04/lightweight-low-power-arduino-library/)
2. Use the auto reset feature of ATMEGA in case a long loop or problems in the sketch. In this case, the time will be much more than 8 seconds.
For utility 2. I have to use ISR (WDT_vect) and use a counter to increase the WatchDogTimer enough to use it for 60 or 120 seconds or even more.
The sketch will be in a BOARD that not need to be active all time (It sleeps most of the time), but it needs an autoreset feature (just in case) because it uses a SIM900 shield (that usually has problems)
For utility 1. and 2. I need to change the ISR (WDT_vect) of the LowPower library. I have to delete it and rename library as LowPowerLong.h and redefine ISR (WDT_vect) in
this sketch.
ISR(WDT_vect) from LowPower.h is:
ISR (WDT_vect)
{
// WDIE & WDIF is cleared in hardware upon entering this ISR
wdt_disable();
}
I aslo need a boolean variable to know insie ISR that I came from LowPowerLong interrupt or from Long autoreset feature.
To provoque a long loop so the board will reset, just put a jumper between A0 and a 5V pin. To normal function, put hte jumper between A0 and GND pin. (see loop)
*/
#include "LowPowerLong.h" //It is the same as LowPower.h but deleting ISR(WDT_vect) function.
#include "avr/wdt.h"
volatile int counter;
volatile boolean counterEnabled = false;
#define counterMax 2 //Number of times of ISR(WDT_vect) to autoreset the board. I will autoreset the board after 8 secondes x counterMax
ISR (WDT_vect)
{
if (counterEnabled) {
counter += 1;
if (counter < counterMax - 1) {
wdt_reset(); // Reset timer, still in interrupt mode
} else {
MCUSR = 0;
WDTCSR |= 0b00011000; //WDCE y WDE = 1 --> config mode
WDTCSR = 0b00001000 | 0b100001; //clear WDIE (interrupt mode disabled), set WDE (reset mode enabled) and set interval to 8 seconds
//Arduino post's author put here 64 ms, but, I am a noob, so I prefer to repeat the loop again just in case. Finally I get what I want.
}
} else {
// It is only for sleep, so I copy source code from LowPower.h
// WDIE & WDIF is cleared in hardware upon entering this ISR
wdt_disable();
}
}
void setup()
{
wdt_disable();
// No setup is required for this library
pinMode(13,OUTPUT);
pinMode(A0,INPUT_PULLUP);
for (byte j = 0; j < 99; j++) { //In order to know the board has reset. Flash led lots of times.
digitalWrite(13, j % 2);
delay(50);
}
}
void wdt_long_enable()
{
counter = 0;
counterEnabled = true;
cli(); //disabled ints
MCUSR = 0; //clear reset status
WDTCSR |= 0b00011000; //WDCE y WDE = 1 --> config mode
WDTCSR = 0b01000000 | 0b100001; //set WDIE (interrupt mode enabled), clear WDE (reset mode disabled) and set interval to 8 seconds
sei(); //enable ints
}
void wdt_long_disable()
{
counterEnabled = false;
wdt_disable();
}
void loop()
{
wdt_long_enable();
//do stufff
if (analogRead(A0)>700) {
//A0 connected to 5V pin
delay(30000); //Let's go to reset the board. We will wait here more than 8 seconds * counterMax
} else {
//A0 connected to ground pin
}
wdt_long_disable();
for (unsigned int i = 0; i < 5; i++) {
LowPower.powerDown(SLEEP_1S, ADC_OFF, BOD_OFF); //Here I could sleep for much more time than autoreset-time as wdt_long_disable was called.
//Flash slow three times so I know that your are sleeping. (normally nothing will be here)
digitalWrite(13,HIGH);
delay(100);
digitalWrite(13,LOW);
delay(100);
digitalWrite(13,HIGH);
delay(100);
digitalWrite(13,LOW);
delay(100);
digitalWrite(13,HIGH);
delay(100);
digitalWrite(13,LOW);
delay(100);
}
}