ElectroDesignForgeElectroDesignForge
ElectroDesignForge

Seite finden

Leiterplatten-Werkzeuge
Bauteile
Schaltungsentwicklung
Anschlussbelegungen und Steckverbinder

Kabel

Dokumentation
Rechner

Umrechner

Pfeiltasten zum Navigieren · Eingabe zum Öffnen · Esc zum Schließen

GrundlagenSignale und Schnittstellen

Unix-Zeitstempel in eingebetteten Systemen, APIs und Datenbanken

Sensorzeitstempel mit RTC, NTP, monotonen Uhren, JSON und SQL entwerfen, einschließlich ESP32-Synchronisierungsbeispiel.

Ein belastbarer Sensordatensatz braucht Messwert, Zeitbezug und Unsicherheit. Unix-Zeit ermöglicht Interoperabilität, garantiert aber weder Genauigkeit noch Ereignisreihenfolge. Nutzen Sie Unix-Timestamp / Epoch-Konverter und die Grundlagen in Unix-Zeitstempel und Epoch-Zeit verstehen.

RTC und Systemuhr

Eine Hardware-RTC hält Kalender oder Zähler während CPU-Schlafphasen, oft mit einer Pufferbatterie. Sie ist nicht automatisch auf UTC eingestellt oder synchronisiert. Die Systemuhr ordnet einer Hardwarezeitbasis eine Epoche zu. Nach Versorgungsausfall muss die Gültigkeit der RTC geprüft werden; ihr Standarddatum ist keine Messung.

STM32, ESP32 und eingebettetes Linux

STM32-RTC, Sicherungsdomäne und Subsekundenfunktionen unterscheiden sich je Familie: Referenzhandbuch und ST AN4759 sind maßgeblich. Ein universelles Unix-Register existiert nicht. ESP-IDF kombiniert RTC- und hochauflösende Zeitgeber gemäß Konfiguration. Linux stellt CLOCK_REALTIME und monotone Uhren bereit. Prüfen Sie libc und ABI unabhängig von der CPU-Breite.

NTP und SNTP

NTP schätzt Zeitversatz und Netzlaufzeit; SNTP vereinfacht den Client. Asymmetrische Laufzeiten bleiben eine Fehlerquelle. NTP-Epoche und Ärenfelder entsprechen nicht Unix-Sekunden; die Protokollbibliothek übernimmt die Umrechnung. Speichern Sie Synchronisierungszustand, Alter und Unsicherheit. Ein Zeitsprung wirkt sofort, während eine schrittweise Korrektur vorübergehend die Taktrate ändert.

Echtzeituhr und monotone Uhr unterscheiden

Die zivile Systemzeit beantwortet die UTC-Datumsfrage und kann korrigiert werden. Ein monotoner Zähler misst Laufzeit seit einem beliebigen Ursprung und ist keine UTC-Angabe. Er kann beim Neustart zurückgesetzt werden; Schlafphasen werden je nach Uhr unterschiedlich behandelt. Verwenden Sie monotone Fristen für Zeitüberschreitungen und einen separaten UTC-Bezug für geräteübergreifende Vergleiche.

Sensorerfassung richtig zeitstempeln

Erfassen Sie die Zeit nahe am relevanten ADC-Abtastwert oder Interrupt. Sende- und Serverempfangszeiten enthalten Warteschlangen und Wiederholungen und gehören in eigene Felder. Für Messblöcke sind Blockursprung, Abtastperiode und Sequenznummer sinnvoll; berücksichtigen Sie Drift. Der Abtastleitfaden erläutert die Signalperspektive.

Ereignisprotokolle und Telemetrie

Gerätekennung, Startkennung und Sequenznummer verhindern, dass wiederholte UTC-Werte nach einer Rückwärtskorrektur Datensätze überschreiben. Unterscheiden Sie gemessene und rekonstruierte Zeiten. Eine reine UTC-Sortierung garantiert keine kausale Reihenfolge zwischen Geräten mit überlappenden Unsicherheiten.

Einheit und Fehlerbudget

Zeitstempeleinheit1 s1700000000 s
Sekunden (s)11700000000
Millisekunden (ms)10001700000000000
Mikrosekunden (µs)10000001700000000000000
Nanosekunden (ns)10000000001700000000000000000

Sekunden eignen sich für grobe Termine, Millisekunden häufig für Web-Telemetrie, Mikrosekunden für geeignete Erfassung und Nanosekunden für entsprechende Hardware. Auflösung, Wiederholbarkeit und Genauigkeit sind verschieden. Ein freier Fehler von 20 ppm summiert sich in nominalen 24 Stunden auf etwa 1,728 s. Temperatur und Alterung verändern diesen Wert.

REST und JSON

{
  "timestamp_ns": "1700000000123456789",
  "captured_at": "2023-11-14T22:13:20.123456789Z",
  "time_quality": "synced",
  "uncertainty_ms": 20,
  "boot_id": "device-session-42",
  "sequence": 17
}

Beschreiben Sie Epoche, Einheit, Vorzeichen und Bereich im Schema. Große Zeitwerte sollten für Binary64-Clients als Dezimalzeichenfolgen übertragen werden. BigInt lässt sich nicht direkt mit JSON.stringify serialisieren. timestamp_ns benennt die Einheit ausdrücklich. Unbekannte UTC-Zeit wird null mit Qualitätsangabe, keine scheinbar gültige Zeit um 1970.

ISO 8601 und RFC 3339

Verwenden Sie einen dokumentierten RFC-3339-Vertrag mit Z oder numerischem Offset und festgelegter Nachkommagenauigkeit. 2023-11-14T22:13:20Z und 2023-11-14T23:13:20+01:00 sind identisch. Eine bloße Ortszeit bestimmt kein UTC. Ein Offset enthält nicht die zukünftigen Regeln von Europe/Paris.

SQL-Datenbanken

CREATE TABLE sensor_measurement (
    device_id text NOT NULL,
    boot_id text NOT NULL,
    sequence bigint NOT NULL,
    captured_at timestamptz,
    monotonic_us bigint NOT NULL,
    time_quality text NOT NULL,
    temperature_c double precision NOT NULL,
    PRIMARY KEY (device_id, boot_id, sequence)
);

INSERT INTO sensor_measurement VALUES ('sensor-1', 'boot-42', 17,
    TIMESTAMPTZ '2023-11-14T22:13:20.123456Z', 9812370, 'synced', 23.625);

Das Beispiel ist PostgreSQL-spezifisch. timestamptz speichert einen Zeitpunkt und stellt ihn in der Sitzungszone dar; die ursprüngliche IANA-Kennung bleibt nicht erhalten. Speichern Sie diese bei Bedarf separat. Die Zeitstempelauflösung beträgt Mikrosekunden; exakte Nanosekunden brauchen ein zusätzliches Ganzzahl- oder Dezimalfeld. Andere SQL-Systeme besitzen andere Bereiche und Regeln. Zeitindex und Datensatzidentität haben unterschiedliche Aufgaben.

UTC und örtliche Zeitpläne

Speichern Sie Ereigniszeitpunkte in UTC. Eine tägliche Regel um 08:00 in Paris benötigt hingegen Ortszeit und IANA-Zone. Definieren Sie das Verhalten bei übersprungenen oder wiederholten Zeiten. 86400 addierte Unix-Sekunden garantieren nicht dieselbe örtliche Uhrzeit am nächsten Kalendertag.

time_t und langlebige Produkte

Leiten Sie time_t nicht aus sizeof(void*) ab. Ein 32-Bit-Sekundenfeld erreicht 2038 auch in einem teilweise 64-bittigen System. ESP-IDF verwendet seit v5.0 vorzeichenbehaftetes 64-Bit-time_t; ältere Firmware und Übertragungsfelder können enger bleiben. Prüfen Sie printf-Formate, Datenbankspalten, Bootloader, RTC-Treiber und OTA-Migrationen.

ESP32-Beispiel mit NTP und Sensorwert

Der ESP-IDF-5.x/6.x-Code wird einmal nach initialisiertem esp-netif und bestehender WLAN- oder Ethernet-Verbindung aufgerufen. Der Kartentreiber übergibt log_sensor eine endliche Temperatur. Die erste Synchronisierung wartet höchstens 15 Sekunden; jede Erfassung erzeugt JSON.

#include <stdbool.h>
#include <stdint.h>
#include <inttypes.h>
#include <stdio.h>
#include <sys/time.h>
#include "freertos/FreeRTOS.h"
#include "esp_netif_sntp.h"
#include "esp_timer.h"
#include "esp_random.h"

static bool clock_synced;
static int64_t last_sync_us;
static uint32_t boot_id;
static uint64_t sequence;

void ntp_after_network_ready(void) {
    boot_id = esp_random();
    esp_sntp_config_t config = ESP_NETIF_SNTP_DEFAULT_CONFIG("pool.ntp.org");
    esp_netif_sntp_init(&config);
    clock_synced = esp_netif_sntp_sync_wait(pdMS_TO_TICKS(15000)) == ESP_OK;
    if (clock_synced) last_sync_us = esp_timer_get_time();
}

void log_sensor(double temperature_c) {
    int64_t monotonic_us = esp_timer_get_time();
    struct timeval tv;
    bool valid = clock_synced && monotonic_us - last_sync_us < INT64_C(3600000000)
                 && gettimeofday(&tv, NULL) == 0;
    printf("{\"boot_id\":\"%08" PRIx32 "\",\"sequence\":%" PRIu64
           ",\"monotonic_us\":\"%" PRId64 "\",\"timestamp_us\":",
           boot_id, sequence++, monotonic_us);
    if (valid) {
        int64_t utc_us = (int64_t)tv.tv_sec * INT64_C(1000000) + tv.tv_usec;
        printf("\"%" PRId64 "\"", utc_us);
    } else printf("null");
    printf(",\"time_quality\":\"%s\",\"temperature_c\":%.3f}\n",
           valid ? "synced" : "unsynced", temperature_c);
}

timestamp_us und monotonic_us sind Dezimalzeichenfolgen. Bei fehlender Synchronisierung bleibt UTC null und die Reihenfolge verfügbar. Die einstündige Gültigkeitsgrenze ist eine Beispielrichtlinie, keine Genauigkeitsgarantie. Automatische spätere Synchronisierungen erneuern in diesem Beispiel nicht das Vertrauen: Produktionscode sollte last_sync_us über eine Benachrichtigung aktualisieren, gemeinsame Zustände schützen und Netzwerkfehler behandeln. Die zufällige 32-Bit-Startkennung ist illustrativ; kritische Identitäten brauchen einen persistenten Zähler oder eine ausreichend starke Kennung.

Neustart, Drift und Synchronisationsverlust

Ein Neustart eröffnet eine neue monotone Zeitlinie. Verbinden Sie diese nicht ungeprüft mit dem vorherigen Start. Erhöhen Sie bei Netzausfall die Unsicherheit anhand des Oszillatorbudgets und des letzten zuverlässigen Bezugs. Eine gepufferte RTC kann helfen, benötigt aber eine Qualitätskennzeichnung. Große Korrekturen sollten beobachtbar bleiben, ohne historische Daten still zu verändern.

Entwurfsregeln und Tests

  • Epoche, Einheit und Vorzeichen an allen Grenzen ausdrücklich definieren.
  • UTC für Ereignisse, monotone Uhren für Fristen verwenden.
  • Sequenz, Startkennung und Synchronisationsqualität erhalten.
  • Kaltstart ohne Netz, leere RTC-Batterie, Rückwärtskorrektur, Zeitumstellung und Zahlenbereichsgrenzen testen.
  • Zeitzonendaten für zukünftige örtliche Termine aktuell halten.

Technische FAQ

Garantiert NTP Mikrosekundengenauigkeit?

Nein. Laufzeitasymmetrie, Betriebssystemplanung und Erfassungslatenz bleiben bestehen. Messen Sie den gesamten Signalweg.

Reicht ein monotoner Zähler für UTC?

Nein. Er braucht eine Zuordnung zu einer UTC-Referenz mit Driftmodell, Alter und Unsicherheit; ein Neustart begrenzt diese Zuordnung.

Soll die lokale Zeit gespeichert werden?

UTC für Ereignisse, eine zusätzliche Zone für zivile Regeln oder den ursprünglichen Kontext. Die Anzeige kann anschließend lokal erfolgen.

Werkzeuge und Primärquellen

Unix-Timestamp / Epoch-Konverter · Unix-Zeitstempel und Epoch-Zeit verstehen · Oszillatortoleranz.

Verwandte Werkzeuge und Leitfäden

Quarz-Lastkondensator-Rechner · Vollständigen Entwurfsleitfaden lesen