1

I have a WeMos D1 connected to an air quality sensor and publishing the value on a self-hosted website. Initially everything works fine (although router UI does not display WeMos). After an hour or two WiFi connection fails.
Other devices on the network are unaffected. Sensor data is still being polled, serial connection works fine, but the device doesn't respond to the ping and the website obviously doesn't work.

Here's the code:

#include <ESP8266WiFi.h>

#include "SerialCom.h"
#include "Types.h"


//WiFi setup:
const char* ssid = "mySSID";                    // Enter SSID here
const char* password = "myPASS";                // Enter Password here

IPAddress ip(192, 168, 0, 101);   
IPAddress gateway(192, 168, 0, 1);
IPAddress subnet(255, 255, 255, 0);

WiFiServer  server(80);                         // Server on port 80
String header;

// sensor setup:

uint32_t statusPublishPreviousMillis = 0;
const uint16_t statusPublishInterval = 30000;   // 30 seconds = 30000 milliseconds

particleSensorState_t state;

unsigned long currentTime = millis();           // Current time
unsigned long previousTime = 0;                 // Previous time
const long timeoutTime = 2000;                  // Define timeout time in milliseconds (example: 2000ms = 2s)

float average;
int rounded;


void setup() {

    Serial.begin(115200);
    SerialCom::setup();
    WiFi.config(ip, gateway, subnet);
    WiFi.mode(WIFI_STA);
    WiFi.begin(ssid, password);                 // Connect to the WiFi router
    while (WiFi.status() != WL_CONNECTED) {
        delay(500);
        Serial.print(".");
    }

    Serial.println("");                         // If connection successful show IP address in serial monitor
    Serial.print("Connected to ");
    Serial.println(ssid);
    Serial.print("IP address: ");
    Serial.println(WiFi.localIP());             // IP address assigned to your ESP

    server.begin();                             // Start server
    Serial.println("HTTP server started");
}


void loop() {
    
    SerialCom::handleUart(state);               // communicate with the sensor
    average = SerialCom::forward(state);        // read sensor value
    rounded = round(average);                   // round the value so that we don't have .00 
    

    const uint32_t currentMillis = millis();
    if (currentMillis - statusPublishPreviousMillis >= statusPublishInterval) {
        statusPublishPreviousMillis = currentMillis;
    }

    WiFiClient client = server.available(); 
    if (client) {                               // If a new client connects,
        Serial.println("Client connected");     // print a message out in the serial port
        String currentLine = "";                // make a String to hold incoming data from the client
        currentTime = millis();
        previousTime = currentTime;
    
        while (client.connected() && currentTime - previousTime <= timeoutTime) { // loop while the client's connected
            currentTime = millis();         
            if (client.available()) {           // if there's bytes to read from the client,
                char c = client.read();         // read a byte, then
//              Serial.write(c);                // print it out the serial monitor
                header += c;
                if (c == '\n') {                // if the byte is a newline character
                    // if the current line is blank, you got two newline characters in a row.
                    // that's the end of the client HTTP request, so send a response:
                    if (currentLine.length() == 0) {
                        // HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK)
                        // and a content-type so the client knows what's coming, then a blank line:
                        client.println("HTTP/1.1 200 OK");
                        client.println("Content-type:text/html");
                        client.println("Connection: close");
                        client.println();
                                    
                        // Display the HTML web page
                        client.println("<!DOCTYPE html><html>");
                        client.println("<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">");
                        client.println("<meta charset='utf-8'>");
                      
                        // Values in the website title            
                        client.print("<title>");
                        client.print(rounded);
                        client.println(" μg/m³</title></head>");
                        client.println("<script>");
                      
                        // Automatic refresh script
                        client.println("  function refresh(refreshPeriod)"); 
                        client.println("    {setTimeout('location.reload(true)', refreshPeriod);}"); 
                        client.println("  window.onload = refresh(60000);");
                        client.println("</script>");
                      
                        // Web Page Heading
                        client.println("<body>");
                        client.println(rounded);
                        client.println("</body></html>");
                        
                        client.println("");      // The HTTP response ends with another blank line
                        break;                   // Break out of the while loop
                    } else {                     // if you got a newline, then clear currentLine
                        currentLine = "";
                    }
                } else if (c != '\r') {          // if you got anything else but a carriage return character,
                    currentLine += c;            // add it to the end of the currentLine
                }
            }
        }

        header = "";                             // Clear the header variable
        client.stop();                           // Close the connection
    }
}


EDIT: I've read somewhere that String implementation in ESP8266 library is problematic, so I replaced every String with char*. That increased the uptime to around 30 hrs.

4
  • Before the edit you said that you'd added a check for wifi disconnection which rebooted the ESP8266 and it didn't help. Did it find that wifi disconnected and reboot, or did it do nothing?
    – romkey
    Mar 19 at 22:24
  • It did nothing. If nothing helps, I will test and see if it didn't detect the issue or detected it but the restart didn't help. But I would like to find the root cause and avoid restarting if possible.
    – Han88
    Mar 20 at 10:45
  • Can you try a different unit? I had a similar problem a few years back. Changing the board helped a lot but finally I changed the router and the problem vanished.
    – Gil
    Mar 21 at 1:09
  • I've ordered a second one, but it will take some time and would like to make it work without additional hardware.
    – Han88
    Mar 21 at 17:56

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.