logo elektroda
logo elektroda
X
logo elektroda
Dostępna jest polska wersja

Czy wolisz polską wersję strony elektroda?

Nie, dziękuję Przekieruj mnie tam

ESP32 – freezes when sending data from the BME280 and CCS811 to InfluxDB via Wi-Fi

K3 69 2
ADVERTISEMENT
Treść została przetłumaczona polish » english Zobacz oryginalną wersję tematu
  • ESP32 freeze likely caused by Wi-Fi or HTTP blocking

    #1 21929682
    K3
    Level 30  
    Posts: 1686
    Help: 153
    Rate: 429
    Having trouble with your ESP32 freezing?

    I have an ESP32 development board with two sensors connected to it, which together measure temperature, humidity, pressure and CO2.
    The whole system works; the data is collected, then sent via Wi-Fi to InfluxDB and subsequently displayed by Grafana.

    However, every now and then, the ESP32 suddenly stops responding and there are no recent readings in the database. Where might the problem lie?

    I’ve attached the code:

    
    #include <WiFi.h>
    #include <HTTPClient.h>
    #include <Wire.h>
    #include <Adafruit_Sensor.h>
    #include <Adafruit_BME280.h>
    #include "Adafruit_CCS811.h"
    
    Adafruit_BME280 bme;
    Adafruit_CCS811 ccs;
    
    // ===== WIFI =====
    const char* ssid     = "WiFI";
    const char* password = "WiFi;
    
    // ===== INFLUXDB =====
    const char* influxUrlBase = "http://192.168.1.200:8086";
    const char* influxOrg     = "esp32lab";
    const char* influxBucket  = "esp32_raw_24h";
    const char* influxToken   = "1234567890";
    
    char authHeader[256];
    char influxUrl[256];
    char lineBuf[512];
    
    // ===== IDENTYFIKACJA =====
    const char* sensorId    = "esp32-01";
    const char* deviceId    = "DEV01";
    const char* locationTag = "office";
    
    // ===== LOKALIZACJA STACJI =====
    const float STATION_ALTITUDE = 60.0; 
    
    // ===== PINY I2C =====
    const int I2C_SDA = 21;
    const int I2C_SCL = 22;
    
    // ===== PROGRAMOWY WATCHDOG SIECI =====
    int httpErrorCounter = 0;
    const int MAX_HTTP_ERRORS = 10; 
    
    // ===== LED =====
    const int LED_GREEN  = 25;
    const int LED_YELLOW = 26;
    const int LED_RED    = 27;
    const int PWM_FREQ   = 5000;
    const int PWM_RES    = 8;
    const int LED_ON     = 255;
    const int LED_OFF    = 0;
    
    int ledState = -1;  // -1 brak danych, 0 zielona, 1 zolta, 2 czerwona
    
    // ===== STAN CZUJNIKOW =====
    bool bmeFound = false;
    bool ccsFound = false;
    uint8_t bmeAddress = 0;
    uint8_t ccsAddress = 0;
    
    // ===== OSTATNIE POPRAWNE DANE =====
    float lastTemp  = 0.0;
    float lastHum   = 0.0;
    float lastPress = 0.0; 
    
    int lastEco2 = -1;
    int lastTvoc = -1;
    
    bool haveTemp  = false;
    bool haveHum   = false;
    bool havePress = false;
    bool haveEco2  = false;
    bool haveTvoc  = false;
    
    // ===== STATUS SWIEZOSCI =====
    bool tempFresh  = false;
    bool humFresh   = false;
    bool pressFresh = false;
    bool eco2Fresh  = false;
    bool tvocFresh  = false;
    
    // ===== TIMERY =====
    unsigned long lastBmeRead   = 0;
    unsigned long lastCcsRead   = 0;
    unsigned long lastSend      = 0;
    unsigned long lastWifiCheck = 0;
    
    const unsigned long bmeIntervalMs  = 2000;
    const unsigned long ccsIntervalMs  = 2000;
    const unsigned long sendIntervalMs = 15000;
    const unsigned long wifiCheckMs    = 10000;
    
    // =========================================================
    void printSeparator() {
      Serial.println("--------------------------------------------------");
    }
    
    void buildStaticBuffers() {
      snprintf(authHeader, sizeof(authHeader), "Token %s", influxToken);
      snprintf(influxUrl, sizeof(influxUrl),
               "%s/api/v2/write?org=%s&bucket=%s&precision=s",
               influxUrlBase, influxOrg, influxBucket);
    }
    
    void printWiFiStatus() {
      if (WiFi.status() == WL_CONNECTED) {
        Serial.println("WiFi: POLACZONE");
        Serial.print("IP: ");
        Serial.println(WiFi.localIP());
        Serial.print("RSSI: ");
        Serial.println(WiFi.RSSI());
      } else {
        Serial.print("WiFi: NIEPOLACZONE, status=");
        Serial.println(WiFi.status());
      }
    }
    
    void connectWiFi() {
      Serial.print("Laczenie z WiFi: ");
      Serial.println(ssid);
    
      WiFi.mode(WIFI_STA);
      WiFi.setAutoReconnect(true); 
      WiFi.persistent(true);
      WiFi.begin(ssid, password);
    
      unsigned long startTs = millis();
      while (WiFi.status() != WL_CONNECTED && millis() - startTs < 20000) {
        delay(500);
        Serial.print(".");
      }
      Serial.println();
      printWiFiStatus();
    }
    
    void maintainWiFi() {
      if (millis() - lastWifiCheck < wifiCheckMs) return;
      lastWifiCheck = millis();
    
      if (WiFi.status() != WL_CONNECTED) {
        Serial.println("WiFi rozlaczone - oczekiwanie na systemowy auto-reconnect...");
      }
    }
    
    // =========================================================
    void scanI2C() {
      Serial.println("Skanowanie I2C...");
      for (byte addr = 1; addr < 127; addr++) {
        Wire.beginTransmission(addr);
        if (Wire.endTransmission() == 0) {
          Serial.print("Znaleziono I2C: 0x");
          if (addr < 16) Serial.print("0");
          Serial.println(addr, HEX);
        }
      }
    }
    
    void initSensors() {
      if (bme.begin(0x76)) {
        bmeFound = true;
        bmeAddress = 0x76;
      } else if (bme.begin(0x77)) {
        bmeFound = true;
        bmeAddress = 0x77;
      }
    
      if (ccs.begin(0x5A)) {
        ccsFound = true;
        ccsAddress = 0x5A;
      } else if (ccs.begin(0x5B)) {
        ccsFound = true;
        ccsAddress = 0x5B;
      }
    
      if (bmeFound) {
        Serial.print("BME280 @ 0x");
        Serial.println(bmeAddress, HEX);
      } else {
        Serial.println("BME280: nie wykryto.");
      }
    
      if (ccsFound) {
        ccs.setDriveMode(CCS811_DRIVE_MODE_1SEC);
        Serial.print("CCS811 @ 0x");
        Serial.println(ccsAddress, HEX);
      } else {
        Serial.println("CCS811: nie wykryto.");
      }
    }
    
    // =========================================================
    void setupLeds() {
      ledcAttach(LED_GREEN, PWM_FREQ, PWM_RES);
      ledcAttach(LED_YELLOW, PWM_FREQ, PWM_RES);
      ledcAttach(LED_RED, PWM_FREQ, PWM_RES);
    
      ledcWrite(LED_GREEN, LED_OFF);
      ledcWrite(LED_YELLOW, LED_OFF);
      ledcWrite(LED_RED, LED_OFF);
    }
    
    void updateLedFromEco2() {
      if (!eco2Fresh || lastEco2 < 0) {
        ledcWrite(LED_GREEN, LED_OFF);
        ledcWrite(LED_YELLOW, LED_OFF);
        ledcWrite(LED_RED, LED_OFF);
        ledState = -1;
        return;
      }
    
      if (lastEco2 > 1600) {
        ledcWrite(LED_GREEN, LED_OFF);
        ledcWrite(LED_YELLOW, LED_OFF);
        ledcWrite(LED_RED, LED_ON);
        ledState = 2;
      } else if (lastEco2 >= 1000) {
        ledcWrite(LED_GREEN, LED_OFF);
        ledcWrite(LED_YELLOW, LED_ON);
        ledcWrite(LED_RED, LED_OFF);
        ledState = 1;
      } else {
        ledcWrite(LED_GREEN, LED_ON);
        ledcWrite(LED_YELLOW, LED_OFF);
        ledcWrite(LED_RED, LED_OFF);
        ledState = 0;
      }
    }
    
    // =========================================================
    void readBMEOnce() {
      if (!bmeFound) return;
      if (millis() - lastBmeRead < bmeIntervalMs) return;
      lastBmeRead = millis();
    
      tempFresh  = false;
      humFresh   = false;
      pressFresh = false;
    
      float t = bme.readTemperature();
      if (!isnan(t)) {
        lastTemp = t;
        haveTemp = true;
        tempFresh = true;
      }
    
      float h = bme.readHumidity();
      if (!isnan(h)) {
        lastHum = h;
        haveHum = true;
        humFresh = true;
      }
    
      float p_abs = bme.readPressure() / 100.0F;
      if (!isnan(p_abs)) {
        // Rzutowanie ciśnienia bezwzględnego do poziomu morza (QNH)
        lastPress = p_abs * pow(1.0 - (STATION_ALTITUDE / 44330.0), -5.255);
        havePress = true;
        pressFresh = true;
      }
    
      Serial.println("===== BME280 =====");
      Serial.print("Temperatura: "); Serial.print(lastTemp); Serial.print(" *C | fresh="); Serial.println(tempFresh ? 1 : 0);
      Serial.print("Wilgotnosc:  "); Serial.print(lastHum); Serial.print(" % | fresh="); Serial.println(humFresh ? 1 : 0);
      Serial.print("Cisnienie:   "); Serial.print(lastPress); Serial.print(" hPa (QNH) | fresh="); Serial.println(pressFresh ? 1 : 0);
    }
    
    // =========================================================
    void readCCSOnce() {
      if (!ccsFound) return;
      if (millis() - lastCcsRead < ccsIntervalMs) return;
      lastCcsRead = millis();
    
      eco2Fresh = false;
      tvocFresh = false;
    
      if (haveHum && haveTemp) {
        ccs.setEnvironmentalData(lastHum, lastTemp);
      }
    
      if (ccs.available()) {
        if (!ccs.readData()) {
          lastEco2 = ccs.geteCO2();
          lastTvoc = ccs.getTVOC();
          haveEco2 = true;
          haveTvoc = true;
          eco2Fresh = true;
          tvocFresh = true;
        }
      }
    
      updateLedFromEco2();
    
      Serial.println("===== CCS811 =====");
      Serial.print("eCO2: "); Serial.print(lastEco2); Serial.print(" ppm | fresh="); Serial.println(eco2Fresh ? 1 : 0);
      Serial.print("TVOC: "); Serial.print(lastTvoc); Serial.print(" ppb | fresh="); Serial.println(tvocFresh ? 1 : 0);
    }
    
    // =========================================================
    void sendToInfluxAlways() {
      if (millis() - lastSend < sendIntervalMs) return;
      lastSend = millis();
    
      Serial.println("===== SEND =====");
    
      if (WiFi.status() != WL_CONNECTED) {
        Serial.println("Brak WiFi - pomijam ten cykl wysylki.");
        return;
      }
    
      // Usunięto całkowicie pole 'altitude' oraz flagę 'alt_fresh'
      snprintf(lineBuf, sizeof(lineBuf),
        "esp32_air,sensor_id=%s,device_id=%s,location=%s "
        "temperature=%.2f,humidity=%.2f,pressure=%.2f,"
        "eco2=%di,tvoc=%di,wifi_rssi=%di,led_state=%di,"
        "temp_fresh=%di,hum_fresh=%di,press_fresh=%di,"
        "eco2_fresh=%di,tvoc_fresh=%di,bme_found=%di,ccs_found=%di",
        sensorId, deviceId, locationTag,
        lastTemp, lastHum, lastPress,
        lastEco2, lastTvoc,
        (int)WiFi.RSSI(),
        ledState,
        (int)tempFresh, (int)humFresh, (int)pressFresh,
        (int)eco2Fresh, (int)tvocFresh,
        (int)bmeFound, (int)ccsFound
      );
    
      Serial.print("Line: ");
      Serial.println(lineBuf);
    
      HTTPClient http;
      http.setConnectTimeout(5000);
      http.setTimeout(10000);
      http.setReuse(false); 
    
      if (!http.begin(influxUrl)) {
        Serial.println("HTTP begin() nieudane.");
        return;
      }
    
      http.addHeader("Authorization", authHeader);
      http.addHeader("Content-Type", "text/plain; charset=utf-8");
      http.addHeader("Accept", "application/json");
      http.addHeader("Connection", "close"); 
    
      int code = http.POST((uint8_t*)lineBuf, strlen(lineBuf));
    
      Serial.print("HTTP code: ");
      Serial.println(code);
    
      if (code > 0) {
        httpErrorCounter = 0; 
        if (code != 204) {
          String body = http.getString();
          Serial.print("Odpowiedz: ");
          Serial.println(body);
        }
      } else {
        httpErrorCounter++; 
        Serial.print("HTTP error: ");
        Serial.println(http.errorToString(code));
        Serial.print("Licznik bledow sieci: ");
        Serial.println(httpErrorCounter);
    
        if (httpErrorCounter >= MAX_HTTP_ERRORS) {
          Serial.println("!!! KRYTYCZNY ZAWIS SIECI - WYMUSZAM AUTORESTART ESP32 !!!");
          delay(1000);
          ESP.restart(); 
        }
      }
    
      http.end();
      delay(50);
    }
    
    // =========================================================
    void setup() {
      Serial.begin(115200);
      delay(1500);
    
      buildStaticBuffers();
    
      Serial.println();
      Serial.println("Start systemu");
      printSeparator();
    
      Wire.begin(I2C_SDA, I2C_SCL);
      Wire.setTimeOut(3000);
    
      setupLeds();
      connectWiFi();
      scanI2C();
      initSensors();
    
      printSeparator();
      Serial.println("Setup zakonczony.");
      printSeparator();
    }
    
    // =========================================================
    void loop() {
      maintainWiFi();
      readBMEOnce();
      readCCSOnce();
      sendToInfluxAlways();
    }
    
  • ADVERTISEMENT
  • Helpful post

    Missing quote and forced Wi-Fi reconnect fix

    #2 21929735
    yanek231
    Level 23  
    Posts: 411
    Help: 100
    Rate: 148
    You’re missing a closing quotation mark at the end.
    const char* password = "WiFi;

    In
    maintainWiFi()
    , you’re just printing a message, but you’re not actually reconnecting. You’ve got: “waiting for system auto-reconnect...”, but sometimes the ESP32 can hang. It’s better to do it like this:
    void maintainWiFi() {
      if (millis() - lastWifiCheck < wifiCheckMs) return;
      lastWifiCheck = millis();
    
      if (WiFi.status() != WL_CONNECTED) {
        Serial.println("WiFi rozlaczone - wymuszam reconnect...");
        WiFi.disconnect(false);
        delay(100);
        WiFi.begin(ssid, password);
      }
    }
  • #3 21929777
    K3
    Level 30  
    Posts: 1686
    Help: 153
    Rate: 429
    >>21929735

    The typo occurred whilst I was deleting my actual WiFi password; the code itself is fine.

    I’ve corrected the code from maintainWiFi; let’s see how it performs.
ADVERTISEMENT