Esp8266 在很长时间(9 小时)后随机重置

问题描述 投票:0回答:1

我有esp8266,它连接了3个温度传感器。我将所有数据放入列表中(温度和时间)。 esp8266 工作 9 小时后刷新所有内容,所有数据都会丢失。我尝试检查我的代码,但问题仍然存在。

我预计它只会编辑以前的温度并且不会重置。这是架构(没有 8266): 没有 esp8266 的架构

这是我的代码:

    #include <ESP8266WiFi.h>
    #include <ESP8266WebServer.h>
    #include <OneWire.h>
    #include <DallasTemperature.h>
    #include <WiFiUdp.h>
    #include <EEPROM.h>
    #define SENSORS_PIN D7


    OneWire oneWire1(SENSORS_PIN);

    DallasTemperature sensors(&oneWire1);

    const int numSensors = 3;
    const int maxRecords = numSensors * 1000;
    const int INTERVAL_ADDRESS_IN_EEPROM = 0;
    float temperatures[maxRecords];
    unsigned long timestamps[maxRecords];
    int ids[maxRecords];
    int dataIndex = 0;
    unsigned long lastMillis = 0;
    int interval = 10000;


    unsigned long blink = 0;
    int blink_type = 0;

    const char* ssid = "MY-SSID";
    const char* password = "MY-PASSWORD";

    ESP8266WebServer server(80);
    WiFiUDP udp;
    const unsigned int udpPort = 4210;
    unsigned long lastUdpMillis = 0;

    int sensor_ids[numSensors] = {1,2,3};

    void writeToEEPROM(int address, int value) {
      EEPROM.put(address, value);
      EEPROM.commit();
    }

    int readFromEEPROM(int address) {
      int value;
      EEPROM.get(address, value);
      return value;
    }

    void setup() {
      pinMode(SENSORS_PIN, INPUT_PULLUP);
      pinMode(LED_BUILTIN, OUTPUT);

      sensors.begin();

      Serial.begin(9600);
      EEPROM.begin(512);

      interval = readFromEEPROM(INTERVAL_ADDRESS_IN_EEPROM);
      if (interval <= 0 || interval > 60000) {
        interval = 10000;
        writeToEEPROM(INTERVAL_ADDRESS_IN_EEPROM, interval);
        Serial.println("Interval set to default value: 10000 milliseconds");
      } else {
        Serial.printf("Current interval is %d milliseconds\n", interval);
      }

      WiFi.begin(ssid, password);
      while (WiFi.status() != WL_CONNECTED) {
        delay(500);
        Serial.print(".");
      }
      Serial.println("\nConnected to WiFi");

      Serial.print("IP Address: ");
      Serial.println(WiFi.localIP());

      udp.begin(udpPort);

      server.on("/status", []() {
        server.send(200, "text/html", "OK");
      });
      
      server.on("/setinterval", []() {
        int newInterval = server.arg("interval").toInt();
        if (newInterval > 0 && newInterval <= 60000) {
          interval = newInterval;
          writeToEEPROM(INTERVAL_ADDRESS_IN_EEPROM, interval);
          Serial.printf("Interval updated to %d milliseconds\n", interval);
          server.send(200, "text/html", "<p>Interval set</p>");
        } else {
          server.send(400, "text/html", "<p>Invalid interval</p>");
        }
      });

      server.on("/exit", []() {
        Serial.println("Restarting device...");
        server.send(200, "text/html", "Exiting");
        ESP.restart();
      });

      server.on("/temp", []() {
        String sensor_id = server.arg("sensor_id");
        int limit = server.arg("limit").toInt();
        unsigned long currentMillis = millis();
        unsigned long time_frame = 0;
        bool filterByTime = server.hasArg("time");
        unsigned long requestTime = server.arg("time").toInt() * 1000;

        if (filterByTime) {
          time_frame = currentMillis - requestTime;
        } else {
          time_frame = 0;
        }

        if (limit <= 0) {
          limit = 10;
        }

        String response = "{\"temperature_data\":[";
        int count = 0;
        int totalMatched = 0;

        for (int i = 0; i < maxRecords; i++) {
          bool isWithinTimeFrame = !filterByTime || timestamps[i] >= time_frame;
          bool matchesSensorId = sensor_id.isEmpty() || ids[i] == sensor_id.toInt();

          if (ids[i] != 0 && isWithinTimeFrame && matchesSensorId) {
            totalMatched++;

            if (count < limit) {
              if (count > 0) {
                response += ",";
              }
              response += "{\"temp\":" + String(temperatures[i], 2) + ",\"time\":" + String(currentMillis - timestamps[i]) + ",\"sensor_id\":" + ids[i] + "}";
              count++;
            }
          }
        }

        int remainCount = totalMatched - count;
        response += "],\"remain_cnt\":" + String(remainCount) + "}";
        server.send(200, "application/json", response);
      });

      Serial.println("Server started");
      server.begin();
    }

    void loop() {
      server.handleClient();

      if (millis() - blink >= 100) {
        blink = millis();

        if (blink_type == 1) {
          digitalWrite(LED_BUILTIN, HIGH);
          blink_type = 0;
        }else{
          digitalWrite(LED_BUILTIN, LOW);
          blink_type = 1;
        }
      }

    if (millis() - lastMillis >= interval) {
        lastMillis = millis();

        for (int i = 0; i < numSensors; i++) {
            sensors.requestTemperatures();
            float temperature = sensors.getTempCByIndex(i);

            int lastIndex = (dataIndex - 1 + maxRecords) % maxRecords;
            int secondLastIndex = (dataIndex - 2 + maxRecords) % maxRecords;

            float lastTemperature = temperatures[lastIndex];
            float secondLastTemperature = temperatures[secondLastIndex];

            float diffLast = abs(temperature - lastTemperature);
            float diffSecondLast = abs(temperature - secondLastTemperature);

            if (diffLast <= 0.2 && diffSecondLast <= 0.2) {
                timestamps[lastIndex] = millis();
            } else {
                temperatures[dataIndex] = temperature;
                timestamps[dataIndex] = millis();
                ids[dataIndex] = sensor_ids[i];
                dataIndex = (dataIndex + 1) % maxRecords;
            }
        }
    }


      if (millis() - lastUdpMillis > 1000) {
        int packetSize = udp.parsePacket();
        if (packetSize) {
          char packetBuffer[255];
          int len = udp.read(packetBuffer, sizeof(packetBuffer) - 1);
          packetBuffer[len] = '\0';
          if (len > 0) {
            String packetString = String(packetBuffer);

            if (packetString.indexOf("DISCOVER") >= 0) {
              if (packetString.indexOf(WiFi.localIP().toString()) < 0) { 
                IPAddress remoteIp = udp.remoteIP();
                Serial.print("Device with IP: ");
                Serial.print(remoteIp);
                Serial.print(" is attempting to connect...");

                udp.beginPacket(remoteIp, udpPort);
                String message = "'DEVICE' ," + String(numSensors) + ", [";
                for (int i = 0; i < numSensors; i++) {
                  message += sensor_ids[i];
                  if (i < numSensors - 1)  message += ", ";
                }
                message += "]";
                udp.print(message);
                udp.endPacket();
                Serial.println("Response packet sent");
              }
            }
          } else {
            Serial.println("Error reading UDP packet");
          }
        }
        lastUdpMillis = millis();
      }
    }
```

list arduino esp8266
1个回答
0
投票

这种情况下的问题很难解决,因为 Arduino 运行在 Espressif SDK 这也不是没有错误!

随着时间的推移,固件出现的问题可能来自 RAM,因为您还有近 40K 的 RAM 可供使用。

1-了解这是否来自您的代码的更好方法是保持 ESP 连接到串行并增加调试消息,并在错误再次发生时检查串行,并使用

ESP.getFreeHeap();
跟踪内存使用量是否增长。

2- 考虑使用 char[] 数组而不是 String 对象进行 Web 响应,以尽可能避免动态内存分配。

© www.soinside.com 2019 - 2024. All rights reserved.