Wait for Arduino IoT cloud to finish connecting

I have some code in my project that shouldn't execute until we are completely connected to the IoT Cloud. How can I do this?

I want to do something like:

//the usual cloud startup stuff:
	initProperties();
	ArduinoCloud.begin(ArduinoIoTPreferredConnection);
	setDebugMessageLevel(2);
	ArduinoCloud.printDebugInfo();

//My added code:

//1) while not connected to cloud, wait.

//2) finally finish setup functions and start loop

What I find is that it might seem like things have started up but execution during the loop gets interrupted about the same time that I get a Serial message about "Connected to: [my wifi network]" This leads me to believe I need to wait for connections to be established that may be running on another thread somewhere.

I use below code in my void loop to trigger action when it's not connected to the cloud, you can do the opposite?

  if ((ArduinoCloud.connected() == 0)  {
    //Not connected do this
  } else {
    //connected do this
  }

@rumbaar Thanks. I tried this and some variations. I also disabled anything in setup that was unusual or not related to the cloud.

I tried a variation on your code:

//the usual cloud startup stuff:
	initProperties();
	ArduinoCloud.begin(ArduinoIoTPreferredConnection);
	setDebugMessageLevel(2);
	ArduinoCloud.printDebugInfo();

//My added code:
	while (ArduinoCloud.connected() == 0) 
	{
		Serial.println("Waiting for connection to Arduino IoT Cloud");
		delay(1000);
	}

What happens is that it keeps trying to connect for around 30 seconds, then setup aborts/restarts.

I tried another slightly dumber approach:

//the usual cloud startup stuff:
	initProperties();
	ArduinoCloud.begin(ArduinoIoTPreferredConnection);
	setDebugMessageLevel(2);
	ArduinoCloud.printDebugInfo();

//My added code:

	Serial.println("Waiting for connection to Arduino IoT Cloud");
	delay(60000);//wait until the cloud is connected.
	

In this case, it will wait for, again around 30 seconds before the whole setup starts over again.

Sort of scratching my head here on why setup() would just randomly abort...

I think it is able to connect to the cloud, because if I don't wait for the connection or put a delay in the setup function, it will eventually start streaming values to the cloud, sometime during the loop() function maybe a minute later. Also, around a minute into loop() I see a Serial message "connected to [network SSID]".

Update: regardless of where I put this in my code (setup or loop), after some time, the Arduino resets.

	while (ArduinoCloud.connected() == 0) 
	{
		Serial.println("Waiting for connection to Arduino IoT Cloud");
		delay(1000);
	}

could "delay()" interfere with the act of connecting to the cloud? or perhaps the .connected() function?

Yeah, so whatever I do, it seems like you can't do anything with the Arduino while it is connecting to the cloud because you might upset it.

The thing is the cloud connection functions are not blocking, and happen in the background.

That means that they just finish sometime later, most likely during loop...

But you can't do anything during loop that might await the connection. Even waiting for millis() to be greater than some time doesn't work. The Arduino just resets after some time.

And checking to see if the cloud is connected also seems to disturb the progress of connecting.

So...what is the right way to do things? This cannot be a unique problem.

Have you tried putting the code you want to run, only after it's connected, in the else section and within the void loop? Then it should only run after its fully connected.

Yes, I've tried this. It does the same thing. Executes for like 15-30 seconds while not connected, then crashes/resets. I did this using the default sketch generated by the Arduino Cloud IDE, nothing special except a list of cloud variables and a few lines of code as discussed above.

If you don't try to see if it's connected, it will connect on its own. But of course I need to know if it's connected.

Device: Arduino Nano 33 IoT, with latest firmware.

Some progress...

I got some of the above code to work if I insert ArduinoCloud.update() into the while loop:

	while (ArduinoCloud.connected() == 0) 
	{
		ArduinoCloud.update();//required so things don't crash on us
                Serial.println("Waiting for connection to Arduino IoT Cloud");
		delay(1000);
	}
       Serial.println("Connected to cloud");

What I find is that the Arduino connects to my wifi network. I get the message "Connected to [my network name]" and things seem ok.

But then 10 seconds or so later, while executing void loop() I get another error message:

ArduinoIoTCloudTCP::handle_ConnectMqttBroker could not connect to mqtts-sa.iot.arduino.cc:8883
ArduinoIoTCloudTCP::handle_ConnectMqttBroker 1 connection attempt at tick time 49031

Then, the Arduino continues doing the loop() function, and finally says it is connected on the 2nd try some seconds later.

What I'm finding, however is that these messages or events (whatever these interruptions are), are causing problems with execution of other things in my void loop(). My hypothesis is that the ArduinoCloud.update() function in void loop() is causing the hangup, but not sure.

Though documentation is almost no existent, I'm sure you need the ArduinoCloud.update() code in the base void loop to perform the 'regular' functionality of IoTCloud services.

What does your whole void loop code look like?

Also why doesn't something like this work?

void loop() {
  ArduinoCloud.update();
  if (ArduinoCloud.connected() == 0) {
    //not connected do nothing or whatever
  } else {
    //I'm now connected, put code here that should only run while connected.
  }
}