Wie erhalte ich eine genaue Uhrzeit?


16

Ich habe eine Uhr mit einem Arduino gemacht, aber die Zeit scheint zu driften. Mir ist das Rollover- Problem bekannt. die uhr scheint im laufe einer woche um etwa 15 minuten zu driften.

Ich verwende eine benutzerdefinierte Platine mit diesem Resonator von Digi-Key. Der Code liest die Funktion millis () am Anfang jeder Schleife und arbeitet ab diesem Wert.

Meine Frage ist: Wie kann ich mit einem Arduino die Zeit genau genug messen, um eine befahrbare Tischuhr zu machen?


3
Die Millisekundenfunktion wird mit Daten von einem Interrupt versorgt, für dessen Ausführung einige Taktzyklen erforderlich sind. Dies fügt jedem Tick eine winzige Zeit hinzu.
TheDoctor

3
@TheDoctor: Das ist falsch. Der Interrupt verlangsamt nicht den Hardware-Timer, der ausgeführt wird millis().
Edgar Bonet

Antworten:


15

Hinweis: Obwohl meine Antwort akzeptiert wurde und eine höhere Punktzahl aufweist, lesen Sie unbedingt die großartige Antwort von Edgar Bonet, wie Sie Ihren Arduino dazu bringen, die Zeit ohne RTC zu halten.

Ich habe die Echtzeituhr DS1307 sehr erfolgreich eingesetzt. Hier ist ein Link zu seinem Datenblatt .

Im Folgenden sind einige seiner Funktionen aufgeführt:

  • Es verwendet eine IC-Schnittstelle für die Kommunikation mit Arduino, wodurch es einfach ist, mit den richtigen Bibliotheken (im Internet verfügbar) zu programmieren.

  • Es ist über die SCL- und SDA-Pins (analog A4 und A5) mit Arduino verbunden und verwendet daher nur 2 Pins.

  • Zum Ausführen sind nur sehr wenige externe Komponenten erforderlich.

  • Es kann an eine Knopfzellenbatterie angeschlossen werden, sodass die Zeit auch dann erhalten bleibt, wenn der Arduino ausgeschaltet ist. Im Energiesparmodus hält der Knopfzellenakku jahrelang.

  • Es driftet sehr wenig (in meinem Fall driftet es nur einige Sekunden pro Woche).

  • Es ist nicht sehr teuer.

Wenn Sie nicht vorhaben, eine RTC zu verwenden, können Sie den Kristall ersetzen, der üblicherweise verwendet wird, um Arduino eine Uhr für ein Kristalloszillatormodul wie dieses von Farnel oder dieses andere zu liefern . Sie werden in 4-Pin-Gehäusen wie in den folgenden Abbildungen geliefert. Sie erzeugen eine viel genauere Uhr für Ihren Arduino.

Kristalloszillatorbild Kristalloszillatorbild Kristalloszillatorbild

Beide genannten Module haben Toleranzen von 50 ppm und arbeiten mit 5V.

Um es noch einmal deutlich zu machen, sind diese Quarzoszillatormodule nicht mit regulären 2-Pin- Quarzen wie diesen zu verwechseln . Diese sind zum Beispiel Teil der Schaltung externer Uhren für MCUs.

Kristalloszillator


Ist der DS1302 gut genug oder soll ich auf den DS1307 umsteigen?
Kelly S. Französisch

14

Sie benötigen keine Echtzeituhr, um eine Uhr zu bauen: Der ATmega-Chip verfügt über die gesamte Hardware, die zur Erfüllung der Aufgaben der Echtzeituhr selbst erforderlich ist. Hier ist, wie:

  1. Holen Sie sich einen 32768 Hz-Uhrenkristall: Kaufen Sie ihn oder bauen Sie eine alte Uhr auseinander. Diese speziell für die Zeitmessung entwickelten Kristalle weisen eine extrem geringe Temperaturdrift auf. Sie würden auch eine davon benötigen, wenn Sie einen RTC-Chip verwenden möchten.

  2. Konfigurieren Sie die Sicherungen Ihres ATmega so, dass der 8-MHz-RC-Oszillator ausgeschaltet ist. Dies wird Ihre millis()Funktion fürchterlich ungenau machen und auch die Pins XTAL1 und XTAL2 freigeben.

  3. Verbinden Sie den Uhrenkristall mit den Pins TOSC1 und TOSC2. Dies sind die gleichen Pins wie bei XTAL1 und XTAL2 (9 und 10 beim 328P). Die verschiedenen Namen bedeuten unterschiedliche Funktionen.

  4. Konfigurieren Sie den Timer / Zähler 2 für asynchronen Betrieb, normalen Zählmodus, Prescaler auf 128 und aktivieren Sie den Timer-Überlauf-Interrupt.

Jetzt erhalten Sie einen TIMER2_OVF-Interrupt mit einer sehr konstanten Rate von einmal pro Sekunde. Sie müssen die Uhrzeitanzeige im ISR nur um eine Sekunde vorstellen. Zwischen den Interrupts können Sie die MCU in einen sehr tiefen Schlaf versetzen (Energiesparmodus: nur Timer / Counter 2) und jahrelang auf ein paar AA-Zellen laufen lassen. Es sei denn, das Display ist offensichtlich stromhungrig.

Genau das habe ich getan, um meine 24-Stunden-Einhand-Wanduhr zu bauen . Dieser Link verweist nun auf die englische Übersetzung der Originaldokumentation in Französisch.

Quarzkalibrierung

Wenn Sie Ihren Quarz nicht kalibrieren, können Sie eine signifikante Abweichung erwarten, in der Regel einige Sekunden pro Woche . Die Driftrate hängt von der Streukapazität der Leiterbahnen ab, die den Kristall mit der MCU verbinden. Im Prinzip könnte es durch Hinzufügen einer zusätzlichen, fein abgestimmten Kapazität entfernt werden. Es ist erwähnenswert, dass Sie das gleiche Driftproblem mit einer RTC haben würden.

Wenn Sie mit dieser Genauigkeit zufrieden sind, dann leben Sie damit und seien Sie glücklich. Wenn Sie jedoch die Drift messen möchten, werden Sie feststellen, dass sie sehr stabil ist. Sie können dies dann in der Software problemlos kompensieren und eine Genauigkeit von wenigen Sekunden pro Jahr erzielen .

Der Algorithmus zur Korrektur der Drift ist sehr einfach. Aus der gemessenen Drift ermitteln Sie die genaue Verzögerung zwischen den Interrupts, die ungefähr 10 9  Nanosekunden betragen sollte. Dann gilt Folgendes:

#define ONE_SECOND    1000000000  // in nanoseconds
#define ONE_INTERRUPT  999993482  // for example

ISR(TIMER2_OVF_vect)
{
    static uint32_t unaccounted_time;

    unaccounted_time += ONE_INTERRUPT;
    while (unaccounted_time >= ONE_SECOND) {
        advance_display_by_one_second();
        unaccounted_time -= ONE_SECOND;
    }
}

Im obigen Beispiel ist der Quarz etwas zu schnell, und die Software gleicht dies aus, indem alle paar Tage ein Häkchen „fehlt“. Wenn der Quarz zu langsam wäre, würde derselbe Code stattdessen alle paar Tage ein Mal doppelt angeklickt.

Diese Art der Kalibrierung könnte auch für eine RTC durchgeführt werden, ist jedoch erheblich komplexer, da die RTC die Zeit in einer aufgeschlüsselten Form anzeigt, die sich für arithmetische Operationen naturgemäß nicht eignet.


Wow, das ist ein wirklich schickes Design! Ich mag es wirklich, wie Sie genug Fotos gemacht haben, um das Design klar zu machen, auch für uns dummen Amerikaner.
John Walthour

2
@ JohnWalthour: Danke! Jetzt ermutigen Sie mich, eine Übersetzung zu schreiben. :-)
Edgar Bonet

2
@ JohnWalthour: Fertig! Der Link verweist nun auf die englische Übersetzung.
Edgar Bonet

Nur um klar zu sein: Wenn Sie sagen, dass der ATmega-Chip über die erforderliche Hardware verfügt, stimmt dies nicht ganz, wenn Sie einen neuen Kristall benötigen. Ich denke, Ihre Lösung ist schlau und ich bin nicht über dem Ersetzen des Kristalls, aber ich war ein bisschen verwirrt, als Sie sagten, ich brauche keine Hardware und dreh mich dann um und sage, ich muss ein Stück Hardware ersetzen.
Kelly S. French

@ KellyS.French: Mein Satz war "Der ATmega-Chip hat die gesamte Hardware, die benötigt wird , um die Aufgaben des RTC selbst zu erfüllen " (Hervorhebung hinzugefügt). Aber dann ist es wichtig zu beachten, dass die meisten RTCs, einschließlich der allgegenwärtigen DS1307, einen externen Kristall benötigen, um zu funktionieren. Das ATmega ist nicht anders: Es hat alles, was benötigt wird, um die RTC selbst zu ersetzen , aber nicht, um den Kristall zu ersetzen, den Sie sowieso an die RTC anschließen müssten. Bitte beachten Sie, dass ein RTC - Modul ist mehr als nur eine RTC, wie es den Kristall enthält.
Edgar Bonet,

6

Der von Ihnen angegebene Resonator hat eine Stabilität von 0,3%, wobei der Kristall oder der Kristalloszillator (wie von Ricardo erwähnt) 50 ppm beträgt. Vielfach stabiler. Ganz zu schweigen von der Temperaturdrift des Resonators. Erhitzen durch Sonnenlicht wird es ändern. Ein Resonator sollte daher nicht dazu verwendet werden, die Zeit über längere Zeiträume zu halten.

Wenn Sie also entweder einen Kristall oder einen Kristalloszillator verwenden, erhalten Sie das, was Sie wollen. Verwenden Sie es entweder am ATmega und setzen Sie die entsprechenden Sicherungen ein, oder verwenden Sie eines, das an eine Echtzeituhr angeschlossen ist.


Wo 50 ppm ist 0,005% Stabilität?
Matthew G.

Ich verallgemeinere diese Spezifikation, um die Antwort kurz zu halten. Beachten Sie die Stabilität. habe eine viel größere toleranz und kann recht dran sein. Wie John W erlebt. "das richtige teil für den richtigen job"
mpflaga

Oh, ich war nur neugierig auf die Terminologie @mpflaga ... neu für mich.
Matthew G.

4

Wenn Sie keine zusätzliche Hardware wie eine Echtzeituhr (z. B. DSDS1307) verwenden möchten, können Sie die Zeitgenauigkeit erheblich verbessern, indem Sie alle nicht verwendeten Interrupts deaktivieren. Standardmäßig sind in Arduino-Skizzen verschiedene Interrupt-Routinen aktiviert und werden häufig nicht für Ihre Skizze verwendet. Der schnellste Weg, um herauszufinden, ob Sie darauf verzichten können, indem Sie versuchen, sie durch Ausgabe zu deaktivierennoInterrupts();


3
-1 (obwohl dies -4 verdient), weil: 1. Sofern Sie diese nicht tatsächlich benötigen, sind alle Interrupts standardmäßig deaktiviert, mit Ausnahme von TIMER0_OVF, das für die Zeitmessung benötigt wird. 2. Die zeitliche Genauigkeit der Arduinos wird hauptsächlich durch die Qualität des Resonators begrenzt. 3. Interrupts beeinflussen nicht die Genauigkeit , millis()wenn Sie verwalten mehr als eine Millisekunde zu einer Zeit verbringen sie Wartung, in welchem Fall Sie andere Probleme haben ... 4. Deaktivieren von Interrupts mit noInterrupts()verhindern millis()aus halten an Board !
Edgar Bonet

2

Ich verstehe, dass ein Großteil des Geistes mit Arduino sparsam ist und gelegentlich durch ein Problem stapft. Ich verwende Arduino (und jetzt chipKIT, da es das 10-fache des RAM und die 10-fache der Taktrate hat) für meinen Arbeitsplatz und ich benötige "Peripheriefunktionen", um auf dem neuesten Stand zu sein und so schnell wie möglich zu arbeiten.

Ich benutze die funkenfrohe Echtzeituhr in einem meiner Projekte und bin sehr zufrieden damit. Sie haben auch eine "Dead on" -Variante .

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.