Keeping time when particle is not connected

I have a strange issue regarding device time when the particle photon is not connected to the cloud. we try to have the particle collect some data once a day, and store the data in the EEPROM, for a few days when the particle does not have cloud access. as soon as the particle is connected to the cloud, it will send out the data collected.

everything seems OK, except the time stamp is getting a negative number. For instance, the first day everything is good including the time stamp. the second day and so on, all data are good except the time stamp turned into negative numbers. these are the 4 recent time stamps: 1490621744, -2678259, -2678185, -2678220. the weird thing is, when we first tested the program, it did not have this issue. only recently we started to have this issue.

can someone shed some light into this?

Thanks in advance.

Sorry for not directly answering your question but in me project I decided to use the battery backed up RTC module. These modules are not very expensive, so maybe you can consider to go this way.

What datatype are you using for your timestamp?
It should be unsigned so it would never become negative.

2 Likes

we used int, but it should never overflowed.

by the way, we discovered that the battery went out between the measurements, not sure if that has anything to do with it?

@sean168, the int won’t overflow but when the MSb changes, the number will appear to be negative. Thus the need for an unsigned integer. Having the battery go out would absolutely play havoc on the time.

1 Like

Definetly.
To protect against that you can attach a coin cell battery to VBAT which will keep the RTC powered even if your main supply fails.

thanks for your response.

I figured out that the problem is deeper than what I originally thought.

for some reason the particle.connect seems to be different from before. now if there is no internet connection, photon will keep trying to make connection forever without running the loop(). is there a way to let the photon stop trying to make connection after trying for certain number of times?

the following code used to work, but no longer works:
connectionAttemp = 0;
Particle.connect();
while(!Particle.connected() && connectionAttemp<5)
{
SPARK_WLAN_Loop();
delay(100);
connectionAttemp++;
}

With default AUTOMATIC mode and without SYSTEM_THREAD(ENABLED) that has always been the case.

But SPARK_WLAN_Loop() has been replaced with Particle.process() and we now have dedicated functions waitUntil() / waitFor() for waiting till the connection gets established.

thanks for your quick response!

we were using Semi Automatic.

is there a way to stop trying to connection after certain number of attempts? or certain duration?

what we are seeing now is the system hangs everything else, if photon cannot make connection with particle.connect.

As mentioned SYSTEM_THREAD(ENABLED) makes sure your code will keep running during the connection attempts (with short blocking periods tho’, but not comming to a full stop).

If you have time critical tasks in your code, you may also want to consider using timed interrupts for these tasks via SparkIntervalTimer library.

BTW, if you can provide a simple code and description that illustrates the circumstances that cause the trouble we may be able to suggest code cures.

we have a need to basically put the photon to sleep to save battery power, but the photon will not progress to that, but rather keep on trying to make connection, and drain the battery power before going to sleep. how do we stop the connection attempt after a certain failed attempts?

this is essentially the code:

void loop() {
    
wakeTimer++;

if (wakeTimer==2) {
    connectionAttemp = 0;
    WiFi.on();
    Particle.connect();
    while(!Particle.connected() && connectionAttemp<5)
    {
        SPARK_WLAN_Loop();
        delay(100);
        connectionAttemp++;
    }
    
    if(Particle.connected()){ 
        Serial.begin(115200);
        sendStoredData();}
}

if (dataSendFlag==1) {
    if(Particle.connected()){
        sendData();}
    else {       
        storeData();
        dataSendFlag=0;
        wakeTimer = 0;
        WiFi.off();
        System.sleep(D0,FALLING);
        }}
else { measureData();
dataSendFlag = 1;}

if (wakeTimer>600) {
    wakeTimer = 0;
    WiFi.off();
    System.sleep(D0,FALLING);

}
delay(100);
}

basically waketimer controls when photon goes to sleep. every time photon is awaken, it takes measurements, then try to make connection with cloud. if it’s successful, it sends all the stored data, as well as new measurement. if it cannot make connection, then it will store data, which will be sent when next time it makes a successful connection.

I’d go along this line

SYSTEM_THREAD(ENABLED)
SYSTEM_MODE(SEMI_AUTOMATIC)

...
void loop() {
  ... 

  if (!timeToConnectAndSleep) return;

  for (int cnt=0; cnt < 5 && !Particle.connected(); cnt++) {
    Particle.connect();
    if(!waitFor(Particle.connected, 30000) && cnt >= 3) {
      // after four attempts not being able to connect
      WiFi.off();    // turn WiFi off and try once more with a cold start of the module
      delay(1000);
    }
  }
  if (Particle.connected()) {
    // do whatever needed when connected
  }
  else {
    // do whatever when not connectd
  }
  System.sleep(D0, FALLING);
}

In order to save power I’d always rather store the data first (in RAM) and only connect and send the collected data once just before going to sleep to keep the WiFi connection time as short as possible.
It also makes controling the connection much easier when you only do it in one place.

The problem with your code is that you only allow 500ms (5x 100ms) to connect each time and if your connection is not ready by then (which it won’t be in that short time) you knock the module back and start over again.

thanks for your help. I think we are on the right track. now I see the photon shuts off quickly. the problem is that it is shutting off too quickly, not even able to finish sending data or even making connection?

another problem is: how to flash the code now that it’s shutting down so quickly?

I think it’s working now. however, if there is no wifi, it took 2.5 minutes to go to sleep. I think this time somehow is related to waitFor(Particle.connected, 30000), because 5 times 30 seconds is about 2.5 minutes. Am I right?

can we shorten this time?

You should not cut the time any shorter than 30sec for one try, otherwise you may never be able to connect in poor reception cases - even 30sec is on the short side in such cases.
But you can easily go for less retries - the five came only from your own code. I’d actually only retry once with WiFi.off() in between.

@sean168, yes, you can shorten the time. I wouldn’t shorten the 30 seconds per attempt too much. You could cut it to 20 secs though I would stick with 30. You can also reduce the number of retries to 3 and turn wifi off after 2 tries:

  for (int cnt=0; cnt < 2 && !Particle.connected(); cnt++) {
    Particle.connect();
    if(!waitFor(Particle.connected, 30000) && cnt >= 2) {

The total time will now be reduced to 1.5 minutes.

1 Like

thanks again for your help.

now I am having some trouble flashing software.

I added the following line in the loop after the data is sent, hoping to use this time to do flashing if needed.

for (int i =0; i<600; i++) {
delay(100);}

however, it’s not able to flash the code.

am I wrong in doing so?

Since you will only be connected a few sec, it might be difficult to guess the correct time to initiate the OTA update.
Do you ever see the LED turn magenta?
The simplest way to OTA in such cases is to go with Safe Mode.

Otherwise you need to add some extra code that gets triggered on demand and keeps the connection open for 60sec after the OTA already kicked in.

I’d also do this kind of idle wait like this

  for(uint32_t _ms=millis(); millis() - _ms < 60000; Particle.process());
1 Like

wow, that was fast! Thanks for your answer, I will try that.

what does SYSTEM_THREAD(ENABLED) do?

I am suspecting that it is doing something to my data collection.