How to make sure the Core runs my code even when the network is having problems?

Hello

My core is installed in a location with poor WiFi range (I’ve already ordered a new antenna) therefore sometimes it loses the WiFi connection and starts blinking green.

That is ok, but there are two problems:

  1. If it’s been blinking green for a while (hours) it won’t recover by itself, even after I restore the wifi signal, so I need to do a manual reset. I call that the green blinking of death.
  2. During that whole time, it won’t run my code.

My code needs to always be running, even when the network is offline / unreachable / poor range / whatever. A few seconds or even a minute of blinking green is acceptable, but after that it needs to timeout and get back to my code.

I see there are some very long threads on the topic, but they are quite old.

What is the current state of the art? What are the guidelines for making sure my code is always running? or at least never blocked for more than a few seconds or a minute.

What is the recommended SYSTEM_MODE to get reliability in the face of CC3000 or connectivity issues? Is there some example application code to achieve just that?

I mean, if I use semi-automatic or manual mode, will Spark.connect() timeout and get back to my code if it cannot connect to WiFi? Should I set up an interrupt to call Spark.disconnect() and make it do so? In semi-automatic mode, what happens when it loses WiFi? Does it try to connect again by itself, or does it wait for me to call connect() again?

I’ll make a few tests, but I’d like to get some info on the current state of things.

I’m using an old core from June 14, so I just performed all the updates (deep_update_2014_06 and flash --usb cc3000). In a few days I’ll know if that solves these issues. I’ve also ordered a couple of Photons. Are they more reliable in this regard?

I mean, the whole point of having an embedded controller is that it never fails. If it locks up and stops running user code, that’s quite a problem!

2 Likes

I have been using this:

SYSTEM_MODE(SEMI_AUTOMATIC);


uint8_t retry_count = 0;
unsigned long old_time = millis();

void setup(){
    WiFi.on();
}



void loop(){
     if(millis() - old_time >= 2000){
        if(retry_count < 10){
            if(!WiFi.ready()){
                WiFi.connect();
                retry_count++;

            }
            else if (!Spark.connected()){
                Spark.connect();
                retry_count++;
            }
        }
        else{
            WiFi.off();
            retry_count = 0;
            WiFi.on();
        }
        old_time = millis();
    }
    
    
    // Insert code here
} 

The photon hardware is definitely more robust and using the code above will automatically attempt to connect if Wifi disconnects

4 Likes

That looks nice. I’ll make sure to try it out and compare it to the stock functionality.

If you get really desperate, you can use System.reset() after a longer duration.

http://docs.particle.io/core/firmware/#system-system-reset

Do you need to access the web/cloud after your code starts running?
If you are only using the cloud to flash your script, then maybe the cloud access could be turned off ?

I do make use of the cloud for my complete functionality. But the basic operation only needs the RTC (which right now needs a connection to sync on startup, but on the Photon I’ll be able to keep synchronised between power outages with a supercap.)

I didn’t have a single lockup in 24 hours, since I applied the updates (deep_update_2014_06 and cc3000) so maybe it was just that. I did have an unexplained reset happening.

If you are talking about using Vbat, it is not a viable option yet. The particle team expects to have some software to work with it in a few weeks.

Is your concern about when the network is having problems, or when the power goes out, or both?

VBAT is certainly usable right now, if you have a Photon. As long as you feed the right power to it, It keeps the clock (RTC) synchronized even when the main power (VIN or 3V3) goes down.

What is coming in a few weeks is the ability to mark specific variables (in user code) so that they are allocated in the small part of SRAM that is kept alive with VBAT backup power, so that when the main power comes back on and the Photon reboots, those variables will have kept their value. But that’s not an essential feature: I’m using the simulated EEPROM to get permanent variable storage (with the union technique) and it’s working a treat.

As per the topic, my main concern is (was) with the Core going into green blinking mode and not calling loop() ever again, until I manually reset it. The deep and cc3000 updates seem to have solved it, or at least alleviated it. I’m keeping @kennethlimcp’s code in the backburner in case the issue is not completely solved, because it’s a nice summary of how to manually handle the connection status.

3 Likes

@tobia, I respectfully disagree about Vbat being usable today.
You ask “How to make sure the Core runs my code even when …”. Even if you have power to Vbat, your code will not run if 3v3 is down.

Once the Photon gets power back, it will not start with the last line of script, but will reset. When the Photon resets, I believe it will acquire the date/time from the cloud.

I don’t know your application, and Vbat may work well for you, but I don’t see it.
Thanks

This is not what VBAT does--it simply preserves some values in the processor. The processor does not run.

@blo, yes, we are in agreement with that.

maybe we should forget debating Vbat, and stick to the main topic. If so, I think it has been solved. Maybe this thread can be marked [SOLVED] if the OP feels it so.

1 Like