Boron Sleep wakeup using GPIO 'AND' after a fixed Time

Hi All,

I am trying to get my Boron to wake up every 1 minute and report on the no. of counts detected by its PIR motion sensor. I am using the .gpio and .duration options with the SystemSleepMode. Here is my program, currently it looks very ugly I am sure there got to be an elegant way to doing this.

SYSTEM_MODE(MANUAL);

#define ledPin D7 // LED
#define pirPinDigital D2
volatile byte count = 0;

uint32_t beforeSleepTime, lastWakeupTime, timeSlept, ONE_MINUTE = 60 * 1000;  

SystemSleepConfiguration config;

#include <Wire.h>

void setup()
{
  pinMode(ledPin, OUTPUT);
  pinMode(pirPinDigital, INPUT_PULLUP);                                 
  attachInterrupt(digitalPinToInterrupt(pirPinDigital), Counter, CHANGE); 
  Serial.begin(9600);
  beforeSleepTime = millis();
}

void loop()
{ 
  beforeSleepTime = millis();
  config.mode(SystemSleepMode::STOP)
      .gpio(D2, RISING)
      .duration(ONE_MINUTE);
  SystemSleepResult result = System.sleep(config);
  lastWakeupTime = millis();
  timeSlept = lastWakeupTime - beforeSleepTime;

  if (result.wakeupReason() == SystemSleepWakeupReason::BY_GPIO)
  {
    ONE_MINUTE = ONE_MINUTE - timeSlept;   // Subtract the amount of time slept
  }

  if (result.wakeupReason() == SystemSleepWakeupReason::BY_RTC)    // Wake up properly, act.
  {
    for (int i = 0; i < count; i++)             // The action taken
    {                              // Count indicated using LED pulses.
      digitalWrite(ledPin, HIGH);
      delay(100);
      digitalWrite(ledPin, LOW);
      delay(100);
    }                                         // End of action
    ONE_MINUTE = 60 * 1000;
  }
}

void Counter()
{
  count += 1;
}

It should be something simple that I am missing. I tried looking around in the documentation and the community, but probably missed it. Any advice, guidance would be appreciated.

Regards,
Joseph

Can you elaborate a bit more… what is working… what is not working? Does it not fall asleep, not wake up, not count like it should. A little more description of the problem you are encountering would help.

Hi @jgskarda, things are working fine. Like no problem with regards to falling asleep, waking up and counting. I was wondering if there was any way to enable the Boron to monitor activity at its GPIO while it is asleep!.

Which would mean I could remove all that round about code subtracting the time it slept and tidying up the program substantially. The way it is written at the moment looks a bit odd to me.

@Joseph17 ,

I am fairly familiar with what you are trying to do and perhaps I could give you some ideas on how to solve it:

  1. When you are in stop mode sleep, the program code execution stops so millis() stops counting

  2. Think of having two modes - One where you wake from the interrupt, count and go back to sleep as quickly as you can (under 1 second). The second where you wake due to duration and report your counts. In this approach, you get your counts and periodically report them based on the wakeupReason.

  3. A suggestion as you refine your code, try to eliminate delay() where you can.

  4. To see how long you slept, you can use Time functions as the Real Time Clock (RTC) keeps running in STOP mode. If you want to get to lower power sleep modes, you will need an external RTC.

Hope this helps,

Chip

2 Likes
  1. When you are in stop mode sleep, the program code execution stops so millis() stops counting

A small correction that on Gen 3 platforms micros and millis counters continue to count in STOP sleep mode (albeit with much lower resolution).

2 Likes

@avtolstoy , Did not realize that - thank you for pointing this out!

Chip

Hi @chipmc and @avtolstoy, thanks for your inputs.

So I kind of saw that and tried it out.
ultraLowPower

I think RTC does keep running even in ULTRA_LOW_POWER mode (but not in HIBERNATE mode for Gen 3 devices). I used it to successfully wake up in 1 hour to send data, while using GPIO to wake up when motion is sensed to update counter and go back to sleep.

I will see if I can get hold of an external RTC (that would tidy the code as well) and sleep in HIBERNATE mode to see if that will make any difference with battery consumption. Thanks again.

1 Like