Frage: Wie kann ich einen Sensor immer zur gleichen Zeit, besser im selben Zeitintervall, auslesen?
Daten sollen über einen sehr langen Zeitraum gesammelt werden.
Immer zur vollen Stunde soll eine Messung geschrieben werden,
Im Großen und Ganzen funktioniert das einwandfrei, aber...
Es verschlägt immer um eine oder gar 2 Sekunden.
Und über das Jahr sammelt sich da schon eine Ungenauigkeit an, Zeit mäßig.
Wie kann ich erreichen, dass die Daten immer zur vollen Stunde ausgelesen werden.
Ich habe es schon mit "delay", "millis() und mit deep sleep versucht.
Aber es war nichts zielführend.
nimm das schon angesprochene RTC als Modul (suche nach Arduino ds3231) oder gleich einen Microcontroller der eine Internetverbindung hat und somit die Uhrzeit über NTP konstant halten kann. Ein Board mit einem ESP8266 oder ESP32 wäre hier ein guter Anfang.
Wenn Du schon die Zeit per NTP aus dem Internet holst, dann erklärt das nicht die Abweichung von mehreren Sekunden pro Stunde. Dann machst Du sehr wahrscheinlich in Deinem Programm etwas falsch.
Nur, da es keiner außer Dir kennt, ist eine klare Aussage woran das liegt unmöglich.
wenn du schon einen D1 mini mit NTP nutzt, dann sollte der Stundenwechsel auch auf die Sekunde genau möglich sein. Nimm nicht ein delay/millis() sondern arbeite mit dem Stundenwechsel!
Und wenn du dann noch den NTP update auch auf 60 Minuten setzt, dann läuft das rund.
Heureka!
Die Lösung, vielleicht nicht so komfortabel, aber dafür bin ich auch Laie.
Also, ich lasse mir Stunden, Minuten uns Sekunden einzeln ausgeben.
Dann starte ich eine Abfrage. Wenn Minute und Sekunde gleich 0 sind, wird der Sensor ausgelesen und alles mit der Zeit auf SD geschrieben.
Wenn nicht, wird gewartet.
Probelauf hat geklappt.
/*
NTP TZ DST - bare minimum with Timer
for https://forum.arduino.cc/t/sensor-auslesen-mittels-uhrzeit/1356698/5
by noiasca
2025-02-02 see also https://werner.rothschopf.net/202011_arduino_esp8266_ntp_en.htm
*/
//#include <credentials.h> // if you have a config file with your credentials
#ifndef STASSID
#define STASSID "your-ssid" // set your SSID
#define STAPSK "your-password" // set your wifi password
#endif
/* Configuration of NTP */
// choose the best fitting NTP server pool for your country
#define MY_NTP_SERVER "at.pool.ntp.org"
// choose your time zone from this list
// https://github.com/nayarsystems/posix_tz_db/blob/master/zones.csv
#define MY_TZ "CET-1CEST,M3.5.0/02,M10.5.0/03" // Berlin, Vienna, Rom, ...
//#define MY_TZ "<+0115>-1:15" // Test
//#define MY_TZ "ACST-9:30" // Australia/Darwin
//#define MY_TZ "<+0845>-8:45" // Australia/Eucla
/* Necessary Includes */
#ifdef ARDUINO_ARCH_ESP32 // for the ESP32
#include <WiFi.h> // we need wifi to get internet access
#endif
#ifdef ARDUINO_ARCH_ESP8266 // for the ESP8266
#include <ESP8266WiFi.h> // we need wifi to get internet access
#endif
#include <time.h> // time() ctime()
/* Globals */
time_t now; // this is the epoch
tm tm; // the structure tm holds time information in a more convenient way
/*
* Another standard value is the NTP polling interval.
* The default value is 60 minutes.
* This value can also be changed.
*/
uint32_t sntp_update_delay_MS_rfc_not_less_than_15000 () {
return 1 * 60 * 60 * 1000UL; // n hours
}
void showTime() {
time(&now); // read the current time
localtime_r(&now, &tm); // update the structure tm with the current time
Serial.print(F("year:"));
Serial.print(tm.tm_year + 1900); // years since 1900
Serial.print(F(" month:"));
Serial.print(tm.tm_mon + 1); // January = 0 (!)
Serial.print(F(" day:"));
Serial.print(tm.tm_mday); // day of month
Serial.print(F(" hour:"));
Serial.print(tm.tm_hour); // hours since midnight 0-23
Serial.print(F(" min:"));
Serial.print(tm.tm_min); // minutes after the hour 0-59
Serial.print(F(" sec:"));
Serial.print(tm.tm_sec); // seconds after the minute 0-61*
Serial.print(F(" wday:"));
Serial.print(tm.tm_wday); // days since Sunday 0-6
if (tm.tm_isdst == 1) // Daylight Saving Time flag
Serial.print(F(" DST"));
else
Serial.print(F(" standard"));
Serial.println();
}
void timerShowTime() {
static uint32_t previousMillis = 0;
const uint32_t interval = 60000;
uint32_t currentMillis = millis();
if (currentMillis - previousMillis >= interval) {
previousMillis = currentMillis;
Serial.print(F("w millis: "));
showTime();
}
}
void timerHourly() {
static uint32_t previousHour = 1;
const uint32_t interval = 1;
time(&now); // read the current time
localtime_r(&now, &tm); // update the structure tm with the current time
if (tm.tm_hour - previousHour >= interval) {
previousHour = tm.tm_hour;
Serial.print(F("new hour: "));
showTime();
}
}
void timerMinutely() {
static uint32_t previousMinute = 0;
const uint32_t interval = 1;
time(&now); // read the current time
localtime_r(&now, &tm); // update the structure tm with the current time
if (tm.tm_min - previousMinute >= interval) {
previousMinute = tm.tm_min;
Serial.print(F("new minute: "));
showTime();
}
}
void setup() {
Serial.begin(115200);
delay(200); // just give Serial some time to start
Serial.println(F("\nNTP TZ DST - bare minimum with timer"));
#ifdef ARDUINO_ARCH_ESP32 // for the ESP32 (needs 3 lines)
configTime(0, 0, MY_NTP_SERVER); // 0, 0 because we will use TZ in the next line
setenv("TZ", MY_TZ, 1); // Set environment variable with your time zone
tzset();
#endif
#ifdef ARDUINO_ARCH_ESP8266 // for the ESP8266
configTime(MY_TZ, MY_NTP_SERVER); // the ESP8266 you only need this IMPORTANT ONE LINER in your sketch!
#endif
// start network
WiFi.persistent(false);
WiFi.mode(WIFI_STA);
WiFi.begin(STASSID, STAPSK);
while (WiFi.status() != WL_CONNECTED) {
delay(200);
Serial.print('.');
}
Serial.println(F("\nWiFi connected"));
// remark: by default, the NTP will be started within 60 secs
}
void loop() {
timerShowTime();
timerHourly();
timerMinutely();
}
//
Danke!
Schaue ich mir an.
Zur Zeit habe ich Probleme.
Mit Sekunde auf Null geht, mit Minuten auf irgendwas, um nicht immer so lange warten zu müssen, geht auch.
Minute und Sekunde auf Null geht nicht.
Den Code muss ich nun erst mal wieder zusammen fummeln.
Den habe ich gestückelt zum Testen.
Kann ich morgen posten.
Ist aber ziemlich lang
das spielt überhaupt keine Rolle was deine Lokale Zeit ist. Es gibt bestimmt auch in deiner Zeitzonen einen Stundenwechsel.
Und testweise hab ich dir in meinen Testsketch auch Zeitzonen mit 15 Minuten offsets eingetragen, damit du den Stunden-Wechsel testen kannst ohne auf deine volle Stunde warten zu müssen.
Die Bemerkung war nur wegen den Antworten.
Da kann es bei mir schon mal passieren das ich erst am nächsten Tag antworte.
Ging nicht ums Programm
Aber Danke für die Hilfe!