Hallo,
ich habe da ein etwas seltsamen Problem mit meiner Wetterstation. Das Problem ist bis jetzt zwei mal aufgetreten jeweils etwa nach 3 Wochen Betrieb ohne Probleme.
Anwendung
Wetterstation mit Hardware ESP8266-01 und BME 280
als NTP Timeserver verwende ich die Fritzbox und als interne Uhr die standard Time.h. Synchronisiert wird die Zeit jede Stunde . Alle zwei Stunden schreibe ich per FTP Daten auf die Fritzbox. Zusätlich ist noch ein Webserver enthalten Auf der Webseite werden die aktuellen Messwerte und eine Grafik der letzten 4 Stunden dargestellt . Die jeweiligen Ereignisse zum Messen und das Daten in´s FIFO für die Grafik schreiben werden mittels Abfrage der Zeit now() getriggert.
if ( tnow >= last_mess + 10) { // Messen
last_mess = tnow;
Serial.print("gemessen ");Serial.println(tnow);
messen();
}
Das Problem :
in der auf die Fitzbox geschreibenen CSV Datei ist zu sehen das es einen Eintrag mit völlig falschem Datum/Zeit gibt.
2036-02-07 08:28:25; 23,91; 44,45; 1016,68
danach wird dann wahrscheinlich noch einmal gemessen und dann nicht mehr, da die Varialbe zum speichen der letzten Messzeit "last_mess" auf einem hohen Wert steht und die >= nicht mehr erfüllt ist.
Irgendwann scheint dann die Zeit wieder richtig zu sein und es wird wieder in die CSV geschrieben. Der Trigger dazu wird durch die aktuelle Uhrzeit mit hour(), minute(), second() gebildet. Allerdings immer die gleichen Messwerte da der Trigger zum messen wegen des immer noch falschen "last_mess" nicht funzt.
2018-06-12 00:00:17; 24,19; 51,85; 1013,58
2018-06-12 02:00:17; 24,13; 49,76; 1013,46
2018-06-12 04:00:16; 23,91; 49,62; 1013,61
2018-06-12 06:00:17; 23,90; 48,63; 1013,68
2018-06-12 08:00:17; 23,86; 48,07; 1014,20
2018-06-12 10:00:17; 23,86; 47,73; 1014,47
2018-06-12 12:00:17; 23,96; 47,03; 1015,17
2018-06-12 14:00:17; 24,30; 45,11; 1015,16
2018-06-12 16:00:18; 24,26; 44,46; 1015,31
2018-06-12 18:00:17; 22,90; 46,14; 1015,25
2018-06-12 20:00:17; 23,45; 45,54; 1015,59
2018-06-12 22:00:17; 24,03; 46,71; 1016,44
2018-06-13 00:00:17; 23,91; 48,62; 1016,38
2036-02-07 08:28:25; 23,91; 44,45; 1016,68 <----- falsch
2018-06-13 10:00:17; 23,60; 43,51; 1016,86
2018-06-13 12:00:17; 23,60; 43,51; 1016,86
2018-06-13 14:00:17; 23,60; 43,51; 1016,86
2018-06-13 16:00:17; 23,60; 43,51; 1016,86
2018-06-13 18:00:17; 23,60; 43,51; 1016,86
Handelt es sich bei dem falschen Datum eventuell um den Überlaufwert ? von tnow. Ist jemandem sowas bekannt?
Ich denke eigendlch es kann nur daran liegen das bei dem Sync mit dem NTP was falsch läuft. Aber warum nur alle ca.3 Wochen da sind dann ca. 500 Sync´s gut gelaufen.
#include <Time.h>
#include <TimeLib.h>
#include <ESP8266WiFi.h>
#include <WiFiUdp.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <ESP8266mDNS.h>
#include <string.h>
#include <BME280I2C.h>
#include <Wire.h>
char ssid[] = "xxxxx"; // lokales Netzwerk
char pass[] = "xxxxx"; // passwort
unsigned int localPort = 2390; // lokaler port für UDP
IPAddress FritzboxIP(192, 168, 178, 1); // Fritzbox
const int NTP_PACKET_SIZE = 48; // NTP Paket länge
byte paket[ NTP_PACKET_SIZE]; // NTP puffer
boolean sommerzeit = true;
boolean status_messen = false;
String file = "wetter.csv";
unsigned long last_mess, last_buf;
unsigned long alarmzeit[12];
boolean alarmquit[12];
float temperatur, humidity, luftdruck; // aktualwerte
float tempMittelbuf, humMittelbuf, luftMittelbuf; // puffer gleitender Mittelwert
float buftemp[18], bufhum[18], bufluft[18]; // Kurzzeitspeicher
float Steigung, Abschnitt;
int ZeigerBuf = -1;
// UDP Instanz erstellen
WiFiUDP udp;
// Server Instanz erstellen
ESP8266WebServer server(80);
// FTP Instanz erstellen
WiFiClient ftpClient;// client Port 21
WiFiClient dClient;// client für daten Portnr. kommt vom Server
// BME settings
BME280I2C::Settings settings(
BME280::OSR_X1,
BME280::OSR_X1,
BME280::OSR_X1,
BME280::Mode_Forced,
BME280::StandbyTime_1000ms,
BME280::Filter_4,
BME280::SpiEnable_False,
0x77 // I2C address. I2C specific.
);
BME280I2C bme(settings);
//======================= Set up ============================
void setup() {
Serial.begin(115200);
Serial.println("-------------");
Serial.printf("Connecting to ", ssid);
wificonnect();
// NTP Zeit abrufen und läuft so automatisch zyklisch ab
setSyncProvider(get_time);
setSyncInterval(3600);
Serial.println(DatumZeit());
// WebServer starten
if (MDNS.begin("esp8266")) {
Serial.println("MDNS responder started");
}
server.on("/", handleRoot);
server.on ( "/test1.svg", drawGraph1 );
server.on ( "/test2.svg", drawGraph2 );
server.on ( "/test3.svg", drawGraph3 );
server.onNotFound(handleNotFound);
server.begin();
Serial.println("HTTP server started");
// I2C Bus starten an pin 1 u pin 2
Wire.begin(0, 2);
delay(2000);
while (!bme.begin()) {
Serial.println(F(" Kann BME 280 Sensor nicht finden"));
}
// Alarmwerte vorbesetzeten ab 0:00:15 alle zwei Stunden
for (int i = 0; i <= 11; i++) {
alarmzeit[i] = i * 7200 + 15;
// Serial.println(alarmzeit[i]);
}
bool dummy = alarm(); // Alarm initialisieren auf aktuelle Zeit
}
//======================= loop ============================
void loop() {
if (WiFi.status() != WL_CONNECTED) {
wificonnect();
delay(1000);
}
time_t tnow = now();
server.handleClient();
if ( tnow >= last_mess + 10) { // Messen
last_mess = tnow;
Serial.print("gemessen ");Serial.println(tnow);
messen();
}
if (tnow >= last_buf + 900) { // Kurzzeitspeicher schreiben
last_buf = tnow;
fill_buffer();
}
if (alarm()) { // Daten auf Fritzbox schreiben
if ( ftp_write()) {
Serial.println(F("Daten geschrieben"));
}
}
}
Sync
// -------------- Datum Zeit von Timeserver holen-------------
time_t get_time() {
Serial.println(F("UDP starten"));
udp.begin(localPort);
// Paketdaten zur NTP Anfrage
memset(paket, 0, 48);
paket[0] = 0b11100011;
paket[1] = 0;
paket[2] = 6;
paket[3] = 0xEC;
paket[12] = 49;
paket[13] = 0x4E;
paket[14] = 49;
paket[15] = 52;
udp.beginPacket(FritzboxIP, 123);
udp.write(paket, NTP_PACKET_SIZE);
udp.endPacket();
delay(1000);
int cb = udp.parsePacket();
if (!cb) {
Serial.println("kein NTP Paket");
}
else {
udp.read(paket, NTP_PACKET_SIZE);
Serial.println("Zeit synchron");
}
udp.stop();
unsigned long secsSince1900;
// convert four bytes starting at location 40 to a long integer
secsSince1900 = (unsigned long)paket[40] << 24;
secsSince1900 |= (unsigned long)paket[41] << 16;
secsSince1900 |= (unsigned long)paket[42] << 8;
secsSince1900 |= (unsigned long)paket[43];
const unsigned long seventyYears = 2208988800UL;
unsigned long aktTime = secsSince1900 - seventyYears;
// UTC -> Europa und sommerzeit
if (sommerzeit) {
aktTime += 7200L;
}
else {
aktTime += 3600L;
}
return aktTime;
}
PS : sehe gerade muss das nicht
// UTC -> Europa und sommerzeit
if (sommerzeit) {
aktTime += 7200UL;
}
else {
aktTime += 3600UL;
könnte es daran liegen ?