SleepyDog library, watchdog.sleep (n) -- not working what am I missing...

Post here about your Arduino projects, get help - for Adafruit customers!

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
Locked
User avatar
tomjennings
 
Posts: 102
Joined: Thu Aug 17, 2006 1:21 am

SleepyDog library, watchdog.sleep (n) -- not working what am I missing...

Post by tomjennings »

I seem to be misunderstanding something with the SleepyDog library. I've reduced the problem to this simple example program:

Code: Select all

#include <Adafruit_SleepyDog.h>

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
}

unsigned long t;
int state;

void loop() {

 ////////// PICK ONE 
 // delay (10);
  int sleepMS= Watchdog.sleep (16);


  if (millis() > t) {
    switch (state) {
      case 0:
        digitalWrite (LED_BUILTIN, 1);
        t= millis() + 500;                         ///// THIS
        state= 1;
        break;

      case 1:
        digitalWrite (LED_BUILTIN, 0);
        t= millis() + 1000;                        //// THAT
        state= 0;
    }
  }
}
My target is Feather M4 Express, but I'm testing with a Mega 2560 for simplicity. A bare board.

With the first statement in loop() delay(10) in place, the LED blinks fine, half second on full second off. The delay makes time (millis()) "chunky" but that's fine.

With Watchdog.sleep (16) in place, the code appears to halt -- but I determined experimentally (by changing ///// THIS and //// THAT values to + 1, eg blink very fast) that in fact sleep() is sleeping for a very long time, seconds.

I realize sleep() can only handle fixed values (16, 32, etc). But any value I use results in this excessively long sleep.

Any suggestions?

User avatar
tomjennings
 
Posts: 102
Joined: Thu Aug 17, 2006 1:21 am

Re: SleepyDog library, watchdog.sleep (n) -- not working what am I missing...

Post by tomjennings »

OK I was thinking wrong, and looking in the wrong place for the answer (which is in the underlying Arduino libs).

Of course millis doesn't run when it's sleeping because it's just a timer tick. Duh. So of course my test code works as it does.

Here's a solution that works. All of my realtime code uses a Timer library I worked up that internally uses millis(), and so I will incorporate a fix like this into the timer lib and simply compensate for the time spent sleeping.

I imagine there's some round-off error involved but it should come out in the wash; software timers for tasks are generally "equal to or greater than" so a millisecond error won't kill me.

Code: Select all

#include <Adafruit_SleepyDog.h>

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
}
uint32_t millisCompensator = 0;

uint32_t long t;
int state;

void loop() {

  // Sleep, then adjust "millis()" for the number of millseconds we were asleep.
  //

  unsigned w= Watchdog.sleep (1);

  millisCompensator += w;
  uint32_t M= millis() + millisCompensator;

  if (M > t) {
    switch (state) {
      case 0:
        digitalWrite (LED_BUILTIN, 1);
        t= M + 500;
        state= 1;
        break;

      case 1:
        digitalWrite (LED_BUILTIN, 0);
        t= M + 1000;
        state= 0;
        break;
    }
  }
}

Locked
Please be positive and constructive with your questions and comments.

Return to “Arduino”