Guidelines to choose System Mode

As mentioned in device OS API link, there 3 system modes:

  1. Automatic Mode which effort of connecting, reconnecting is done automatically by the system. Only when connected then setup() and loop() would be called.
  2. Semi Automatic Mode which connecting to cloud is user responsibility but setup() and loop() are immediately called upon boot up.
  3. Manual mode where connection is entirely user responsibility.

I would like to hear your opinions, how would you decide to choose which mode?

That’s a very open question one could write books about as the decision is driven by the infinite count of possible use-cases :wink:

The main criterion is whether you want your code to run independently of connection state on startup.

An additional decision to be made along the selection of SYSTEM_MODE is whether to use SYSTEM_THREAD(ENABLED) or not.

If you need the cloud connection established at all times then AUTOMATIC all other cases need special attention in code and hence an understanding of the possible implications of each SYSTEM_MODE with or without SYSTEM_THREAD(ENABLED).

2 Likes

Very opened indeed @ScruffR, but made purposely to gather opinions :smile:.

In IoT application, I could not see why would user not wanting to ensure cloud connecting before the start of application. But maybe someone can share sample of use case? I just wonder why platform offer 3 options instead of just make it AUTOMATIC mode.

I could not see the connection between both clearly, care to elaborate? My understanding SYSTEM_THREAD() option is to decide whether the thread of application code would be on separate thread than the system? While system mode is mainly about whose responsibility to handle connection to cloud.

Hi @parhusip

Of course, getting opinions is always good, if you are lucky someone might just have a good idea :wink:

With regards to the statement above, I can provide you with a use case we had for this. We are monitoring current consumed by devices in a factory. We need ‘live’ results which in this case mean concurrent readings in as small instances as possible. To achieve this, we are taking 1000 readings per second, calculate an average and then save this data. The Data is then send in intervals to Google Cloud where it is later used to load balance production lines.

If for some reason the WiFi in the factory goes down, we still needs this data. In full Automatic mode, the devices would not be recording the data in the absence of cloud connection. In Semi-Automatic mode (or Manual) the data is recorded regardless of cloud status. Once connection has been established, data is then sent through.

Another case might be when using Cellular data in these type of devices. I am not sure of cellular costs around there world, but here we surely do not want a cellular device posting data every second :smiley: In this case we accumulate data for an hour and then post.

Last case I can think of is to conserve battery life when devices are powered by solar and Lipo. In semi-Automatic you can have your device do what it needs to so without having the have the cellular radio active, this way consuming a lot less energy. Every hour or so the radio can connect and you can send data.

Hope this helps :slight_smile:

Friedl.

4 Likes

Aha that make sense @friedl_1977, thank you!
Anyway, for your current monitoring, in case no connection the device still need to collect current reading without publishing it. So I believe you have to buffer it somewhere till connection ready again? You use any of memory persistency or just RAM?

I would like to hear more opinions from other audience, especially one that decided AUTOMATIC or MANUAL mode are sensible choice for their project.

1 Like

Correct

The ‘issue’ is that the application thread makes calls to system functions. When they succeed everything works fine whether SYSTEM_THREAD(ENABLED) or not. It is when they don’t that you need multi-thread and to test for application thread blocking calls before you make them. You also need a mechanism to buffer publishes so you can create an event in the application thread and not have to worry about whether you should have or not. This then makes the application thread cadence (loops/second) much more predictable.

I use SYSTEM_MODE(MANUAL) when testing functions that don’t need a cloud connection.

I use SYSTEM_MODE(AUTOMATIC) when testing functions that do need a cloud connection and where I am not worried about handling when there is no connection.

For everything else SEMI_AUTOMATIC - because it retries to connect once connected and because the manual turn on gives better control and understanding of WiFi environment without needing to get the WICED error codes.

3 Likes

Image an IoT fridge that would only start cooling after you got a connection or stopped as soon the connection was dropped :wink:

3 Likes

Hi @parhusip

Hhm… there might be some more clever opinions on this, but my view is always that it depends on whether or not the data collected is mission critical. If so, I would not mind writing to an ‘external EEPROM’ of some sort. It is easy enough to replace after you have used up the 1 000 000 odd re-writes allowed :slight_smile:

If not critical, I would probably store the data in RAM using a string or array, depends on how you want to publish the data once you connect to the cloud. I think both have advantages.

Regards,
Friedl.

1 Like

Hahaha, that is a good one, yeah my wife would not want to cook for me anymore :grin:

That’s right. Also what I can think of is to implement ring buffer in this case, just thinking out loud :smiley:

1 Like

Thanks @armor for the insight. So I take it that you are using SYSTEM_THREAD(ENABLED) in your project?

Ok now that I can understand why Semi-automatic and Manual modes could be a more sensible choice than Automatic, it is time to bring my concern about the handling when there is connection error.

In automatic mode as per API doc:

If the connection to the Cloud is ever lost, the device will automatically attempt to reconnect. This re-connection will block from a few milliseconds up to 8 seconds

I take it that platform guys have more understanding in handling connection lost and they do some testing to verify it (well hopefully :smile:). So this is very beneficial for user to leverage that knowledge.

However for Semi Auto and Manual are not clearly mention whose responsibility to handle reconnecting effort, someone can clarify? But it seems this would be on user side which might differ from how platform would handle it.

In my project, using electron, one a while the LTE connection is lost. It is using Semi-Automatic mode, and the device never manage to reconnect back to cellular/cloud till finally reset has to be done. This is despite the error handling by calling Cellular.on().

Maybe someone care to share how they handle their connection lost and successfully regain the connection?

I’d have to test MANUAL again, but IIRC when the connection is lost unexpectedly the device OS will attempt a reconnect in all cases. However, with SEMI_AUTOMATIC and MANUAL the application has better options to cancel an ongoing attempt when it deems in necessary (e.g. when WiFi or cell coverage are gone entirely).

there are scenarios where the application can put the device into a state where the connection cannot be reactivated either way - e.g. memory leaks or heap fragmentation may be the reason.

2 Likes

Hi @parhusip

As far as I know reconnecting will be your job, hehe. I do not have a lot of experience with Cellular devices, but assume the same applies.

As an example, I have this void connect(); function being run in void loop(); in one project, so checking and reconnecting is happening all there time. I am sure there are nicer ways of doing it, but this is what I could come up with up and it works :wink:

void connect() {                // Connect to Cloud initiated
    
     if(connectToCloud) {
        if(Particle.connected() == false) {  
             Particle.connect();
             connectToCloud = true; 
             Blynk.begin(auth);
        }
    }
}

Ok, so here its the way I approach matters, mainly because I believe in simplicity and also I am still working n drastically improving my C-skills :laughing:

  • First Automatic mode.
    If there is no reason for me to run void loop(); without being connected, this is the mode I go with.

  • Second, Semi-Automatic mode.
    This is 99% of the time what I use. It lets me run the entire code without being connected and the only additional thing I need to take care of, is connecting whenever I need to.

  • Manual Mode.
    There must be a VERY specific reason for me to consider this. Now I and not saying there is no place for this, but most certainly not at my level :slight_smile:

Now SYSTEM_THREAD(ENABLED) is great just keep it in mind from the go. I found it more difficult to implement after the fact. Again, I would make 100% I really need another thread before using this.

My 2 cents worth anyway… :slight_smile:

2 Likes

I use Particles for Escape Room puzzles. While many of these require the cloud because they are part of connected systems, some do not.

As I use a custom library framework for all my devices, I would use the semi-automatic mode. Moreover, due to some issues I have experienced with the cloud, I will likely be moving to UDP for my communication, so as to not have my room go offline if there are problems with the Particle Cloud.

On a somewhat related note, I build a delay loop into all my programming, so as to allow me to update them in the case I have a perpetual crashing bug. I feel that this should be built into the core OS. If the device detects N crashes, all in a short time from boot, the device should go into listening mode and wait for an update. This would save much pain. As you might well surmise, mine is the voice of experience in this type of misfortune. And it was a royal pain to manually force each device into listening mode.

1 Like

Thanks folks, I really enjoy this discussion.

So just to share my regression result for System Mode Automatic, I verified that in the event of cellular network lost, from the log, the system did put effort to reconnect in about ~ 36s (But this could vary case by case, need more data points). So in this case, the burden to maintain connection can indeed relieved from the user’s shoulder in Auto mode. Previously in Semi Auto mode, when disconnected, I tried to use Cellular.on() but it never successfully regain connection till system reset enforced.

In summary, while users can justify to use non Automatic mode, but should you choose Automatic mode, you have benefit to leverage system capability to perform re connection in the event of disconnection.

That may be due to the fact that Cellular.on() is not meant to initiate a connection :wink:
You’d need Cellular.connect() and/or Particle.connect() to do that.

2 Likes

I re-read the manual again, you are right, thanks for pointing that out :smiley:

I was not expecting turn on Cellular module not necessarily to connect to cellular.