WiFi.status() returns 3

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.

Serial.print(WiFi.status());

Appreciate any guidance to this issue.

In the WiFiNINA.h library... in wl_definitions.h WiFiNINA/src/utility/wl_definitions.h at master · arduino-libraries/WiFiNINA · GitHub

You should find definitions in /src directories.. that is where I look for "#include" files.

You will see... enum ... it has is own counting system...

typedef enum {
	WL_NO_SHIELD = 255,
        WL_NO_MODULE = WL_NO_SHIELD,
        WL_IDLE_STATUS = 0,
        WL_NO_SSID_AVAIL,
        WL_SCAN_COMPLETED,
        WL_CONNECTED,
        WL_CONNECT_FAILED,
        WL_CONNECTION_LOST,
        WL_DISCONNECTED,
        WL_AP_LISTENING,
        WL_AP_CONNECTED,
        WL_AP_FAILED
} wl_status_t;

This is how enum counts...

enum Foo { a, b, c = 10, d, e = 1, f, g = f + c };
//a = 0, b = 1, c = 10, d = 11, e = 1, f = 2, g = 12

Found here...
https://en.cppreference.com/w/cpp/language/enum

Thank you @xfpd for your response. It's a bit more complected than I expected and will require more studying.

Not really complicated.

I think that means 3 corresponds to WL_CONNECTED.

So maybe there is some other reason it is not responding to pings.

Hello @PaulRB, thank you for the response.

I would have to concur as that was my findings as well. The challenge is with correlating the other possible responses to a numeric value.

typedef enum {
	WL_NO_SHIELD = 255,
        WL_NO_MODULE = WL_NO_SHIELD,
        WL_IDLE_STATUS = 0,
        WL_NO_SSID_AVAIL,
        WL_SCAN_COMPLETED,
        WL_CONNECTED,
        WL_CONNECT_FAILED,
        WL_CONNECTION_LOST,
        WL_DISCONNECTED,
        WL_AP_LISTENING,
        WL_AP_CONNECTED,
        WL_AP_FAILED
} wl_status_t;

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:

What values are you expecting for pingResult? Try type long pingResult;

You can print the values; for you to complete the below if needed

typedef enum {
  WL_NO_SHIELD = 255,
  WL_NO_MODULE = WL_NO_SHIELD,
  WL_IDLE_STATUS = 0,
  WL_NO_SSID_AVAIL,
  WL_SCAN_COMPLETED,
  WL_CONNECTED,
  WL_CONNECT_FAILED,
  WL_CONNECTION_LOST,
  WL_DISCONNECTED,
  WL_AP_LISTENING,
  WL_AP_CONNECTED,
  WL_AP_FAILED
} wl_status_t;

void setup()
{
  Serial.begin(115200);
  Serial.print(F("WL_NO_SHIELD = ")); Serial.println(WL_NO_SHIELD);
  Serial.print(F("WL_NO_MODULE = ")); Serial.println(WL_NO_MODULE);
  Serial.print(F("WL_IDLE_STATUS = ")); Serial.println(WL_IDLE_STATUS);

  Serial.print(F("WL_CONNECTED = ")); Serial.println(WL_CONNECTED);
}

void loop()
{
}

And to prevent that you have to remember, you can use something like

typedef enum {
  WL_NO_SHIELD = 255,
  WL_NO_MODULE = WL_NO_SHIELD,
  WL_IDLE_STATUS = 0,
  WL_NO_SSID_AVAIL,
  WL_SCAN_COMPLETED,
  WL_CONNECTED,
  WL_CONNECT_FAILED,
  WL_CONNECTION_LOST,
  WL_DISCONNECTED,
  WL_AP_LISTENING,
  WL_AP_CONNECTED,
  WL_AP_FAILED
} wl_status_t;

wl_status_t status = WL_CONNECTION_LOST;

void setup()
{
  Serial.begin(115200);

  switch (status)
  {
    case WL_CONNECTION_LOST:
      Serial.println(F("Connection lost"));
      break;
    case WL_CONNECTED:
      Serial.println(F("Connected"));
      break;
    default:
      Serial.print(F("Other status"));
      Serial.println(status);
      break;
  }
}

void loop()
{
}

Hi @xfpd,

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?

Much appreciated!

@sterretje, thank for that info. It never dawned on me to just display them. And thank you for providing example code, much appreciated!

Yeay!

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.)

Sometimes something somewhere somehow might be slow. Usually leaving the topic and re-opening it again will show the change.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.