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
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();
}
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'
Hmm. I'm not very experienced with this. lol