How to reset network connection if wifi fails?

I have a few BME280 weather stations in and around the house. My devices connect to the local wifi network and start a web server that my data collector server polls every few minutes to collect data into a database.

This runs very reliably until the device loses the wifi connection, for instance when the router is being rebooted. I have no clue about C programming and have just collected and combined a few code snippets to make it work.

However, I don't seem to be using the statement "if (WiFi.status() != WL_CONNECTED)" at the beginning of loop() correctly to jump back to the setup() function and re-establish the wifi connection in case it's gone.

Does anyone have a tipp? My code:

// INIT WIFI
#include <SPI.h>
#include <WiFiNINA.h>
#include "arduino_secrets.h" 
///////please enter your sensitive data in the Secret tab/arduino_secrets.h
char ssid[] = SECRET_SSID;
char pass[] = SECRET_PASS;
IPAddress ip(10, 10, 23, 46);
int status = WL_IDLE_STATUS;
WiFiServer server(80);


// INIT BME280
#include <Arduino.h>
#include <Wire.h>
#include <BMx280I2C.h>
#define I2C_ADDRESS 0x76
//create a BMx280I2C object using the I2C interface with I2C Address 0x76
BMx280I2C bmx280(I2C_ADDRESS);


void setup() {

  // SETUP WIFI AND WEB-SERVER
  
  // Assign fixed IP
  WiFi.config(ip);
  
  // check for the WiFi module:
  if (WiFi.status() == WL_NO_MODULE) {
    // don't continue
    while (true);
  }

  String fv = WiFi.firmwareVersion();

  // attempt to connect to WiFi network:
  while (status != WL_CONNECTED) {
    // Connect to WPA/WPA2 network. Change this line if using open or WEP network:
    status = WiFi.begin(ssid, pass);

    // wait 10 seconds for connection:
    delay(10000);
  }
  server.begin();

  // SETUP BME280
  Wire.begin();

  //begin() checks the Interface, reads the sensor ID (to differentiate between BMP280 and BME280)
  //and reads compensation parameters.
  if (!bmx280.begin())
  {
    while (1);
  }

  //reset sensor to default parameters.
  bmx280.resetToDefaults();

  //by default sensing is disabled and must be enabled by setting a non-zero
  //oversampling setting.
  //set an oversampling setting for pressure and temperature measurements. 
  bmx280.writeOversamplingPressure(BMx280MI::OSRS_P_x16);
  bmx280.writeOversamplingTemperature(BMx280MI::OSRS_T_x16);

  //if sensor is a BME280, set an oversampling setting for humidity measurements.
  if (bmx280.isBME280())
    bmx280.writeOversamplingHumidity(BMx280MI::OSRS_H_x16);
}


void loop() {

  // Reset connection if it disappears
  if (WiFi.status() != WL_CONNECTED)
  {
    setup();
  }
  
  // listen for incoming clients
  WiFiClient client = server.available();
  if (client) {
    // an HTTP request ends with a blank line
    boolean currentLineIsBlank = true;
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        // if you've gotten to the end of the line (received a newline
        // character) and the line is blank, the HTTP request has ended,
        // so you can send a reply
        if (c == '\n' && currentLineIsBlank) {
          // send a standard HTTP response header
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println("Connection: close");  // the connection will be closed after completion of the response
          client.println();

          // Output the measurement values
            delay(1000);

            //start a measurement
            if (!bmx280.measure())
            {
               return;
            }
          
            //wait for the measurement to finish
            do
            {
              delay(100);
            } while (!bmx280.hasValue());
          
            // Output BME280 Readings
            client.print(bmx280.getTemperature());
            client.print(";");
            client.print(bmx280.getPressure());
            client.print(";");
            client.print(bmx280.getHumidity());
            client.print(";");
            
            //Output voltage from A0
            int sensorReading = analogRead(0);
            client.print(sensorReading); 
            
          break;
        }
        if (c == '\n') {
          // you're starting a new line
          currentLineIsBlank = true;
        } else if (c != '\r') {
          // you've gotten a character on the current line
          currentLineIsBlank = false;
        }
      }
    }
    // give the web browser time to receive the data
    delay(1);

    // close the connection:
    client.stop();
  }

}

Calling setup is not advised....Put the code in setup in a separate function.

Something like this should work....

#include <SPI.h>
#include <WiFiNINA.h>
#include "arduino_secrets.h" 
///////please enter your sensitive data in the Secret tab/arduino_secrets.h
char ssid[] = SECRET_SSID;
char pass[] = SECRET_PASS;
IPAddress ip(10, 10, 23, 46);
int status = WL_IDLE_STATUS;
WiFiServer server(80);


// INIT BME280
#include <Arduino.h>
#include <Wire.h>
#include <BMx280I2C.h>
#define I2C_ADDRESS 0x76
//create a BMx280I2C object using the I2C interface with I2C Address 0x76
BMx280I2C bmx280(I2C_ADDRESS);


void setup() {

  // SETUP WIFI AND WEB-SERVER
  setup_WIFI();

  // SETUP BME280
  Wire.begin();

  //begin() checks the Interface, reads the sensor ID (to differentiate between BMP280 and BME280)
  //and reads compensation parameters.
  if (!bmx280.begin())
  {
    while (1);
  }

  //reset sensor to default parameters.
  bmx280.resetToDefaults();

  //by default sensing is disabled and must be enabled by setting a non-zero
  //oversampling setting.
  //set an oversampling setting for pressure and temperature measurements. 
  bmx280.writeOversamplingPressure(BMx280MI::OSRS_P_x16);
  bmx280.writeOversamplingTemperature(BMx280MI::OSRS_T_x16);

  //if sensor is a BME280, set an oversampling setting for humidity measurements.
  if (bmx280.isBME280())
    bmx280.writeOversamplingHumidity(BMx280MI::OSRS_H_x16);
}


void loop() {

  // Reset connection if it disappears
  if (WiFi.status() != WL_CONNECTED)
  {
    setup_WIFI();
  }
  
  // listen for incoming clients
  WiFiClient client = server.available();
  if (client) {
    // an HTTP request ends with a blank line
    boolean currentLineIsBlank = true;
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        // if you've gotten to the end of the line (received a newline
        // character) and the line is blank, the HTTP request has ended,
        // so you can send a reply
        if (c == '\n' && currentLineIsBlank) {
          // send a standard HTTP response header
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println("Connection: close");  // the connection will be closed after completion of the response
          client.println();

          // Output the measurement values
            delay(1000);

            //start a measurement
            if (!bmx280.measure())
            {
               return;
            }
          
            //wait for the measurement to finish
            do
            {
              delay(100);
            } while (!bmx280.hasValue());
          
            // Output BME280 Readings
            client.print(bmx280.getTemperature());
            client.print(";");
            client.print(bmx280.getPressure());
            client.print(";");
            client.print(bmx280.getHumidity());
            client.print(";");
            
            //Output voltage from A0
            int sensorReading = analogRead(0);
            client.print(sensorReading); 
            
          break;
        }
        if (c == '\n') {
          // you're starting a new line
          currentLineIsBlank = true;
        } else if (c != '\r') {
          // you've gotten a character on the current line
          currentLineIsBlank = false;
        }
      }
    }
    // give the web browser time to receive the data
    delay(1);

    // close the connection:
    client.stop();
  }

}

void setup_WIFI() {
// SETUP WIFI AND WEB-SERVER
  
  // Assign fixed IP
  WiFi.config(ip);
  
  // check for the WiFi module:
  if (WiFi.status() == WL_NO_MODULE) {
    // don't continue
    while (true);
  }

  String fv = WiFi.firmwareVersion();

  // attempt to connect to WiFi network:
  while (status != WL_CONNECTED) {
    // Connect to WPA/WPA2 network. Change this line if using open or WEP network:
    status = WiFi.begin(ssid, pass);

    // wait 10 seconds for connection:
    delay(10000);
  }
  server.begin();
}
2 Likes

Thanks a lot! I understand and yes, it looks cleaner. Unfortunately the connection still is not being restored though. Is the location at the beginning of the loop() function correct? Does this get executed even if no client has polled the web server data? Or should I put it within the while loop? Or maybe my if statement itself is buggy?

You can test it in the while loop....It probably is a good idea to locate it there.

Still no success. Do you happen to know whether the statement "WiFi.status() != WL_CONNECTED" will ever be true if the wifi network disappears?

Change this to, does it work then?

// check for the WiFi module:
  if (WiFi.status() == WL_NO_MODULE) {
    // don't continue
    //while (true);
  }

No success. I check this out and tried connection lost and that too fails. I think I will play around with those some more and put them in different places. Thanks a lot for your help!

i'm guessing you mean the connections to the router or some device also associated with the wifi router

should only need to set credentials once, then wait for them to be accepted

  while (status != WL_CONNECTED) {
    delay(1000);       // just 1 sec
    Serial.print (".");
  }
  Serial.println ("\nconnected\n");
1 Like

Success! @gcjr your comment got me to rethink the order in which things are happening. Thanks for the mental floss! I do indeed have to put WiFi.begin() into the loop as otherwise it won't work if the wifi downtime is too long. Also, server.begin() (starting the web server) had to go to setup() as that may only be used once, otherwise something blocks the web server.

So now I'm testing long term but so far it's looking good. Code below for reference. Thanks everyone for your time and help!

#include <SPI.h>
#include <WiFiNINA.h>
#include "arduino_secrets.h" 
///////please enter your sensitive data in the Secret tab/arduino_secrets.h
char ssid[] = SECRET_SSID;
char pass[] = SECRET_PASS;
IPAddress ip(10, 10, 23, 46);
int status = WL_IDLE_STATUS;
WiFiServer server(80);


// INIT BME280
#include <Arduino.h>
#include <Wire.h>
#include <BMx280I2C.h>
#define I2C_ADDRESS 0x76
//create a BMx280I2C object using the I2C interface with I2C Address 0x76
BMx280I2C bmx280(I2C_ADDRESS);


void setup() {

  // SETUP BME280
  Wire.begin();

  //begin() checks the Interface, reads the sensor ID (to differentiate between BMP280 and BME280)
  //and reads compensation parameters.
  if (!bmx280.begin())
  {
    while (1);
  }

  //reset sensor to default parameters.
  bmx280.resetToDefaults();

  //by default sensing is disabled and must be enabled by setting a non-zero
  //oversampling setting.
  //set an oversampling setting for pressure and temperature measurements. 
  bmx280.writeOversamplingPressure(BMx280MI::OSRS_P_x16);
  bmx280.writeOversamplingTemperature(BMx280MI::OSRS_T_x16);

  //if sensor is a BME280, set an oversampling setting for humidity measurements.
  if (bmx280.isBME280())
    bmx280.writeOversamplingHumidity(BMx280MI::OSRS_H_x16);

  setup_WIFI();
  server.begin();

}


void loop() {

  // Reset connection if it disappears
  if (WiFi.status() != WL_CONNECTED)
  {
    setup_WIFI();
  }

  // listen for incoming clients
  WiFiClient client = server.available();
  if (client) {
    // an HTTP request ends with a blank line
    boolean currentLineIsBlank = true;
    while (client.connected()) {

      if (client.available()) {
        char c = client.read();
        // if you've gotten to the end of the line (received a newline
        // character) and the line is blank, the HTTP request has ended,
        // so you can send a reply
        if (c == '\n' && currentLineIsBlank) {
          // send a standard HTTP response header
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println("Connection: close");  // the connection will be closed after completion of the response
          client.println();

          // Output the measurement values
            delay(1000);

            //start a measurement
            if (!bmx280.measure())
            {
               return;
            }
          
            //wait for the measurement to finish
            do
            {
              delay(100);
            } while (!bmx280.hasValue());
          
            // Output BME280 Readings
            client.print(bmx280.getTemperature());
            client.print(";");
            client.print(bmx280.getPressure());
            client.print(";");
            client.print(bmx280.getHumidity());
            client.print(";");
            
            //Output voltage from A0
            int sensorReading = analogRead(0);
            client.print(sensorReading); 
            
          break;
        }
        if (c == '\n') {
          // you're starting a new line
          currentLineIsBlank = true;
        } else if (c != '\r') {
          // you've gotten a character on the current line
          currentLineIsBlank = false;
        }
      }
    }
    // give the web browser time to receive the data
    delay(1);

    // close the connection:
    client.stop();
  }

}

void setup_WIFI() {

  // Assign fixed IP
  WiFi.config(ip);
  
  // check for the WiFi module:
  if (WiFi.status() == WL_NO_MODULE) {
    // don't continue
    while (true);
  }

  // String fv = WiFi.firmwareVersion();

  while (WiFi.status() != WL_CONNECTED)
  {

    WiFi.begin(ssid, pass);
    delay(5000);
 
  }

}
1 Like

It's a pleasure to help you. :blush:

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