Sensor auslesen mittels Uhrzeit

Guten Tag zusammen,

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.

Für eine kleine Hilfe wäre ich dankbar.

Hallo vlakvark1

Und herzlich Willkommen im besten Arduinoforum der Welt :slight_smile:

Es empfiehlt sich, die Verwendung einer Echtzeituhr (Real-Time Clock - RTC) zu studieren.

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.

Ja, das habe ich mir auch gedacht.
Daher hole ich die Zeit aus dem Internet und verwende einen D1 mini pro.
Aber das löst nicht mein Problem.

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.

Ich habe das Thema unter XY-Problem abgelegt.

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.

Wenn du jetzt deinen Code zeigst, bekommst du bestimmt noch Verbesserungsvorschläge: De ersten habe ich auch schon ohne Code:

ist aufwendig und fehleranfällig. Besser: Wenn Stunde != letzterStunde benutzen.

Eventuell musst Du noch eine Maßnahme ergreifen damit nicht mehrfach auf die SD geschrieben wird während die Sekunden 0 sind.

wart' noch bis kurz nach 11 dann poste ich ein Beispiel.

edit:

dieser Code enthält 3 Timer (trigger) für Events.

/*
  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

Nur mal so am Rande, wir sind 6h auseinander!

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 :slight_smile:
Aber Danke für die Hilfe!

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.