Particle.connect() blocking main loop permanently, even with SYSTEM_THREAD(ENABLED)

I’m still a bit confused as what is said in this thread doesn’t seem to match the docs.

In the docs under System Threads / System Functions it says in SYSTEM_THREAD(ENABLED) mode only the following system functions block the caller:

  • WiFi.hasCredentials(), WiFi.setCredentials(), WiFi.clearCredentials()
  • Particle.function()
  • Particle.variable()
  • Particle.subscribe()
  • Particle.publish()

But the thread above talks about Particle.connect() blocking even with SYSTEM_THREAD(ENABLED). Can someone in the know be specific about under what circumstances (and if specific on what boards) Particle.connect() will not block.

Little late to the game but was hoping for a point of clarification - the docs seem to hint at it, as do most of the forum post, but I figured in case it was just asked differently and I or someone else just wasn’t asking the question the right way etc…

If both SYSTEM_MODE(SEMI_AUTOMATIC) and SYSTEM_THREAD(ENABLED) as in @ScruffR’s post awhile back with this bit of code:

SYSTEM_MODE(SEMI_AUTOMATIC)
SYSTEM_THREAD(ENABLED)
void setup()
{
  //pinMode(D7, OUTPUT); //Wasn't sure if that was here for a specific reason
  Particle.connect();
}
void loop()
{
  //do *stuff* - I simplified :)
}

Does the above mean that if WIFI & Internal nets are up but the interwebs are down, that whatever’s going on in the loop will keep on trucking till the webs come back up - and then automatically re-connect to the cloud?

Or should the code read more along the lines of:

SYSTEM_MODE(SEMI_AUTOMATIC)
SYSTEM_THREAD(ENABLED)

long timeout = 2000;
long timer = 0;

void setup()
{
  //pinMode(D7, OUTPUT); //Wasn't sure if that was here for a specific reason
  Particle.connect();
  timer = millis();
}
void loop()
{
  //do *stuff* - I simplified :)
  if(millis() - timer >= timeout)
  {
    //I might have got the timer wrong, but you know what I'm going for there
    Particle.connect();
  }
}

Or would both work, but the second one would just be redundant?

From what I gather, in this setup, ‘Particle.connect()’ would not block anything because of the threading mode and system mode(?)

FWIW, the docs, while fairly comprehensive, don’t always cover things in a one size fits all kind of way - I for example need to have 5 different people tell me the same thing before I realize I asked the wrong question :smiley:

I think ultimately the reason this line of questioning keeps coming up is that there’s (and maybe I’m off my rocker - I accept this) this perception that this platform is more plug and play than it really is (thats probably true of most things come to think of it…)

For a long time I just could not wrap my mind around a for loop, now I don’t understand why I had trouble with it… I think if I could understand what happened in between, it would open doors to figuring out how to meet people where there at so to speak.

I digress. a lot… thoughts on the more relevant bits?

First, once a connection has been established with SYSTEM_MODE(SEMI_AUTOMATIC) there is no difference between this and default SYSTEM_MODE(AUTOMATIC).
Consequently with your single Particle.connect() in setup() the behaviour of loop() is (supposed to be) exactly the same in both cases: The device OS will try its best to keep the connection stable and in case of a disconnect will try to reconnect.

However, sometimes the automatic reconnection scheme may not always fit your needs and hence you may opt for another layer of control over the connection in your application code.

This question has not got a single answer. It depends on what device OS version you are using.
There were versions where Particle.connect() (in SEMI_AUTOMATIC, SYSTEM_THREADING(ENABLED) mode) wasn't blocking at all, versions were it was mostly blocking and blocking under various conditions. I've lost track of how it behaves or how it should behave especially when the chosen path seems less intuitive and flexible than what was previously available.
Hence I've given up arguing, but always test the behaviour of the device OS version I want to target or opt for the most restrictive interpretation and build the code around that.
Having said that, I've found SYSTEM_MODE(MANUAL) plus SYSTEM_THREAD(ENABLED) to give me most flexibility and predictability of behaviour.

1 Like

Thanks @ScruffR for the insight - at the moment I’m on 0.8.0-rc.11 (I’m a glutton for punishment when it comes to the bleeding edge…), though from what it sounds like, I’m well past those versions in which it wasn’t blocking… even if I wasn’t though, I wouldn’t want to rely long term on a ‘feature’ resulting from a bug (been there, done that :stuck_out_tongue:)

Based on what I’ve read and what you’ve wrote, manual/threading should do what I want, though @rickkas7’s tutorial on it makes me a bit nervous… not that there’s a lot at stake - if it breaks, I build it again - and its not like auto prevents me from getting stuck in SOS mode either, I just hate spending a whole bunch of time learning something and coding something (as a relative novice) only to find out after it worked once and died that I missed a spot and can’t actually do said thing etc. etc. I suppose thats always a risk…

Ok ok, its less convenient to put something in DFU mode when it goes south. what can I say, I’m lazy like that :smiley:

Appreciate you taking the time!

1 Like