Was hoping by examining WiFiNINA.h that it would reveal what return code "3" represents. According to the library it references these conditions:
WL_CONNECTED: assigned when connected to a WiFi network;
WL_AP_CONNECTED : assigned when a device is connected in Access Point mode;
WL_AP_LISTENING : assigned when the listening for connections in Access Point mode;
WL_NO_SHIELD: assigned when no WiFi shield is present;
WL_NO_MODULE: assigned when the communication with an integrated WiFi module fails;
WL_IDLE_STATUS: it is a temporary status assigned when WiFi.begin() is called and remains active until the number of attempts expires (resulting in WL_CONNECT_FAILED) or a connection is established (resulting in WL_CONNECTED);
WL_NO_SSID_AVAIL: assigned when no SSID are available;
WL_SCAN_COMPLETED: assigned when the scan networks is completed;
WL_CONNECT_FAILED: assigned when the connection fails for all the attempts;
WL_CONNECTION_LOST: assigned when the connection is lost;
WL_DISCONNECTED: assigned when disconnected from a network;
The wifi radio is in a state that I believe has to reconnect with the AP (since it's failing simple wifi.ping() call). The result from running that function is just the number 3.
The reason why ping fails is that I'm forcing the router to block traffic from the board's IP address. It's a simple simulation test to check code logic.
When the board is unblocked pings continue to fail. This I believe is due to the router deregistering the board but I'd like to confirm that with the status code from WiFiNINA.h
In follow-up to this thread, I've noticed some strange behavior and wondered if others have seen similar issues with this board?
After uploading sketch to UNO WiFi Rev2 board it takes somewhere between 1-2 hours of runtime before the board throws ping failure errors (returning -1). It doesn't matter what target IP is specified, local wifi gateway, "www.google.com" or OpenDNS "1.1.1.1".
I know it's not my wireless network because during the same time frame there's another wireless device that is successfully pinging the same target, so I can safely say it's not the Wifi network or target end point.
Here's the code -- as it stands today.
/*
This example connects to a encrypted WiFi network (WPA/WPA2).
Then it prints the MAC address of the WiFi 101 Shield,
the IP address obtained, and other network details.
Then it continuously pings given host specified by IP Address or name.
Circuit:
WiFi 101 Shield attached / MKR1000 or embedded WiFi circuitry as found in UNO WiFi R2.
created 13 July 2010
by dlf (Metodo2 srl)
modified 09 June 2016
by Petar Georgiev
modified 04 April 2024
by Endreola
*/
#include <SPI.h>
#include <WiFiNINA.h>
#include <avr/wdt.h>
#include <utility/wifi_drv.h>
#include "arduino_secrets.h"
///////please enter your sensitive data in the Secret tab/arduino_secrets.h
char ssid[] = SECRET_SSID; // your network SSID (name)
char pass[] = SECRET_PASS; // your network password (use for WPA, or use as key for WEP)
int status = WL_IDLE_STATUS; // the WiFi radio's status
int i = 0; // the number of consecutive times ping failed
int relay = 13; // Tells Arduino the relay is connected to pin 13
int pingResult;
// Specify IP address or hostname
String hostName = "www.google.com";
//String hostName = "1.1.1.1";
void checkWiFi() {
status = WiFi.status();
Serial.println("Checking WiFi connection");
Serial.print("WiFi status = ");
Serial.println(status);
if (status != 3) {
// WiFiDrv::analogWrite(26, 32);
// Serial.println("Connecting to WiFi...");
connectWiFi();
}
}
void connectWiFi() {
status = WiFi.status();
while (status != WL_CONNECTED) {
Serial.print("Attempting to connect to WPA SSID: ");
Serial.println(ssid);
// Connect to WPA/WPA2 network:
status = WiFi.begin(ssid, pass);
// wait 5 seconds before connecting:
delay(5000);
}
// you're connected now, so print out the data:
// Serial.println("");
// Serial.println("You're connected to the network");
printCurrentNet();
printWiFiData();
Serial.print("WiFi Status = ");
Serial.println(status);
Serial.println();
}
void printCurrentNet() {
// print the SSID of the network you're attached to:
Serial.print("SSID: ");
Serial.println(WiFi.SSID());
// print the MAC address of the router you're attached to:
byte bssid[6];
WiFi.BSSID(bssid);
Serial.print("BSSID: ");
printMacAddress(bssid);
// print the received signal strength:
long rssi = WiFi.RSSI();
Serial.print("signal strength (RSSI): ");
Serial.println(rssi);
// print the encryption type:
byte encryption = WiFi.encryptionType();
Serial.print("Encryption Type: ");
Serial.println(encryption, HEX);
Serial.println();
}
void printMacAddress(byte mac[]) {
for (int i = 5; i >= 0; i--) {
if (mac[i] < 16) {
Serial.print("0");
}
Serial.print(mac[i], HEX);
if (i > 0) {
Serial.print(":");
}
}
Serial.println();
}
void printWiFiData() {
// print your WiFi 101 Shield's IP address:
IPAddress ip = WiFi.localIP();
Serial.print("IP address : ");
Serial.println(ip);
Serial.print("Subnet mask: ");
Serial.println((IPAddress)WiFi.subnetMask());
Serial.print("Gateway IP : ");
Serial.println((IPAddress)WiFi.gatewayIP());
// print your MAC address:
byte mac[6];
WiFi.macAddress(mac);
Serial.print("MAC address: ");
printMacAddress(mac);
}
void powerOnIoT() {
Serial.println("Powering ON IoT.");
digitalWrite(relay, HIGH); // Turn the relay on (HIGH is the voltage level = 1)
}
void powerCycleIoT() {
// WiFiDrv::analogWrite(27, 64);
Serial.println("Recycling power on IoT.");
digitalWrite(relay, LOW);
Serial.println("Pausing 30 seconds to allow device to properly reset.");
delay(30000); // delay 30 seconds before powering back on
digitalWrite(relay, HIGH);
Serial.println("Pausing 10 minutes for device to fully recover after a power recycle.");
delay(600000);
}
void reboot() {
Serial.print("Rebooting...");
wdt_disable();
wdt_enable(WDTO_15MS);
while (1) {}
}
void setup() {
WiFiDrv::pinMode(25, OUTPUT); //define GREEN LED
WiFiDrv::pinMode(26, OUTPUT); //define RED LED
WiFiDrv::pinMode(27, OUTPUT); //define BLUE LED
pinMode(relay, OUTPUT); // Initialize the Atmel GPIO pin as an output
// Initialize serial and wait for port to open:
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}
// check for the presence of the shield:
if (WiFi.status() == WL_NO_SHIELD) {
Serial.println("WiFi 101 Shield not present");
// don't continue:
while (true);
}
checkWiFi();
powerOnIoT();
}
void loop() {
WiFiDrv::analogWrite(25, 32);
pingResult = WiFi.ping(hostName);
WiFiDrv::analogWrite(25, 0);
if (pingResult >= 0) {
i = 0;
Serial.print("pinging ");
Serial.print(hostName);
Serial.print(", ");
Serial.print(pingResult);
Serial.println(" ms");
} else {
Serial.print("Ping failure, result = ");
Serial.println(pingResult);
printCurrentNet();
printWiFiData();
i++; // Keep track of the number of times ping failed
Serial.print("Looping ");
Serial.println(i);
checkWiFi();
}
// Serial.println("Pausing for 1 minute...");
delay(60000); // ping once a minute
if (i == 10) { // ping failed 10 times in a row, reboot router
powerCycleIoT();
reboot();
}
}
Appreciate your response.
Here's a couple of screenshots showing beginning and when the failures started:
Yup, defining it as "long int" certainly resolved that issue. Thank you and great catch!
But why? I thought IDE defines "int" as a 16-bit integer (2-bytes), for a select series of boards, including UNO. And since 'int' supports a fairly large range of signed & unsigned numbers; -32 768 to +32,767 who would of thought that isn't large enough to support ping() response?
Also, sample given for ping() in Arduino WiFiNINA::ping() library shows the var declared as 'int'. Is this a bug?
I do not know if this is a bug. How big is the value inside ping() before it is returned?
The "-1" in your ping made me think, "overflow" (counting past the "type" size). When using any value larger than I can count on my remaining fingers and toes, I use anything bigger than int... and if you use explicit values (42 for example) you probably need to "type" the value to the size of the thingy you want calculated (42UL for example for "unsigned long"). These two points are worth searching and reading, pertaining to Arduino.
610 was the last reported result (ref 2nd screenshot). Which is small enough to easily fit within a 2-byte variable. (The "ms" was appended to it for display purposes). Now, when ping() fails the result should reflect a value assigned to one of the cases below, which I would expect it to be a single digit number.
WL_PING_SUCCESS when the ping was successful
WL_PING_DEST_UNREACHABLE when the destination (IP or host is unreachable)
WL_PING_TIMEOUT when the ping times out
WL_PING_UNKNOWN_HOST when the host cannot be resolved via DNS
WL_PING_ERROR when an error occurs
EDIT: (tried to change text "1-byte" to "2-bytes" but the editing feature didnt reflect it.)