Extended watchdog timer.

So, i read a bit on the forum about extending a watchdog timer. I found this:

nickgammon:
And here is an example of using a watchdog to wake after sleep. Yes, you have to do it multiple times to get more than 8 seconds, but it isn’t that bad:

// Example of sleeping and saving power

//
// Author: Nick Gammon
// Date:  25 May 2011

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

#define LED 13

// watchdog interrupt
ISR(WDT_vect)
  {
  wdt_disable();  // disable watchdog
  }

void myWatchdogEnable(const byte interval)
  { 
  MCUSR = 0;                          // reset various flags
  WDTCSR |= 0b00011000;              // see docs, set WDCE, WDE
  WDTCSR =  0b01000000 | interval;    // set WDIE, and appropriate delay

wdt_reset();
  set_sleep_mode (SLEEP_MODE_PWR_DOWN); 
  sleep_mode();            // now goes to Sleep and waits for the interrupt
  }

void setup()
{
pinMode (LED, OUTPUT);
}  // end of setup

void loop()
{
  digitalWrite (LED, HIGH);  // awake
  delay (2000);    // ie. do stuff here
  digitalWrite (LED, LOW);  // asleep

// sleep for a total of 20 seconds
  myWatchdogEnable (0b100001);  // 8 seconds
  myWatchdogEnable (0b100001);  // 8 seconds
  myWatchdogEnable (0b100000);  // 4 seconds

}  // end ofloop

// sleep bit patterns:
//  1 second:  0b000110
//  2 seconds: 0b000111
//  4 seconds: 0b100000
//  8 seconds: 0b100001

This will work for me, BUT, i’ll have to extend this for about 24 hours.

24 hours = 86400 seconds.
86400 seconds / 8 seconds per sleep= 10800
So i would have to add this 10800 times in my code to get this 24 hours sleep done. There is probabl a better way to do this.

Ant suggestions?

(deleted)

And would this work? Set n to 10800?

for (int i = 0; i < n; i++)
{
    // content in between these brackets
}

(deleted)

Bringamosa:
There is probabl a better way to do this.

Define 'better'

spycatcher2k:
I’d use a counter rather than a for loop, but that will work.

will google that tnx.

srnet:
Define ‘better’

well, less messy code for sure, 10800 lines of the same code looks bad to me…

Bringamosa:
well, less messy code for sure, 10800 lines of the same code looks bad to me…

Something like this?

int counter = 0;

void loop() {
  //.....
  digitalWrite (LED, HIGH);  // awake
  counter++; // +1
  if (counter >= 10800) {
    //do stuff here
    counter = 0; // start all over again
  }
  digitalWrite (LED, LOW);  // asleep
  //....
}

Leo…

@WaWa thanks.

So in my case something like this? If reading is below 150 i want the sleep cycle to start.

void loop() {

  if (photocellReading <= 150) { // distance less then 25 cm 
  
  Serial.println("afstand klein");
  Serial.println(photocellReading);
}

counter++; // +1
  if (counter >= 10800) {
  myWatchdogEnable (0b100001);
    counter = 0; // start all over again
 }

Wawa:
Something like this?

int counter = 0;

void loop() {
  //.....
  digitalWrite (LED, HIGH);  // awake
  counter++; // +1
  if (counter >= 10800) {
    //do stuff here
    counter = 0; // start all over again
  }
  digitalWrite (LED, LOW);  // asleep
  //....
}



Leo..

The way i tried to put it together in my code as posted above does nothing so somewhere i'm wrong i'll doe some research on the counter part thanks for helping.

Think again.
myWatchdogEnable is not inside (part of) the if() condition.
The counter increases with every loop(), and should increase with every sleep block.
Leo..

Thanks again for helping, guess it's back to the basic tutorials again since i'm still stuck here...

Hobby coder here, so there might be other/better ways to do this.
Untested, and still needs the LED setup and watchdog code added.
Leo…

const byte ldrPin = A0;
int ldrValue;
unsigned int counter = 0;
unsigned long previousMillis = 0;

void loop() {
  if (counter == 0) { // if not asleep
    ldrValue = analogRead(ldrPin);
    if (millis() >= previousMillis + 1000) { // print every second
      Serial.print("afstand is: ");
      Serial.println(ldrValue);
      previousMillis = millis();
    }
    if (ldrValue < 150) {
      Serial.print("Going to sleep now....");
      delay(25); // some time to print this line before sleeping
      counter = 1; // doubles as a flag
    }
  }
  else { // if asleep
    digitalWrite (LED, HIGH);
    delay(1); // shortflash LED to indicate sleep mode
    digitalWrite (LED, LOW);
    if (counter <= 10800) {
      myWatchdogEnable (0b100001);
      counter++;
    } else counter == 0;
  }
}

Wawa thanks a million. This works like a charm, nice to have this code to play around for a bit now.

Afterall i found out that after the sleep command the red light keeps on flashing telling me it’s in sleep mode while it’s not will have to tinker around a bit more so far the “for” command works best

for (int i = 0; i < n; i++)
{
    // content in between these brackets
}

I have added the watchdog code,
and a delay, because the sleep text did not print fast enough before sleeping.
Seems to work ok on a Nano (not tested current draw yet).

Which Arduino are you using, and how is the LDR connected (pin to ground or pin to VCC).
What value is the pull up/down resistor.
Is there a cap from pin to ground, or not.

Merged code attached.
Leo…

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

#define LED 13

const byte ldrPin = A0;
int ldrValue;
unsigned int counter = 0;
unsigned long previousMillis = 0;

// watchdog interrupt
ISR(WDT_vect)
{
  wdt_disable();  // disable watchdog
}

void myWatchdogEnable(const byte interval)
{
  MCUSR = 0;                          // reset various flags
  WDTCSR |= 0b00011000;               // see docs, set WDCE, WDE
  WDTCSR =  0b01000000 | interval;    // set WDIE, and appropriate delay

  wdt_reset();
  set_sleep_mode (SLEEP_MODE_PWR_DOWN);
  sleep_mode();            // now goes to Sleep and waits for the interrupt
}

void setup() {
  Serial.begin(9600);
  pinMode (LED, OUTPUT);
}

void loop() {
  if (counter == 0) { // if not asleep
    ldrValue = analogRead(ldrPin);
    if (millis() >= previousMillis + 1000) { // print every second
      Serial.print("afstand is: ");
      Serial.println(ldrValue);
      previousMillis = millis();
    }
    if (ldrValue < 150) {
      Serial.println("Going to sleep now....");
      delay(25); // some time to print this line before sleeping
      counter = 1; // doubles as a flag
    }
  }
  else { // if asleep
    digitalWrite (LED, HIGH);
    delay(1);
    digitalWrite (LED, LOW);
    if (counter <= 10800) {
      myWatchdogEnable (0b100001);
      counter++;
    } else counter == 0;
  }
}

Well, at this point the LDR is there to emulate the 3 states that i have on my nano with ultrasonic sensor.

So at this point i have the LDR with my uno to try to get everything to work. LDR is connected to A0 and vcc. resistor depending the amount of ambient light i have. The readings from the LDR are good, i see it all change. It works perfectly, however, when i try to combine your part of code with the existing code i have from the ultrasonic i'm getting some errors, just because of my noobness missing some characters or messing stuff up.....

Got everything running now! thanks a million for all the help!

I suppose you have the rest of your code below this line...

if (counter == 0) { // if not asleep
// your code

Good to hear you have it working.
Leo..