sleep mode + wakeUPpin issue

Hi forum,
I've been searching the forum to solve a problem but couldn't find answer yet, so I'm asking for your help.
I have my custom board working, based on Arduino M0 pro (SAMD21G18A); I can get it into sleep mode for the time I need (tested with 1min/10 min/30 min/etc...) but I also want to insert a wake up from pin and back to sleep again. Wakeup from pin is also working but it resets my sleep time each time it wakes from pin. So if the order is to sleep for 10min, and after 5min it wakes up from PIN, it will go back to sleep but for 10 min, not for the remaining 5min...

here's simple code to count how many times it wakes up:

#define SLEEP_TIME 10

uint16_t wake_up_count=0;

void int_handle ()
{
  wake_up_count++;
}

void setup()
{
  SerialDEBUG.begin(115200);
  delay(100);
  pinMode(WAKE_UP_PIN, INPUT_PULLUP);
  LowPower.attachInterruptWakeup(WAKE_UP_PIN, int_handle, CHANGE);
}

void loop()
{
  // do stuff
  LowPower.sleep(1000 * SLEEP_TIME);   //go to sleep
  delay(5000);    // to allow manual connection to serial port
  SerialDEBUG.print(" Wake UP count == "); SerialDEBUG.println(wake_up_count,DEC);
  delay(100);
}

Thanks for watching.

Hi tozito,

Wakeup from pin is also working but it resets my sleep time each time it wakes from pin.

You should be able to call the LowPower.sleep() function (without millis), after the microcontroller has been woken up by an interrupt. This will put microcontroller to sleep once more, but without affecting the RTC alarm.

By the way, in order for the wake_up_count variable to be used in both the loop() function and the int_handle() interrupt service routine, it needs to be made volatile:

volatile uint16_t wake_up_count=0;

The reason is explained here: volatile - Arduino Reference.

Hi Martin.
Thanks for your reply!
I did try your suggestion to add "LowPower.sleep()" to the function handling the PIN interrupt but it did not work.
it seems it will sleep forever after a PIN interrupt detection. The idea was to continue the "count-down" from LowPower.sleep(1000 * SLEEP_TIME), at the point where it was at the moment of PIN interrupt.

Hi tozito,

Try this:

// Arduino Low Power Library Test
#include <ArduinoLowPower.h>

#define SLEEP_TIME 10                   // Sleep time in seconds

volatile boolean interrupt = false;     // Interrupt flag
boolean toggle = false;

void setup() 
{
  pinMode(8, INPUT_PULLUP);             // Configure the external interrupt and callback function on FALLING edge
  LowPower.attachInterruptWakeup(8, extInterrupt, FALLING);
  pinMode(LED_BUILTIN, OUTPUT);         // Configure the LED output
}

void loop() 
{ 
  LowPower.sleep(SLEEP_TIME * 1000);    // Put the microcontroller to sleep for 10 seconds, Zzzzz...
  digitalWrite(LED_BUILTIN, toggle);    // Toggle the LED
  toggle = !toggle;                     // Flip the toggle
  if (interrupt == true)                // If an external interrupt has occured
  {     
    interrupt = false;                  // Clear the interrupt flag
    LowPower.sleep();                   // Put the microcontroller to sleep once more
    digitalWrite(LED_BUILTIN, toggle);  // Toggle the LED
    toggle = !toggle;                   // Flip the toggle
  }
}

void extInterrupt() 
{
  interrupt = true;                     // Set the interrupt flag
}

Thanks again MartinL, and sorry for late reply.
Still have issues with this code... after external pin wake-up it goes to sleep, but always restart the sleep time count; so, it doesn't wake-up after the remaining time left, btu restart sleep timer.
Hare able to test it, to check if I'm doing something wrong here?

I finally managed to get it work, but with LowPower and RTCzero libs (using "epoch" option).
On external pin wake-up it reads epoch and thus I know how much more time it needs to sleep :slight_smile:

Now I've added a watchdog to it... using WDTZero lib. The thing is I cannot have more than 8 minutes on watchdog timer. Is there a another lib I can use, that will manage WD in sleep mode?

Hi tozito,

Glad to hear that you got it working.

The WDT is not really suited to counting over long durations and normally operates up to 16 seconds.

This is usually achieved using the Ultra Low Power 32.768kHz Oscillator (OSCULP32K) divided down to 1.024kHz and the WDT's timer set to trigger after 16384, (16384 / 1.024kHz = 16s).

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.