Boron Cellular Connection Management

I’m having trouble getting a boron to connect to the cloud. Being at the development stage, there is a need to reprogram and try a code change. I’ve been using USB to do this, and when the new version starts, it needs to reconnect. Typically that gets into a scenario where the boron has multiple blinks of green, then a white blink, and back to the green blinking, and so on repeatedly. I don’t have hard evidence, but powering off, waiting some number of hours and retrying sometimes gets it back to working. I’ve seen a few isses in the community forum describing a similar LED pattern. Then I saw this in the documentation about Cellular:

You must not turn off and on cellular more than every 10 minutes (6 times per hour). Your SIM can be blocked by your mobile carrier for aggressive reconnection if you reconnect to cellular very frequently. If you are manually managing the cellular connection in case of connection failures, you should wait at least 5 minutes before stopping the connection attempt. When retrying on failure, you should implement a back-off scheme waiting 5 minutes, 10 minutes, 15 minutes, 20 minutes, 30 minutes, then 60 minutes between retries. Repeated failures to connect can also result in your SIM being blocked.

How is this done in software? My initial setup does Cellular.on(), Cellular.connect(), followed by Particle.connect() - with some Serial.printlnfs after each of these so I can watch progress. However, during the looping failure scenario described above, I see no Serial output, so it seems like the code does not have an opportunity to count / manage connection attempts.

Another thing I observe is that, if a connection is dropped after being established in the main loop, then setup() is again called - I can see this from the Serial output. What!? That can wipe out variables holding important data. So does that imply that variable initialization should be done outside of Setup()?

Note the console shows that the cellular connection is weak, like as low as 21% in some cases.

When you are in default SYSTEM_MODE(AUTOMATIC) and also not using SYSTEM_THREAD(ENABLED) the device will always try to establish a cloud connection before your code is executed.

This would suggest that the connection is not just dropped but your code actually crashes and causes a reset (or is actually resetting/deep sleeping - which I’d assume you would be aware of :wink: )

If it’s important data you may want to consider string it in less volatile memory (i.e. as retained variables or in EEPROM).

I will try the suggestion to remove Cellular calls, though some checking of connectivity in the main loop could be helpful.

For instance, just now some application sensor data was obtained, then Particle.publish() was called - returning 1 (true) and reported via Serial. Yet the data was not published! The cloud console shows no event. What happened is that connectivity was lost somewhere in the publish event. Sure the boron did retry and establish a connection, but the publish() never went through. Also, so far as I can tell, the event of communication loss did trigger a restart (so setup was called again, though I doubt that should have any bearing on the validity of seeing via Serial that the publish() returned 1.

Maybe the default Particle.keepalive of 23 minutes should be set to a smaller value?

I guess this highlights your suggestion to save data in more persistent storage.

Here’s a question for you. Is is better to simply publish the same data multiple times, or publish once, then have some backend cloud process tell the boron that the data was successfully recorded? In the former case, the idea is that at least one of the copies will, with high probability actually be published; with the latter, there can be higher assurance though at higher complexity of operation/code.

Particle.publish() (when not used with WITH_ACK) will not report whether the event was successfully delivered but only whether the message was queued for sending successfully.