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?
millis()
.Antworten:
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.
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.
quelle
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:
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.
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.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.
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:
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.
quelle
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.
quelle
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 deaktivieren
noInterrupts();
quelle
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 mitnoInterrupts()
verhindernmillis()
aus halten an Board !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 .
quelle