#include <avr/sleep.h>
#include <avr/power.h>
#include <avr/wdt.h>
#include <EEPROM.h>
// Utility macros
#define adc_disable() (ADCSRA &= ~(1<<ADEN)) // disable ADC (before power-off)
#define adc_enable() (ADCSRA |= (1<<ADEN)) // re-enable ADC
#define BODS 7 //BOD Sleep bit in MCUCR
#define BODSE 2 //BOD Sleep enable bit in MCUCR
/** the current address in the EEPROM (i.e. which byte we're going to write to next) **/
int addr = 0;
#define LED_PIN (13)
#define USB_PIN (9)
volatile int f_wdt=1;
/***************************************************
* Name: ISR(WDT_vect)
*
* Returns: Nothing.
*
* Parameters: None.
*
* Description: Watchdog Interrupt Service. This
* is executed when watchdog timed out.
*
***************************************************/
ISR(WDT_vect)
{
if(f_wdt == 0)
{
f_wdt=1;
}
// else
// {
// Serial.println("WDT Overrun!!!");
// }
}
/***************************************************
* Name: enterSleep
*
* Returns: Nothing.
*
* Parameters: None.
*
* Description: Enters the arduino into sleep mode.
*
***************************************************/
void enterSleep(void)
{
//set_sleep_mode(SLEEP_MODE_PWR_SAVE); /* EDIT: could also use SLEEP_MODE_PWR_DOWN for lowest power consumption. */
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
sleep_enable();
/* Now enter sleep mode. */
sleep_mode();
/* 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();
}
/***************************************************
* Name: setup
*
* Returns: Nothing.
*
* Parameters: None.
*
* Description: Setup for the serial comms and the
* Watch dog timeout.
*
***************************************************/
void setup()
{
//digitalWrite(0, LOW);
//digitalWrite(1, LOW);
pinMode(LED_PIN, OUTPUT);
digitalWrite(LED_PIN, LOW);
adc_disable();
// turn bod off
// bod consume 22 uA
MCUCR |= (1<<BODS) | (1<<BODSE);
MCUCR &= ~(1<<BODSE); // must be done right before sleep
int val = EEPROM.read(addr);
if(val==255){
EEPROM.write(addr, 0);
}
//Serial.begin(9600);
//Serial.println("Initialising...");
//delay(100); //Allow for serial print to complete.
//pinMode(LED_PIN,OUTPUT);
/*** Setup the WDT ***/
/* 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<<WDP0 | 1<<WDP3; /* 8.0 seconds */
/* Enable the WD interrupt (note no reset). */
WDTCSR |= _BV(WDIE);
//Serial.println("Initialisation complete.");
//delay(100); //Allow for serial print to complete.
}
/***************************************************
* Name: enterSleep
*
* Returns: Nothing.
*
* Parameters: None.
*
* Description: Main application loop.
*
***************************************************/
void loop()
{
if(f_wdt == 1)
{
int val = EEPROM.read(addr);
//int ret;
/* Toggle the LED */
//ret = digitalRead(LED_PIN);
//digitalWrite(LED_PIN, !ret);
// if(ret==HIGH){
// digitalWrite(USB_PIN, HIGH);
// delay(100);
// digitalWrite(USB_PIN, LOW);
// }
val++;
if(val>23){
digitalWrite(USB_PIN, HIGH);
delay(7000);
digitalWrite(USB_PIN, LOW);
EEPROM.write(addr, 0);
}else{
EEPROM.write(addr, val);
}
/* Don't forget to clear the flag. */
f_wdt = 0;
/* Re-enter sleep mode. */
enterSleep();
}
else
{
/* Do nothing. */
}
}
Discussions
Become a Hackaday.io Member
Create an account to leave a comment. Already have an account? Log In.