What is wrong with my code?

Greetings community,

I'm fairly new to Arduino coding so please have patience with me :slight_smile:
Been struggling to understand why ping() works for a short period of time then fails. It initially runs fine for an hour or two then pings returns -1.

My Wi-Fi runs fairly robust with having several dozen devices operating error free. So I doubt the issue is the Wi-Fi network.

The code includes a bunch of serial.print statements to help pinpoint where it's failing but to no alas. A conditional loop was added in the main loop() section to count the number of times it fails as a temporary solution. And after 10 attempts fail to re-establish a successful ping it forces the board to reboot. Not exactly the logic that I'm looking for but it does kick start the board back to an operational state for another hour or so.

The board is UNO Wifi Rev 2. Most of the code used was found online and some custom written. I had expanded the integers to 'long int' thinking maybe that was the issue, as is shown below.

I'd appreciate if you could look the code over, run it on same board, etc., and provide me some guidance what I'm doing wrong.

/*
  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)
long int status = WL_IDLE_STATUS;  // the WiFi radio's status
long int i = 0;                    // the number of consecutive times ping failed
long int n = 0;                    // number of times it cannot connect to wifi
long int relay = 13;               // Tells Arduino the relay is connected to pin 13
long int pingResult;
long int debug = 1;                // set debug = 0 to suppress Serial.print diagnostic messages

// Specify IP address or hostname
String hostName = "www.google.com";
//String hostName = "1.1.1.1";

void checkWiFi() {
  status = WiFi.status();
  if (debug) { 
    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) {
    if (debug) { 
      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);
    if (n >= 10) {
      powerCycleIoT();
    }
    n++;
  }
  
  // you're connected now, so print out the data:
  // Serial.println("");
  // Serial.println("You're connected to the network");
  printCurrentNet();
  printWiFiData();
  if (debug) { 
    Serial.print("WiFi Status = ");
    Serial.println(status);
    Serial.println();
  }
}

void printCurrentNet() {
  // print the SSID of the network you're attached to:
  if (debug) { 
    Serial.print("SSID: ");
    Serial.println(WiFi.SSID());
  }
  // print the MAC address of the router you're attached to:
  byte bssid[6];
  WiFi.BSSID(bssid);
  if (debug) { 
    Serial.print("BSSID: ");
  }
  printMacAddress(bssid);

  // print the received signal strength:
  long rssi = WiFi.RSSI();
  if (debug) {
    Serial.print("signal strength (RSSI): ");
    Serial.println(rssi);
  }
  // print the encryption type:
  byte encryption = WiFi.encryptionType();
  if (debug) {
    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) {
      if (debug) { Serial.print("0"); }
    }
    if (debug) { Serial.print(mac[i], HEX); }
    if (i > 0) {
      if (debug) { Serial.print(":"); }
    }
  }
  if (debug) { Serial.println(); }
}

void printWiFiData() {
  // print your WiFi 101 Shield's IP address:
  IPAddress ip = WiFi.localIP();
  if (debug) {
    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);
  if (debug) { Serial.print("MAC address: "); }
  printMacAddress(mac);
}

void powerOnIoT() {
  if (debug) { Serial.println("Powering ON IoT."); }
  digitalWrite(relay, HIGH);   // Turn the relay on (HIGH is the voltage level = 1)
}

void powerCycleIoT() {
  // WiFiDrv::analogWrite(27, 64);
  if (debug) { Serial.println("Recycling power on IoT."); }
  digitalWrite(relay, LOW);
  if (debug) { Serial.println("Pausing 30 seconds to allow device to properly settle down."); }
  delay(30000);
  digitalWrite(relay, HIGH);
  if (debug) { Serial.println("Pausing 10 minutes for device to fully recover after a power recycle."); }
  delay(600000);
  //Serial.println(">>>>>>>> uncomment the prior 2 lines");
  n = 0;
}

void reboot() {
  if (debug) { Serial.print("Rebooting..."); }
    wdt_enable(WDTO_2S);
    delay(500);
    wdt_reset();
  while (1) {}
}


void setup() {
  // 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
  }
  
  WiFiDrv::pinMode(25, OUTPUT); //define GREEN LED
  WiFiDrv::pinMode(26, OUTPUT); //define RED LED
  WiFiDrv::pinMode(27, OUTPUT); //define BLUE LED

//  wdt_enable(WDTO_4S);
  //wdt_enable(WDTO_2S);

  pinMode(relay, OUTPUT);      // Initialize the Atmel GPIO pin as an output
  powerOnIoT();
  
  if (debug) { Serial.println("starting setup routine"); }
  // check for the presence of the shield:
  if (WiFi.status() == WL_NO_SHIELD) {
    if (debug) { Serial.println("WiFi 101 Shield not present"); }
    // don't continue:
    while (true);
  }
  checkWiFi();
  
}

void loop() {
  WiFiDrv::analogWrite(25, 32);
  pingResult = WiFi.ping(hostName);
  WiFiDrv::analogWrite(25, 0);

  if (pingResult >= 0) {
    i = 0;
    if (debug) {
      Serial.print("pinging ");
      Serial.print(hostName);
      Serial.print(", ");
      Serial.print(pingResult);
      Serial.println(" ms");
    }
  } else {
    if (debug) { 
      Serial.print("Ping failure, result = ");
      Serial.println(pingResult);
    }

    printCurrentNet();
    printWiFiData();
    i++;                          // Keep track of the number of times ping failed
    
    if (debug) { 
      Serial.print("Looping "); 
      Serial.println(i);
    }
    checkWiFi();
  }
  // Serial.println("Pausing for 1 minute...");
  delay(60000);
  if (i == 10) {    // ping failed 10 times in a row, reboot router
    i = 0;
    powerCycleIoT();
    //setup();
    //loop();
    reboot();
  }
}

TIA

Suggestions:

  • Set baud rate to 115200. You may be experiencing serial message pileup with the low baud rate
  • String may or may not be giving you fits, if you constantly rebuild. Consider moving to classic c strings
  • I see pin actions - Doesn't sound like an application where a schematic would help us much, but is there one available showing wiring and power arrangements?
    Apologies, I don't know this particular device, so some or all of the above may not be very helpful.

The "dies at" problem pointing to overflow seems right. What do the Serial.prints say? Does it quit after the same printout?

Hello @xfpd, I suppose β€œdies” describes it fairly well. You may recall these screenshots from my other post. When ping returns -1 it loops for 10 times (to weed out possible false positives) but once it starts it continues to fail. IP settings look good and so does wifi connection. Am stumped why this is occurring.

I took the liberty to repost screenshots here as they may offer some assistance to those who read this post.

I came across another post on this forum who shared similar WiFi issues and resolved it by shorting the leads connected to digital header. Guess the connected device was generating "noise" causing issues with wifi radio. So am retesting the board again but this time without connecting the IoT Power Relay

The wires were twisted to help cancel out noise and they're not even 8" in length.

Hello @camsysca, Thank you for your response.

I can increase serial speed but since ping tests are performed once a minute, I doubt print statements is flooding the serial buffer queue with messages.

noted

No worries, glad to provide additional detail. The IoT Power Relay is the device and wiring is very basic, consisting of a ground wire and trigger wire.

Making some progress... :slight_smile:

looks like that IoT power relay device is the culprit. Ping worked fine for consecutive 7+ hours without receiving a single failure code. And it successfully continued to ping after blocking & enabling traffic at the router.

Next step is to contact Digital Loggers to understand what's going on. Will update the post with findings.

Looking for some clarification about SPI Library.

Pin 13 on the Uno Wi-Fi rev 2 board shows it's for Serial Clock. (The clock pulses which synchronize data transmission generated by the Controller and one line specific for every device.). Am not sure that I fully comprehend what that is describing, but it sounds like it shouldn't be messed with for this project.

Could this be the reason why the Wi-Fi radio seems to stop functioning over time? And if so, is there different general purpose pin that I should be using? Like any of the non-digital pins like A0-A5? I'm going to try A0 for starters, hopefully that will work...

EDIT: After learning more about the differences between Analog & Digital pins, I don't think using the Analog variant is what I need for this project. So please ignore that reference in the above paragraph.

Boards Default SPI Pins Additonal SPI Pins Notes
UNO R3, UNO R3 SMD, UNO WiFi Rev2, UNO Mini Ltd 10(CS), 11(COPI), 12(CIPO), 13(SCK) SPI pins available on ICSP header

On the Uno WiFi Rev2 the SCLK, MOSI and MISO signals are only available on the ICSP header.

Ah, OK. Thank you for the clarification.

What's interesting is that moving off pin 13 to pin 8 that the Wi-Fi radio has been running solid, error free. Am not sure why of the technical reason behind it but 13 was anything but lucky.

I appreciate everyone's guidance and support!

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