[ESP32] Ways to improve on the code for a GET request

Hello there! I made this code for my ESP32 and I'm wondering if there is anything I need to improve here. I just added WiFi login in a separate file and added "wifiRestart".

Is it possible to add more fail safe strings of code, like a timer on the GET request? My micro controller sometimes get stuck and I don't know where in the code! I suppose it is when trying to connect to server to post data via a GET request. Maybe I need a timeout and retry in the HTTP request?

Also the code I tried adding for "wifiRestart" looks like the function is not the correct text color (it is black plain text)? Edit: I see in the code for this forum post that the colors are correct, but in my Arduino IDE it is not.

Could it be that I run out of memory while trying to post if it takes a very long time?

#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>
#include <WiFi.h>
#include <HTTPClient.h>
#include <credentials.h>

#define SEALEVELPRESSURE_HPA (1013.25)

Adafruit_BME280 bme; // I2C

const char ssid[] = WIFI_SSID;
const char password[] = WIFI_PASSWD;

//Your Domain name with URL path or IP address with path
String serverName = "https://www.mysite.com/write_data.php";

// the following variables are unsigned longs because the time, measured in
// milliseconds, will quickly become a bigger number than can be stored in an int.
unsigned long lastTime = 0;
unsigned long timerDelay = 60000;

void setup() {
    unsigned short count = 0;
    Wire.begin();
    Serial.begin(115200);
    while(!Serial);    // time to get serial running
    Serial.println(F("BME280 test"));

    unsigned status;
    
    // default settings
    status = bme.begin(0x76);  
    // You can also pass in a Wire library object like &Wire2
    //status = bme.begin(0x76, &Wire2)
    if (!status) {
        Serial.println("Could not find a valid BME280 sensor, check wiring, address, sensor ID!");
        Serial.print("SensorID was: 0x"); Serial.println(bme.sensorID(),16);
        Serial.print("        ID of 0xFF probably means a bad address, a BMP 180 or BMP 085\n");
        Serial.print("   ID of 0x56-0x58 represents a BMP 280,\n");
        Serial.print("        ID of 0x60 represents a BME 280.\n");
        Serial.print("        ID of 0x61 represents a BME 680.\n");
        while (1) delay(10);
    }
    
    Serial.println("-- Default Test --");

  WiFi.begin(ssid, password);
  Serial.println("Connecting");
  while(WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
    count++;

    if (count >= 30)
      wifiRestart();
  }
  Serial.println("");
  Serial.print("Connected to WiFi network with IP Address: ");
  Serial.println(WiFi.localIP());
 
  Serial.println("Timer set to 1 minute (timerDelay variable), it will take 1 minute before publishing the first reading.");
}

void wifiRestart() {
  Serial.println("Turning WiFi off...");
  WiFi.mode(WIFI_OFF);
  Serial.println("Sleepping for 10 seconds...");
  delay(10000);
  Serial.println("Trying to connect to WiFi...");
  WiFi.mode(WIFI_STA);
}

void loop() {
  //Send an HTTP POST request every 10 minutes
  if ((millis() - lastTime) > timerDelay) {
    //Check WiFi connection status
    if(WiFi.status()== WL_CONNECTED){
      HTTPClient http;

      String serverPath = serverName + "?temp=" + bme.readTemperature() + "&humi=" + bme.readHumidity() + "&pres=" + (bme.readPressure() / 100.0F) + "&rssi=" + WiFi.RSSI();
      
      // Your Domain name with URL path or IP address with path
      http.begin(serverPath.c_str());
      
      // Send HTTP GET request
      int httpResponseCode = http.GET();
      
      if (httpResponseCode>0) {
        Serial.print("HTTP Response code: ");
        Serial.println(httpResponseCode);
        String payload = http.getString();
        Serial.println(payload);
      }
      else {
        Serial.print("Error code: ");
        Serial.println(httpResponseCode);
      }
      // Free resources
      http.end();
      printValues();
    }
    else {
      Serial.println("WiFi Disconnected");
      wifiRestart();
    }
    lastTime = millis();
  }
}

void printValues() {
    Serial.print("Temperature = ");
    Serial.print(bme.readTemperature());
    Serial.println(" *C");

    Serial.print("Pressure = ");
    Serial.print(bme.readPressure() / 100.0F);
    Serial.println(" hPa");

    Serial.print("Approx. Altitude = ");
    Serial.print(bme.readAltitude(SEALEVELPRESSURE_HPA));
    Serial.println(" m");

    Serial.print("Humidity = ");
    Serial.print(bme.readHumidity());
    Serial.println(" %");

    Serial.print("Signal strength (RSSI) = ");
    Serial.print(WiFi.RSSI());
    Serial.println(" dBm");

    Serial.println();
}

A comment on WiFi restart. If WiFi is found to be disconnected WiFi restart stops and starts the WIFi but does it reconnect?

Best to issue a WiFi.disconnect() before a WiFI connect. The WIFi.disconnect() resets the WiFi stack, the main reason WiFi fracks up.

So should that be this instead? I want something as stable as possible.

void wifiRestart() {
  Serial.println("Turning WiFi off...");
  WiFi.disconnect()
  Serial.println("Sleepping for 10 seconds...");
  delay(10000);
  Serial.println("Trying to connect to WiFi...");
  WiFi.connect()
}

I use this function to connect to WiFi on an esp32.

void connectToWiFi()
{
  int TryCount = 0;
  while ( WiFi.status() != WL_CONNECTED )
  {
    TryCount++;
    WiFi.disconnect();
    WiFi.begin( SSID, PASSWORD );
    vTaskDelay( 4000 );
    if ( TryCount == 10 )
    {
      ESP.restart();
    }
  }
  WiFi.onEvent( WiFiEvent );
}

Any more hints on how to improve the code? Like adding a timeout and retry on the HTTP request?

This was actually my issue (after some research)! The WiFi Disconnected.
So it will be fixed when I improve and upload your suggestion, thank you Idahowalker!

I'm still wondering if there is anything else that I can change to improve on the code!
I guess if I'm not getting anything from the site, I can remove the:

String payload = http.getString();
Serial.println(payload);

?

Edit: And what does "WiFi.onEvent( WiFiEvent );" do?

My current code (hope it looks good?), added WiFi failed count and some minor tweaks:

#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>
#include <WiFi.h>
#include <HTTPClient.h>
#include <credentials.h>

#define SEALEVELPRESSURE_HPA (1013.25)

Adafruit_BME280 bme; // I2C

const char ssid[] = WIFI_SSID;
const char password[] = WIFI_PASSWD;

//Your Domain name with URL path or IP address with path
String serverName = "https://www.mysite.com/write_data.php";

// the following variables are unsigned longs because the time, measured in
// milliseconds, will quickly become a bigger number than can be stored in an int.
unsigned long lastTime = 0;
unsigned long timerDelay = 60000;
unsigned short wifiFail = 0;

void setup() {
    unsigned short count = 0;
    Wire.begin();
    Serial.begin(115200);
    while(!Serial);    // time to get serial running
    Serial.println(F("BME280 test"));
    
    unsigned status;
    
    // default settings
    status = bme.begin(0x76);  
    // You can also pass in a Wire library object like &Wire2
    //status = bme.begin(0x76, &Wire2)
    if (!status) {
        Serial.println("Could not find a valid BME280 sensor, check wiring, address, sensor ID!");
        Serial.print("SensorID was: 0x"); Serial.println(bme.sensorID(),16);
        Serial.print("        ID of 0xFF probably means a bad address, a BMP 180 or BMP 085\n");
        Serial.print("   ID of 0x56-0x58 represents a BMP 280,\n");
        Serial.print("        ID of 0x60 represents a BME 280.\n");
        Serial.print("        ID of 0x61 represents a BME 680.\n");
        while (1) delay(10);
    }
    
    Serial.println("BME280 Test Complete");
    
    WiFi.begin(ssid, password);
    Serial.println("Connecting");
    while(WiFi.status() != WL_CONNECTED) {
        delay(500);
        Serial.print(".");
        count++;
        
        if (count >= 30)
        wifiRestart();
    }
    Serial.println("");
    Serial.print("Connected to WiFi network with IP Address: ");
    Serial.println(WiFi.localIP());
    
    Serial.println("Timer set to 1 minute (timerDelay variable), it will take 1 minute before publishing the first reading.");
}

void wifiRestart() {
    int tryCount = 0;
    while(WiFi.status() != WL_CONNECTED) {
        tryCount++;
        wifiFail++;
        WiFi.disconnect();
        WiFi.begin(ssid, password);
        vTaskDelay(4000);
        if(tryCount >= 10) {
            ESP.restart();
        }
    }
}

void runClear() {
    if(wifiFail >= 20000) {
        wifiFail = 0;
        Serial.println("Too many fails, counter reset");
    }
}

void loop() {
    //Send an HTTP POST request every 10 minutes
    if((millis() - lastTime) > timerDelay) {
        //Check WiFi connection status
        if(WiFi.status() == WL_CONNECTED) {
            HTTPClient http;
            
            String serverPath = serverName + "?temp=" + bme.readTemperature() + "&humi=" + bme.readHumidity() + "&pres=" + (bme.readPressure() / 100.0F) + "&rssi=" + WiFi.RSSI();
            
            // Your Domain name with URL path or IP address with path
            http.begin(serverPath.c_str());
            
            // Send HTTP GET request
            int httpResponseCode = http.GET();
            
            if (httpResponseCode>0) {
                Serial.print("HTTP Response code: ");
                Serial.println(httpResponseCode);
                String payload = http.getString();
                Serial.println(payload);
            }
            else {
                Serial.print("Error code: ");
                Serial.println(httpResponseCode);
            }
            // Free resources
            http.end();
            printValues();
        }
        else {
            Serial.println("WiFi Disconnected");
            wifiRestart();
        }
        Serial.print("Send Time = ");
        Serial.println(lastTime);
        runClear();
        lastTime = millis();
    }
}

void printValues() {
    Serial.print("Test Time = ");
    Serial.println(lastTime);
    
    Serial.print("Temperature = ");
    Serial.print(bme.readTemperature());
    Serial.println(" *C");
    
    Serial.print("Pressure = ");
    Serial.print(bme.readPressure() / 100.0F);
    Serial.println(" hPa");
    
    Serial.print("Approx. Altitude = ");
    Serial.print(bme.readAltitude(SEALEVELPRESSURE_HPA));
    Serial.println(" m");
    
    Serial.print("Humidity = ");
    Serial.print(bme.readHumidity());
    Serial.println(" %");
    
    Serial.print("Signal strength (RSSI) = ");
    Serial.print(WiFi.RSSI());
    Serial.println(" dBm");
    
    Serial.print("Test Time = ");
    Serial.println(lastTime);
    
    Serial.print("WiFi failed ");
    Serial.print(wifiFail);
    Serial.println(" times.");
    
    Serial.println();
}

Something else I'm wondering about is with these libs I use 66% of ESP32 memory? Seems to be a bit much?

Is this a faulty code? Gives no warning:

    {
        delay(500);
        Serial.print(".");
        count++;
        
        if (count == 30)
        wifiRestart();
    }

Edit: Changed it to this:

{
        delay(500);
        Serial.print(".");
        count++;
        
        if (count >= 30) {
            wifiRestart();
        }
    }

I only delay for 4 or 5 seconds and only count to 10. If it fails I reboot the ESP32.

My Wi Fi connection code.


void connectToWiFi()
{
  int TryCount = 0;
  while ( WiFi.status() != WL_CONNECTED )
  {
    TryCount++;
    WiFi.disconnect();
    WiFi.begin( SSID, PASSWORD );
    vTaskDelay( 4000 );
    if ( TryCount == 10 )
    {
      ESP.restart();
    }
  }
  WiFi.onEvent( WiFiEvent );
} // void connectToWiFi()

I can see your code but I want it to work similar to what I have done. And the WiFi.onEvent I have no use for. But look at my improved code, the 30 times counter is just for showing dot's, while the WiFi restart function is:

void wifiRestart() {
    int tryCount = 0;
    while(WiFi.status() != WL_CONNECTED) {
        tryCount++;
        wifiFail++;
        WiFi.disconnect();
        WiFi.begin(ssid, password);
        vTaskDelay(4000);
        if(tryCount >= 10) {
            ESP.restart();
        }
    }
}
1 Like

looks good.

Should have an else

else {

connectToWiFI();
}

And this is a better WiFi check in the loop()

if ( (wifiClient.connected()) && (WiFi.status() == WL_CONNECTED) )
    {

Did you read the code?
It has this:

        else {
            Serial.println("WiFi Disconnected");
            wifiRestart();
        }

I finally did read that.

And the WiFi.onEvent( WiFiEvent ); can be very useful.

// interrupt service routine for WiFi events put into IRAM
void IRAM_ATTR WiFiEvent(WiFiEvent_t event)
{
  switch (event) {
    case SYSTEM_EVENT_STA_CONNECTED:
      break;
    case SYSTEM_EVENT_STA_DISCONNECTED:
      log_i("Disconnected from WiFi access point");
      break;
    case SYSTEM_EVENT_AP_STADISCONNECTED:
      log_i("WiFi client disconnected");
      break;
    default: break;
  }
} // void IRAM_ATTR WiFiEvent(WiFiEvent_t event)
////

You can have the disconnect become automatic code to run when a disconnect is detected.

1 Like

I don't seem to have a wifiClient.connected() function in my current library.

It's not a function, it is a property returned by the WiFi class.

Well I get an error if I add that!
error: 'wifiClient' was not declared in this scope

error: 'class WiFiClass' has no member named 'connected'

Just forget it.

Hmm. I'm not very experienced with this. lol