1

I want to use Arduino's sleep and wakeup functionality but have hit a roadblock and can't seem to get past it. As I am just prototyping for a final system, I cannot use the LowPower library to implement the functionality so I am doing it barebones. I am able to put the Arduino to sleep just fine, the main problem is with the watchdog timer. I have or I think I have configured it for a 8 sec interrupt to wake the Arduino back up from sleep but Arduino comes out of the sleep just as it enters it without any delay. The code is

#include <Arduino.h>
#include <avr/sleep.h>

void goToSleep();
void setupWDT();
void stopWDT();

ISR(WDT_vect) {
  sleep_disable(); // wake up the Arduino
}

void setup() {
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);

  stopWDT();

  pinMode(LED_BUILTIN, OUTPUT);

  Serial.begin(9600);
  Serial.println("Uno is in setup funtion.");

  bool ledState = 0;
  while(millis()<3000){
    digitalWrite(LED_BUILTIN, ledState);
    ledState = !ledState;
    delay(500);
  }
}

void loop() {
  Serial.println("Uno is awake.");
  digitalWrite(LED_BUILTIN, HIGH);
  delay(2000);
  Serial.println("Going to sleep...");
  digitalWrite(LED_BUILTIN, LOW);
  delay(100);

  setupWDT();
  goToSleep();
  stopWDT();
  delay(100);
  digitalWrite(LED_BUILTIN, HIGH);
}

void goToSleep() {
  ADCSRA &= ~(1<<ADEN); // disable ADC
  sleep_mode(); // put the Arduino to sleep
}

void setupWDT() {
  cli();
  WDTCSR |= (1 << WDCE);
  WDTCSR &= ~(1 << WDE);
  WDTCSR |= (1 << WDCE) | (1 << WDIE) | (1 << WDP3) | (1 << WDP0); // configured for 8 sec delay interrupt
  sei();
}

void stopWDT() {
  cli();
  MCUSR &= ~(1 << WDRF); // clear reset flag
  WDTCSR |= (1 << WDCE);
  WDTCSR &= ~(1<<WDE);
  WDTCSR = 0x00; // stop WDT
  sei();
}

1 Answer 1

1

Try changing this:

void setupWDT() {
  cli();
  WDTCSR |= (1 << WDCE);
  WDTCSR &= ~(1 << WDE);
  WDTCSR |= (1 << WDCE) | (1 << WDIE) | (1 << WDP3) | (1 << WDP0); // configured for 8 sec delay interrupt
  sei();
}

to:

void setupWDT() {
  cli();
  WDTCSR = (1 << WDCE) | (1 << WDE) ;
  WDTCSR = (1 << WDCE) | (1 << WDIE) | (1 << WDP3) | (1 << WDP0); // configured for 8 sec delay interrupt  
  sei();
}

It appears that your construct violates the 4 clock cycle window that the WDCE Watchdog Change Enable bit allows for updates to the WDE bit.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.