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.
@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]".
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.
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.
}
}
I think we found some other issues with our system that might be getting in the way of proper communication. Unclear as to cause as of now. Debugging required to get to bottom of things.
I'm experiencing your issue and have the same question. The void loop seems not mater what you put within it, will all run before the final "Connected to Arduino IoT Cloud" is recieved and thus is out of sequence.
I'm trying to trigger actions, that fix negative actions when the device reconnects to the cloud.
Great to hear I'm not alone in seeing this issue. We are no longer attempting to use this Arduino on our project because of a combination of issues with the Cloud and also weird communication issues with i2c devices. Will be interesting to hear if these cloud issues are resolved, however, in case in the future we want to use the Nano again.
Any luck with this. I’m having the same issue. I’m using a MKR 1500 and to limit data use I’m trying to use Millis in the loop but the Arduino continually reboots.
The continuous reboot when connected to Arduino IoT Cloud likely happens due to an update to the library which causes the board to reboot after ~16 seconds if the ArduinoCloud.update() function is not called. In short, you can either ensure that the function is called on time all the time, or you can disable the watchdog timer to disable the reboot.
Unfortunately, still hasn't been smooth sailing for me with the Arduino IoT Cloud. I'm using a MKR NB 1500 board and can't seem to keep stable connection for extended periods, per my latest question.
I now find if i set millis or delay for any longer than 10sec the mkr1500 wont reconnect with the cloud. Thus i cant remotely control the device via app or iot cloud.