Hallo,
ich brauch noch mal einen Tipp von Euch.
ich habe draußen einen D1 mit einem BME280 mit Aku und einer Solarzelle. Der sendet alle halbe Stunde seine Messwerte mittels TCP an einen ESP32. Da werden die Daten ausgewertet und mittels Chart angezeigt. Das Ganze läuft jetzt seit fast drei Jahren zuverlässig. Nun habe ich festgestellt das seit etwa 2 Wochen 5-6 mal ( Tendenz steigend) innerhalb von 24 Stunden jeweils ein Messwert fehlt. Entweder zur vollen Stunde oder zur halben. Da ich zunächst eine kalte Lötstelle vermutet habe , ist alles auf Streifenraster ohne Schutzlack , habe ich das Teil ausgebaut und nachgelötet , sah alles besser aus als ich gedacht hatte nach zwei Wintern. Das Teil hängt im Trockenen an der Hauswand. War aber anscheinend nicht der Fall, der Fehler ist immer noch da. ![]()
Normalerweise kommen die Messwerte um hh.28.55 und hh.58:55 etwa rein. Dabei ist das jeweils die aktuelle Zeit vom ESP32. Ich hab das extra eine Minute nach vorne geholt, damit der ESP die aktuellen Daten jeweils zur vollen Stunde sicher hat.
Im Fehlerfall fehlt dann allerdings eine Messung, dafür ist die nächste aber ein paar Minuten später. Das sieht also etwa so aus.
Hier fehlt z.B die Messung um 8:28 und dafür ist die Messung die eigentlich um 8:58 sein sollte erst um 9:07 gekommen. Die nächste 9:28 war dann wieder in der Reihe. 9:58 fehlt wieder dafür dann 10:36.
Zudem habe ich festgestellt das die Zeiten mit der Ereignisliste in der Fritzbox identisch sind und im Fehlerfall auch keine Anmeldung in der Fritzbox erfolgt. Ich galube jetzt nicht mehr das es am Sketch liegt. Da im Fehlerfall die Zeit zwischen zwei Messungen allerdings dann etwa 67-68 min (etwa maxzeit) ist denke ich ehr daran das die RTC für den Deep-Sleep dann nicht mehr richtig läuft und es sich somit ehr um ein Hardware Problem des D1 handelt.
Kann es sein das der Speicher an der Stelle an der die Sleepzeit abgelegt wird Möhre wird. ?
Ich hab jetzt keinen D1 mehr hier, sonst würde ich das probieren.
Haltet Ihr meine Vermutung für möglich ?
Heinz
hier der Sketch
/* Wetterdaten mit ESP und BME 280
Hardware Wemos D1 , BME280
Stromversorgung Aku 18650 3,7V 2500mAh
Solarzelle 6V 100mA
Laderegler TP4056, Step Up Wandler auf 5V
Akuspannung gemessen an A0 über zus.200KOhm (Messbereich 5,2V)
*/
#include <ESP8266WiFi.h>
#include <time.h>
#include <BME280I2C.h>
#include <Wire.h>
const char* ssid = "xxx";
const char* password = "yyyy";
IPAddress staticIP(192, 168, 178, 12); // eigene IP
IPAddress gateway(192, 168, 178, 1); // Fritzbox Heimnetz
IPAddress subnet(255, 255, 255, 0);
const char*host = "192.168.178.21"; //server IP
//uint16_t localPort = 4211;
uint16_t hostPort = 4210; // Host Port
float temp, hum, pres, Vcc;
unsigned long altzeit;
int devAdress = 1;
int year;
byte month, day, hour, minute, second;
const uint32_t messcycle = 1800UL; // Messzyklus sekunden
uint32_t sleeptime = 0; // ESP deep Sleep Zeit
//ADC_MODE(ADC_VCC);
// BME settings
BME280I2C::Settings settings(
BME280::OSR_X1,
BME280::OSR_X1,
BME280::OSR_X1,
BME280::Mode_Forced,
BME280::StandbyTime_1000ms,
BME280::Filter_Off,
BME280::SpiEnable_False,
BME280I2C::I2CAddr_0x77 // I2C address. I2C specific.
);
BME280I2C bme(settings);
//---------------- Setup--------------
void setup() {
Serial.begin(74880);
//Serial.setDebugOutput(true);
Serial.println("start wire");
// I2C Bus starten an pin D1=SCL u pin D2=SDA
Wire.begin();
//delay(200);
conectWIFI(); // einloggen
configTime(0, 0, "192.168.178.1"); // locale Fritzbox
setenv("TZ", "CET-1CEST,M3.5.0/02,M10.5.0/3", 1); // locale Zeit einstellen mit Sommerzeit
Serial.println(F("Waiting for time "));
while (!time(nullptr)) {
Serial.print(".");
delay(500);
}
delay(1000); // warten auf NTP Zeit
byte count = 0;
while (!bme.begin()) {
delay(100);
Serial.println(F(" Kann BME 280 Sensor nicht finden"));
// Wenn keine Verbindung möglich beenden
count++;
if (count == 10) {
readtime();
//sendTCP();
calcnext();
ESP_sleep(messcycle);
}
}
}
//-------------- Loop ----------------
void loop() {
// if (millis() - altzeit >= sleeptime * 1000UL) {
altzeit = millis();
readtime(); // aktuelle Zeit lesen
messen(); // Messdaten holen
sendTCP(); // daten an Server senden
calcnext(); // nexte Weckzeit berechnen
ESP_sleep(sleeptime); // ESP in sleepmodus
// }
}
//================= funktions ======================
void conectWIFI() {
byte maxzeit = 0;
WiFi.persistent(false); // daten nicht in EEprom
WiFi.mode(WIFI_STA);
Serial.printf("Connecting to %s ", ssid);
WiFi.config(staticIP, gateway, subnet);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
maxzeit++; // max Zeit
if (maxzeit > 30) ESP_sleep(messcycle);
}
Serial.print(F(" connected \nlocale IP:"));
Serial.println(WiFi.localIP());
}
// ---------- messen -------------------------
void messen() {
BME280::TempUnit tempUnit(BME280::TempUnit_Celsius);
BME280::PresUnit presUnit(BME280::PresUnit_hPa);
bme.read(pres, temp, hum, tempUnit, presUnit);
// umrechnen auf Meereshöhe Luftruck wird immer auf Meereshöhe bezogen
// vereinfachte Rechnung 12.2mbar /100m mehr
// Wohnort liegt ca. auf 150m
pres = pres + 12.2 * 150 / 100;
temp = temp - 2.2; // Temp anpassen
Vcc = analogRead(A0) / 1024.0 * 5.20;// zus. 200KOhm Messbereich jetzt 5,2V
}
// -------------- send TCP -------------------------
void sendTCP() {
Serial.printf("connecting to %s %d \n", host, hostPort);
WiFiClient client;
if (!client.connect(host, hostPort)) {
Serial.println("connection failed");
//delay(1000);
return;
}
Serial.println(F("sending data to server"));
Serial.printf("%4d;%4.2f;%4.2f;%4.2f;%4.2f\n", devAdress, temp, hum, pres, Vcc);
client.printf("%4d;%4.2f;%4.2f;%4.2f;%4.2f", devAdress, temp, hum, pres, Vcc);
Serial.println(F("closing connection"));
delay(100);
client.stop();
}
// ------------------Datum und zeit auslesen
void readtime() {
time_t now = time(nullptr);
struct tm*timeinfo;
time(&now);
timeinfo = localtime(&now);
year = 1900 + timeinfo->tm_year;
month = 1 + timeinfo->tm_mon;
day = timeinfo->tm_mday;
hour = timeinfo->tm_hour;
minute = timeinfo->tm_min;
second = timeinfo->tm_sec;
Serial.printf("Time is %02u-%02u-%4u ", day, month, year);
Serial.printf("%02u:%02u:%02u \n", hour, minute, second);
}
//----------------- ESP sleep
void ESP_sleep(uint32_t sl) {
delay(300);// noch warten sonst fehlen Telegramme
// anpassung der esp Frequenz +5%
sl = sl + sl * 5UL / 100UL;
Serial.printf("Korr. Sleepwert %u Laufzeit war %lums\n", sl, millis());
WiFi.disconnect(true);
delay(1);
WiFi.mode(WIFI_OFF);
WiFi.forceSleepBegin ();
delay(1);
ESP.deepSleep(sl * 1000000, WAKE_NO_RFCAL);
delay(1);
}
//----------------- Nexte weckzeit berechnen
// nächstes Wecken soll bei minuten 28 u 58 sein
// wenn nächste sleepzeit < 5 min dann ausfallen lassen
void calcnext() {
uint32_t actsec = 0;
if (year < 2000) { // Datum war falsch
sleeptime = messcycle - millis() / 1000UL;
}
else {
actsec = minute * 60UL + second;
actsec = actsec + 60UL; // messung um 1 minuten vorlegen
sleeptime = messcycle - actsec % messcycle;
sleeptime = sleeptime - millis() / 1000UL; // Laufzeit abziehen
if (sleeptime < 300UL) { // wenn < 5 min dann ausfallen lassen.
sleeptime = messcycle + sleeptime;
}
Serial.printf("akt.Sekunde %u Messcycle %us Sleeptime %us \n", actsec, messcycle, sleeptime);
}
}
