Sleep with RI_UC as wake up pin wakes up prematurely without cellular activity on electron US

Hi,
Using rickkas7’s post from a while back (which seems to be unresponsive now) I have been trying to implement sleep based on waking up with incoming cellular activity with the pin RI_UC, or after a time period of 850 seconds.
What I’m seeing is that the electron keeps waking up before the time period, due to rising edges of the RI_UC, even though there is no cellular activity to my knowledge. None shows in the console and I don’t initiate any.

Right after waking up, I publish the reason for waking up based on result.wakeupReason() . Since there’s no activity it should only wake up on ‘BY_RTC’ but instead I see a mix of that and BY_GPIO. I will attach a screen shot of the console showing these.

I’ve tried longer delays at the start of the loop, up to 2 minutes, to let any cellular activity settle out, with no difference.
Thanks for any ideas!

Here is my code:

SYSTEM_MODE(AUTOMATIC);

int ctr = 0;

void setup() 
{
   Serial.begin(9600);             // Enables printouts over the USB connector to a Putty or such on a PC
   // Enable wake on all URCs. This means E- wakes up from SLEEP_NETWORK_STANDBY on Ping, or Get (variable) or Run Tests, or even Flash
   Cellular.command("AT+URING=1\r\n");

   // Keep alives seem to help the problem of electrons not finding the cellular. Looks like only 122 bytes each.
   //Particle.keepAlive(5 * 60);    // send a ping every xx seconds
   Serial.printlnf("\n--------------Starting Loop---------------");
}

void loop() 
{
   delay(7000);
   Serial.printlnf("\nCtr = %d", ctr++);   
   String wakeupStrings[5] = {"UNKNOWN", "BY_GPIO", "BY_ADC", "BY_DAC", "BY_RTC"};
   Serial.printlnf("%d:%d:%d Going to sleep ...",Time.hour(), Time.minute(), Time.second());
   SystemSleepConfiguration config;
   config.mode(SystemSleepMode::STOP)
       .network(NETWORK_INTERFACE_CELLULAR)
       .flag(SystemSleepFlag::WAIT_CLOUD)
       .gpio(RI_UC, RISING)
       .duration(850s);
    SystemSleepResult result = System.sleep(config);
    delay(1000);
    Serial.printf("%d:%d:%d Wake reason is %d.",Time.hour(), Time.minute(), Time.second(), result.wakeupReason());
    Particle.publish("Wakeup reason is ", wakeupStrings[(int)result.wakeupReason()], PRIVATE);//String((double)result.wakeupReason()), PRIVATE);
}

Here is what I see in the console:

|Wakeup reason is|BY_RTC|E-Tracker3|5/8/20 at 5:30:17 pm|
|Wakeup reason is|BY_RTC|E-Tracker3|5/8/20 at 5:15:58 pm|
|Wakeup reason is|BY_RTC|E-Tracker3|5/8/20 at 5:01:40 pm|
|Wakeup reason is|BY_GPIO|E-Tracker3|5/8/20 at 4:47:19 pm|
|Wakeup reason is|BY_GPIO|E-Tracker3|5/8/20 at 4:46:55 pm|
|Wakeup reason is|BY_GPIO|E-Tracker3|5/8/20 at 4:46:40 pm|

There are a number of things that won’t show up in the console that could trigger a wake from the cloud side: function call, variable request, request for describe (current function/variable list). You should be able to go back to sleep in a few seconds in these cases, but if you go to sleep before the response goes out, it could be requested again, which would cause you to wake up again.

Thanks rickkas7. I’m making sure to not do any function or variable calls. Actually this version of code does not have any variables or functions. So I guess there will be request for describe or other ‘maintenance’ type work.

My main concern is that I need to take my hardware measurements (not shown in this test code but they currently run at the start of the loop in my real code) every 15 minutes, within a minute or so. As is if the electron wakes up early then the mesurements are taken early.

Would a good workaround be to put the sleep command in a loop that checks if 15 minutes have elapsed and keeps putting the device back to sleep if not, or is there a less brute force method?

Thanks!

Yes, that is what I would do.

I would wait for the RTC to be valid Time.isValid() and use the real time clock to keep track of when you should actually take a sample. This will solve two problems: unexpected wakeup because of cloud maintenance traffic, and also drifting over time.

If it’s not time to take a sample, maybe wait a second or two and go back to sleep.

Have you got Particle.subscribe() handlers and haven’t added the MY_DEVICES scope?
If so you may be receiving public events that won’t show up in your eventlog either.

ScruffR , no I don’t have any subscribes.

1 Like

Hi rickkas7, that worked well and so far I’m getting stable timing within a few seconds of 15 minutes. Thanks!

1 Like