Using the Uno R4 Wifi board in Arduino cloud my code has restarts if the cloud or WiFi ever drop out. This usually works but sometimes the R4 fails to connect back up to WiFi. The error message is this:
12:55:21.709 -> .Connection to "Name" failed
12:55:22.801 -> Retrying in "500" milliseconds
(Gave this message repeatedly for several days)
(pushed reset button here)
12:55:22.801 -> .Start...
12:55:27.654 -> WiFi.status(): 0
12:55:27.654 -> Current WiFi Firmware: 0.4.1
12:55:28.882 -> Connected to "Name"
All is once more OK.
Is there a library where I can insert another restart if I ever get that message as I have seen it fail to recover many times.
In other words if I ever see the message "Connection to "Name" failed" I just want to reboot. Is it possible?
Here is some not very pretty code. The issue is though failing to connect to Wifi on boot up occasionally...
#include "arduino_secrets.h"
/*
Sketch generated by the Arduino IoT Cloud Thing "Untitled"
Arduino IoT Cloud Variables description
The following variables are automatically generated and updated when changes are made to the Thing
String command;
float soilMoisture1;
int analog1;
int slider1;
bool bool1;
Variables which are marked as READ/WRITE in the Cloud Thing will also have functions
which are called when their values are changed from the Dashboard.
These functions are generated with the Thing and added at the end of this sketch.
*/
// Rev A1 20 July 2024 Basic cloud functions
#include "thingProperties.h"
#include "Arduino_LED_Matrix.h"
ArduinoLEDMatrix matrix;
#include "frames.h"
//---------------------------------------------------------------
void setup()
{
// 1. Serial
Serial.begin(9600);
delay(1500); // Wait for a Serial Monitor
Serial.println("Start...");
// 2. Cloud
initProperties(); // Defined in thingProperties.h
// The watchdog can be disabled by including the "false" argument as follows
// ArduinoCloud.begin(ArduinoIoTPreferredConnection, false);
// watchdog is disabled and will not carry out the function for which it was intended,
// namely a reset of the processor when there are long-term loss of comms to the cloud
ArduinoCloud.begin(ArduinoIoTPreferredConnection); // Connect to Arduino IoT Cloud
ArduinoCloud.update();
delay(1000);
while(ArduinoCloud.connected() == 0)
{
ArduinoCloud.update();
Serial.print(".");
delay(1000);
}
command = PropertyActions::CLEAR; // clear the command window to avoid a boot loop and so command only executes once // doesn't work sgc
Serial.println("\n***Cloud Connected 1***");
// More information related to the state of network and IoT Cloud connection and errors
// The higher number the more granular information you get.
// The default is 0 (only errors), Maximum is 4
setDebugMessageLevel(4); // 0..4, 0 is only errors
ArduinoCloud.printDebugInfo();
ArduinoCloud.addCallback(ArduinoIoTCloudEvent::DISCONNECT, doThisOnDisconnect); // reset if Cloud is disconnected
ArduinoCloud.addCallback(ArduinoIoTCloudEvent::CONNECT, doThisOnConnect);
// 3. Report RSSI
char msg[20] = "";
sprintf(msg, "RSSI=%idB", (int)WiFi.RSSI());
Serial.println(msg);
if( (int)WiFi.RSSI() < -65) // sgc Also check code to identify the correct AP
{
Serial.println("\n***RSSI too low 1! Restart!!!***\n\n");
// delay a little here to let network come back up? Try for the correct AP
matrix.loadFrame(danger);
NVIC_SystemReset();
}
// 4. Analog input for sensors
//analogReadResolution(14); // 10, 12, 14, default is 10 bit (0-1023) change to 14-bit resolution for analog voltage, int reading = analogRead(A3); // returns a value between 0-16383
// 5. LED Matrix on R4 board
// https://docs.arduino.cc/tutorials/uno-r4-wifi/led-matrix
matrix.begin(); // LED Matrix
//matrix.renderBitmap(arrow_up, 8, 12);
//matrix.loadFrame(stop);
// 6. Report to dashboard and debug serial
// doesn't work sgc
command = PropertyActions::CLEAR; // clear the command window to avoid a boot loop and so command only executes once
//command = "\x1b";
ArduinoCloud.update();
//ArduinoCloud.update();
//ArduinoCloud.update();
Serial.println("setup done!");
}
//---------------------------------------------------------------
void loop()
{
blinkLedNoDelay();
// delay(big number); // force a watchdog reset
if(WiFi.status() != WL_CONNECTED)
{
Serial.println("\n***WiFi not connected!!! Restart!!!***\n\n");
matrix.loadFrame(danger);
NVIC_SystemReset();
}
if( (int)WiFi.RSSI() < -65) // sgc Also check code to identify the correct AP
{
Serial.println("\n***RSSI too low 2! Restart!!!***\n\n");
matrix.loadFrame(danger);
NVIC_SystemReset();
}
ArduinoCloud.update();
if (ArduinoCloud.connected() == 0)
{
// Not connected
Serial.println("\n***Cloud not connected!!! Restart!!!***\n\n");
matrix.loadFrame(danger);
NVIC_SystemReset();
}
else
{
// Continue...
}
}
//---------------------------------------------------------------
// ArduinoCloud.addCallback(ArduinoIoTCloudEvent::DISCONNECT, doThisOnDisconnect);
// https://forum.arduino.cc/t/reset-by-software-arduino-r4/1154313/11
void doThisOnDisconnect()
{
Serial.println("***Cloud disconnect!!! Restart!!!***");
matrix.loadFrame(danger);
NVIC_SystemReset();
}
//---------------------------------------------------------------
void doThisOnConnect()
{
Serial.println("\n***Cloud Connected*** 2");
command = PropertyActions::CLEAR;
ArduinoCloud.update();
matrix.loadFrame(happy);
}
//---------------------------------------------------------------
void readMoisture(int sensor) // sensor 0 or 1 = A0 or A1
{
if(sensor == 0)
{
soilMoisture1 = ((float)analogRead(A3)/1023.0) * 5.0; // 0 to 1023, 5V ref
//Serial.println(moisture1);
//Serial.println(analogRead(A3));
}
// else
}
//---------------------------------------------------------------
// reference: https://www.baldengineer.com/arduino-how-do-you-reset-millis.html
void blinkLedNoDelay(void) // Blink the LED without using Delay in the main loop
{
static long now;
static const int period = 2000; // millisecs
static long lastChangeTime = 0;
// blink LED without delay in loop
now = millis();
//if(now > (lastChangeTime + period)) // Bug! Doesn't roll over correctly!
if((now - lastChangeTime) >= period) // ---FIXED---
{
if(digitalRead(LED_BUILTIN) == HIGH)
{
digitalWrite(LED_BUILTIN, LOW);
}
else
{
digitalWrite(LED_BUILTIN, HIGH);
}
lastChangeTime = now;
readMoisture(0);
}
}
//---------------------------------------------------------------
/*
Analog1 is READ_WRITE variable, onAnalog1Change() is
executed every time a new value is received from IoT Cloud.
*/
void onAnalog1Change()
{
// Add your code here to act upon Analog1 change
Serial.println("analog1 changed");
}
//---------------------------------------------------------------
/*
Bool1 is READ_WRITE variable, onBool1Change() is
executed every time a new value is received from IoT Cloud.
*/
void onBool1Change()
{
// Add your code here to act upon Bool1 change
Serial.println("bool1 changed");
Serial.print("bool1 = ");
Serial.println(bool1);
if(bool1)
{
matrix.loadFrame(arrow_right);
command = "LED ON\n";
}
else
{
matrix.loadFrame(stop); // draw some current to check for voltage sags
command = "LED OFF\n";
}
}
//---------------------------------------------------------------
/*
Since Command is READ_WRITE variable, onCommandChange() is
executed every time a new value is received from IoT Cloud.
*/
void onCommandChange()
{
// Add your code here to act upon Command change
//char cmd[250] = ""; // has to be big enough to contain everything in the command window (might be big!)
//strcpy(cmd, command.c_str()); // https://www.arduino.cc/reference/en/language/variables/data-types/string/functions/c_str/
Serial.print("Command received = ");
//Serial.println(cmd);
Serial.println(command.c_str());
//command = PropertyActions::CLEAR; // clear the command window to avoid a boot loop and so command only executes once
//if(!strcmp(cmd, "rst"))
//if(!strcmp(command.c_str(), "rst"))
if(command == "rst")
{
command = PropertyActions::CLEAR; // clear the command window to avoid a boot loop
ArduinoCloud.update();
Serial.println("Resetting");
delay(100);
NVIC_SystemReset();
}
if(!strcmp(command.c_str(), "clr"))
{
command = PropertyActions::CLEAR; // Clear the Message widget
}
if(!strcmp(command.c_str(), "read"))
{
//command = PropertyActions::CLEAR;
//ArduinoCloud.update(); // this seems to make the clear work
//delay(100);
int reading = analogRead(A3); // default 10 bits (0-1023), can be 10,12 or 14, default ref = 5V
char msg[20];
sprintf(msg, "A3 = %i", reading);
command = msg;
}
if(!strcmp(command.c_str(), "?"))
{
command = PropertyActions::CLEAR; // takes a while but one of these eventually clears the Message widget
ArduinoCloud.update();
command = ("Commands: \nclr = clear message widget\n read = read A3 voltage\n rst = reset (clear message to avoid boot loop!),\n ? = this help (clear message to avoid boot crashes!");
// ArduinoCloud.update();
// command = ("---");
//response = ("Commands: \nclr = clear message widget\n read = read A3 voltage\n rst = reset (clear message to avoid boot loop!),\n ? = this help (clear message to avoid boot crashes!");
//command = ("clr = clear message widget"); this doesn't work sgc
//command = ("rst = reset. Note! Manually clear window before reset!");
//command = ("help or ? = This help");
}
}
//---------------------------------------------------------------
/*
Since Slider1 is READ_WRITE variable, onSlider1Change() is
executed every time a new value is received from IoT Cloud.
*/
void onSlider1Change()
{
// Add your code here to act upon Slider1 change
analog1 = slider1; // echo slider value to the analog guage
Serial.print("slider1 = ");
Serial.println(slider1);
}
I added a reboot at the bottom of loop so that it runs loop once then restarts. Like this:
NVIC_SystemReset();
It rebooted and connected 246 times before it failed to connect. Here is the error:
First good connections:
15:08:33.655 -> Cloud Connected 1
...
16:10:26.010 -> Start...
16:10:26.154 -> WiFi.status(): 0
16:10:26.154 -> Current WiFi Firmware: 0.4.1
16:10:27.402 -> Connected to "Coyote"
16:10:27.402 -> ...
16:10:36.558 -> Cloud Connected 1
16:10:36.558 -> ***** Arduino IoT Cloud - configuration info *****
16:10:36.558 -> Device ID: c292e412-71a7-4263-9e39-e5f0eee9317b
16:10:36.605 -> MQTT Broker: iot.arduino.cc:8883
16:10:36.605 -> RSSI=-51dB
16:10:36.659 -> setup done!
Then:
16:10:38.879 -> Start...
16:10:39.012 -> WiFi.status(): 0
16:10:39.064 -> Current WiFi Firmware: 0.4.1
16:10:40.277 -> Connected to "Coyote"
16:10:40.277 -> .ArduinoIoTCloudTCP::handle_SyncTime could not get valid time. Retrying now.
16:10:42.403 -> ..ArduinoIoTCloudTCP::handle_SyncTime could not get valid time. Retrying now.
16:10:45.511 -> ..ArduinoIoTCloudTCP::handle_SyncTime could not get valid time. Retrying now.
16:10:48.618 -> ..ArduinoIoTCloudTCP::handle_SyncTime could not get valid time. Retrying now.
16:10:51.735 -> ...ArduinoIoTCloudTCP::handle_ConnectMqttBroker could not connect to iot.arduino.cc:8883 Error: -1
16:11:03.071 -> ...ArduinoIoTCloudTCP::handle_SyncTime could not get valid time. Retrying now.
16:11:07.177 -> ...ArduinoIoTCloudTCP::handle_ConnectMqttBroker could not connect to iot.arduino.cc:8883 Error: -1
16:11:18.080 -> .....ArduinoIoTCloudTCP::handle_SyncTime could not get valid time. Retrying now.
16:11:24.209 -> ...ArduinoIoTCloudTCP::handle_ConnectMqttBroker could not connect to iot.arduino.cc:8883 Error: -1
16:11:33.147 -> .........ArduinoIoTCloudTCP::handle_SyncTime could not get valid time. Retrying now.
16:11:43.265 -> ...ArduinoIoTCloudTCP::handle_ConnectMqttBroker could not connect to iot.arduino.cc:8883 Error: -1
16:11:54.139 -> .................ArduinoIoTCloudTCP::handle_SyncTime could not get valid time. Retrying now.
16:12:12.251 -> ...ArduinoIoTCloudTCP::handle_ConnectMqttBroker could not connect to iot.arduino.cc:8883 Error: -2
16:12:25.779 -> .Connection to "Coyote" lost.
16:12:26.866 -> Attempting reconnection
16:12:26.866 -> ..WiFi.status(): 0
16:12:28.934 -> Current WiFi Firmware: 99.99.99
16:12:28.934 -> .Connection to "Coyote" failed
16:12:30.017 -> Retrying in "500" milliseconds
16:12:30.017 -> .Connection to "Coyote" failed
16:12:31.133 -> Retrying in "500" milliseconds
16:12:31.133 -> .Connection to "Coyote" failed
Stuck here forever or until reset button or power cycle.
Notice that when it fails WiFi firmware version reports as:
Current WiFi Firmware: 99.99.99
Indicating that something is very corrupt in the boot process.
Thanks @agilardoni. Have these improvements been pushed back to the version I will find on the normal cloud website? That is, do I just re-compile to try this or do I need to do something else to get the branch with these fixes into my project?