How to perform timed repetitive tasks

I would like to start a task in the firmware every X minutes and then let the imp in deep sleep, but I cannot figure out a consistent way to do this. I am including the pseudo-code below. Depending by the time elapsed to perform OWTest() the delay between two runs changes. It looks like server.sleepuntil() could be of help.

OWTest() {
// do things


}

server.log(“start”);
OWTest();
server.log(“end”);
server.sleepfor(2 * 60);

Yep, server.sleepuntil() works on UTC time; you can just read the time at boot, add 120 seconds, then sleep again (or, indeed, synchronize to a particular schedule like 15 minutes past the hour).

Note that right now, you should always be calling server.sleepfor/sleepuntil from a callback rather than your main code as it can block firmware upgrades from being processed. The next release will contain the fix for this, but for now do:

function onidle() {
server.sleepfor(2*60);
}

imp.wakeup(0.1, onidle);

…the next release adds a specific “onidle” handler.

Doing what you suggest would not just run onidle() every 120 seconds but restart the firmware altogether.

This is correct, and intentional. The point is to let the event handler process any received events from the server before the server.sleepfor() call is executed.

Event processing does not happen in the background in order that user firmware runs predictably.

To answer your question concretely:

server.sleepfor(120 - (time() % 120));

Wakes up every 2 minutes, on the 2 minutes.

Peter

Very elegant and DRY. Thank you.