Electron looking for signal draining battery

Hi,
I use the following code on my Beehives. It has been running for over a year. It wakes up sends data to Blynk and sleeps for an hour.
If the scale can not connect to the cloud on a wake cycle it keeps trying until it either connects or the battery goes flat.
Sometimes the hives are in an intermittent area with occasional cell coverage. In these areas a reading may come through 6 days later. After that the battery is drained and game over. A drive of over 400km one way!
Code works fine for anyone looking.
I have read, tested, read tested… with watchdog, if else etc but I am missing some personal knowledge on how to implement them. ie Rickkas electron library, mayday watchdog etc.
Can anyone point me in the right direction of a software solution to add to my code?

#include <blynk.h>
#include <HX711ADC.h>

#define BLYNK_IP        IPAddress(45,55,130,102)
#define zero_factor 70427 //This large value is obtained using the SparkFun_HX711_Calibration sketch
#define battsoc V6
//SYSTEM_MODE(SEMI_AUTOMATIC);
//SYSTEM_THREAD(ENABLED);
BlynkTimer timer;
FuelGauge fuel;
HX711ADC scale(D2, D3);
char auth[] = "##############";
void setup()
{
   
    Blynk.begin(auth, BLYNK_IP);
    Serial.print("read: \t\t");
    Serial.println(scale.read());      // print a raw reading from the ADC
    Serial.print("read average: \t\t");
    Serial.println(scale.read_average(40));   // print the average of 20 readings from the ADC
    scale.set_scale(42690.f); 
    scale.set_offset(zero_factor); //Zero out the scale using a previously known zero_factor                                                                
    Serial.print("read: \t\t");
    Serial.println(scale.read());                 // print a raw reading from the ADC   
    Serial.println("Readings:");
    delay(10);
    Serial.print("one reading:\t");
    Serial.print(scale.get_units(), 2);
    Serial.print("\t| average:\t");
    Serial.println(scale.get_units(), 2);
    Blynk.virtualWrite(V5, scale.get_units());
    BLYNK_READ(battsoc);
    Blynk.virtualWrite(battsoc, fuel.getSoC());
    Blynk.run();
    delay(5000);
    System.sleep(SLEEP_MODE_DEEP, 60 * 60); 


}


void loop()
{
  
}

You should add SYSTEM_THREAD(ENABLED) and then keep control of the connection state and reconnection attempts.
As it seems you once had been using SEMI_AUTOMATIC mode and SYSTEM_THREAD(ENABLED) why did you opt against it?

You should also guard any network access (especially “black-box” calls like Blynk.xxx()) with a Cellular.ready() check to avoid interference of such calls with ongoing connection attempts.

Thank you for your reply.
I removed the SEMI_AUTOMATIC mode and SYSTEM_THREAD(ENABLED) to return my code to (my normal) after I had experimented with my trying to learn a solution.

So from your suggested way forward, I revisited the PARTICLE DOCS.
In AUTO mode it connects send data and sleeps.
DOCS say in SEMI AUTO only real difference is Particle.connect() needs to be added.
I added it to my code and it wakes and goes to sleep but no data sent to Blynk besides Blynk showing the connection was open before sleeping.
The DOCS say…
SYSTEM_THREAD(ENABLED) mode the setup and loop runs before particle is connected. Is this why my project shows online but with no updated values?
Is this the (especially “black-box” calls like Blynk.xxx() ) part of your reply?

Nope, that’s not the reason. The online indicator can only give you a guess of the state since the Electron uses UDP and a 23 minute keep alive periode. So once the device was seen online, the cloud wouldn’t know whether the device still is or has vanished until twice the keep alive periode has gone by without another sign of the device.

Yup, or any library I don’t necessarily want to know all the inner workings of.
One option is to trust that the implementation of such library features such safety precautions at the risk of falling flat on my face or I play it safe and do everything in my power to prevent that at the risk to waste some clock cycles for double-checking.

That’s only part of the truth.
With SEMI_AUTOMATIC mode you have more control of the connection process.
For example you can opt for a pure cellular connection (Cellular.connect()) without ever needing to connect to the Particle cloud (by not calling Particle.connect()).

AFAICT, Blynk doesn’t use the Particle cloud and as long your own code doesn’t either, you may save some power by not connecting to the cloud at all (or only once a day to sync the RTC).

e.g. even without SYSTEM_THREAD(ENABLED) this would help eleviate your issue outlined in the opening post

SYSTEM_MODE(SEMI_AUTOMATIC)

void setup() {
  Cellular.on();
  Cellular.connect();
  if (waitFor(Cellular.connected, 5*60*1000)) { // allow for 5 minutes to connect to the cell network
    // we now have a cell connection
    // do the stuff
  }
  else {
    // no connection could be established
    // take appropriate action
  }
  System.sleep(SLEEP_MODE_DEEP, 60 * 60); 
}
1 Like

Thanks for your time, I used your suggestion of SEMI_AUTOMATIC mode put in some particle.publish events, Particle.connect.
Also tried cellular.connect and worked as you said bypassing Particle and going direct to Blynk. I chose to stay within the Particle system for better debugging.
If I disconnect the Ariel to simulate no signal the electron tries for x time and sleeps for x time. It wakes and goes on doing its thing as intended. SOLVED.
Thanks once again!!!

1 Like