For a very, very long time I have been fighting with OTA. With the help of @rickkas7 and many others I have finally cracked the code and I thought I would share.
My devices spend a lot of time asleep. They are on a very strict power budget (solar) and so when they wake up I want them to publish exceedingly very quickly and then get back to sleep.
OTA has been a nightmare. Usually is simply doesn’t work. I’ve tried lots of tricks. Pretty much every trick that I have ever read documented here in the forum. What follows is my secret sauce. It is efficient (both power and bandwidth) and in extensive testing I have been able to reliably get OTA updates to every device once a day (you can use other strategies for kicking off the SystemReset function) .
I hope others can benefit from this approach and I welcome any suggestions or feedback.
#include "Particle.h"
PRODUCT_ID(Product_ID); //replace with yours
PRODUCT_VERSION(ProductVersion);
SYSTEM_MODE(MANUAL); // manual mode allows greater control and reduces message count
SYSTEM_THREAD(ENABLED);
int wake_rate = 30; // number of seconds to stay asleep
int day;
void SystemReset() {
System.sleep(SLEEP_MODE_DEEP, 5); //this mode forces a system restart when it wakes up
}
void setup()
{
Particle.connect();
while (!Particle.connected());
Particle.publish("New_session",PRIVATE); // this is the secret sauce.
// If you don't force a new session the OTA doesn't seem to kick in
Particle.publish("spark/device/session/end", "", PRIVATE);
Particle.connect();
while (!Particle.connected());
Particle.process();
while (System.updatesPending());
day = Time.day();
}
void loop()
{
Particle.publish ("I'm awake",PUBLIC);
System.sleep(D0, RISING, wake_rate, SLEEP_NETWORK_STANDBY);
//keeps cellular connected while asleep which allows for very short wake up cycle
Particle.connect();
while (!Particle.connected());
//do some stuff and publish events
if (Time.day() != day) SystemReset();
//forces a reboot every day...btw, I tried using millis()...that doesn't increment when you are sleeping
}