Hallo zusammen,
ich habe einen Arduino nano (168) mit einer rtc ds3231 am laufen.
Auf dem Arduino läuft eine Uhr in Software. Diese Softwarelösung läuft
natürlich nicht genau, je nach Arduino können das schon mal einige
Sekunden am Tag sein, deswegen ja auch die RTC.
Ich finde es nun aber sehr unschön den Sync nur alle 24h zu machen und
habe mir deswegen überlegt einen Korrekturfaktor für den Timer der
Softwarelösung zu errechnen. Der Faktor soll die abweichenden
Millisekunden pro Minute ausgleichen und sich ständig mit anpassen.
Also bei z.B. 15 s am Tag, wären es 10 ms/min die der Millisekundentimer
"ausgleichen" muss. Das macht er, indem einfach in der 59 s bis 990 oder
bis 1010 "gezählt" wird bis +00:01:00 kommt. Der Korrekturwert wird
jeden Tag morgens um 4 Uhr neu ermittelt, immer relativ zur aktuellen
Abweichung etwas addiert oder subtrahiert.
Das läuft alles soweit auch schon, für zu schnell gehende Arduino Uhren
und auch für zu langsam gehende. Es stellte sich auch heraus dass sich
der Korrekturfaktor selten ändert, selbst bei Temperaturschwankungen von
10 Grad... ist es dann wenn es hoch kommt mal 1 bis 2 ms/min...
Die Streuung unter den Arduino nanos (3-4€ Module) ist da schon echt
bemerkenswert. Aber was will man schon für den kleinen Preis erwarten,
das ist aber auch okay für mich, da ich so oder so eine RTC wollte.
Meine Frage an euch ist, ist das eine gute und "gängige" Methode oder
gibt es einfachere oder bessere Ansätze?
Danke! :-)
Das Synchronisieren fuehrt zu unstetiger Zeit. Entweder ist ein
Zeitpunkt doppelt oder er fehlt. Inwiefern kann man sich das leisten ?
Wielange darf so eine "schlechte" Phase dauern, wie oft darf sie
auftreten ?
Ich wuerde eine RTC plus einen Uhrenquarz an einem Timer empfehlen. Der
RTC uebernimmt den Teil ohne Strom, und der Uhrenquarz am Timer die Zeit
waehrend der Runtime. Der Uhrenquarz ist genauer wie jeder andere Quarz,
auch die RTC.
Ich habe allerdings auch schon mal, aus Interesse, keine Notwendigkeit,
auf den Uhrenquarz verzichtet und einen RC Oszillator im Controller auf
die RTC synchronisiert, heisst den RC Oszillator auf 8.0000MHz
abgeglichen, und die Zeit dann intern gemacht.
Wenn man auf low power gehen moechte, nimmt man einen Uhrenquarz und
synchronisiert den internen RC Oszillator darauf. Die Timer Routine wird
dann hinreichend selten aufgerufen.
Maddin schrieb:> nichts, wird ja gemacht, alle 24 h!> Ich verstehe den Hinweis nicht.
Was hindert dich daran z.b. alle 15 Min abzugleichen?
Viele RTC haben auch sowas wie einen Sekundenausgang. Denn kann man
wunderbar auf einen Interrupt legen und kann so zu jeder Sekunde recht
genau in der Software weiterspringen ohne das man den RTC komplett
abfragen muss.
Maddin schrieb:> Es stellte sich auch heraus dass sich> der Korrekturfaktor selten ändert, selbst bei Temperaturschwankungen von> 10 Grad... ist es dann wenn es hoch kommt mal 1 bis 2 ms/min...
Normale CPU-Quarze (Dickenscherschwinger) im MHz-Bereich sind
prinzipbedingt recht stabil gegenüber Temperaturschwankungen. Das liegt
am AT-Schnitt.
32kHz Quarze (Stimmgabelschwinger) sind dagegen nur eingeschränkt
temperaturstabil (Armband oder Zimmertemperatur).
Es sollte also reichen, den Korrekturwert einmalig zu ermitteln und im
EEPROM abzulegen. Z.B. durch Vergleich mit einem DCF-77 Signal über
längere Zeit.
Wieso eine Uhr in Software, wenn du doch eine RTC am uC hast?
Vergiss deine Software Uhr und lese nur die RTC Register, dann brauchst
du auch nichts synchronisieren.
Robert schrieb:> Wieso eine Uhr in Software, wenn du doch eine RTC am uC hast?
RTC haben leider oft nur eine Auflösung von 1s. Das ist für viele Zwecke
nicht zu gebrauchen. Man muß also intern z.B. 1ms Zählschritte erzeugen.
Ich hatte mal einen DS1994, der konnte auf 1/256s auflösen. Wird aber
nicht mehr hergestellt. Und ist die Batterie leer, muß der ganze Chip
getauscht werden.
Maddin schrieb:> "läuft natürlich nicht genau"
"natürlich" ist das nicht. Versuche herauszufinden, warum das nicht
genau ist, und ob die Abweichung vom RTC-Modul oder vom
16MHz-Arduino-Quarz kommt.
Oder ob's vielleicht ein Software-Bug in deiner Uhren-Implementation
ist.
Den solltest du dann besser beheben, anstatt ihn mit einem regelmäßigen
Uhrenvergleich zu übertünchen.
Εrnst B. schrieb:> 16MHz-Arduino-Quarz kommt
Ich meine der Arduino Nano hat meist nur einen Oszillator, keinen Quarz.
Insofern ist diese tägliche Rekalibrierung doch gar nicht schlecht,
oder?
LG, Sebastian
Sebastian schrieb:> Insofern ist diese tägliche Rekalibrierung doch gar nicht schlecht,> oder?
Bei mir würde täglich nicht reichen, weil es nachts kälter ist, als
tagsüber.
Maddin schrieb:> Meine Frage an euch ist, ist das eine gute und "gängige" Methode oder> gibt es einfachere oder bessere Ansätze?
Das ganze Konzept mit zwei Uhren ist aus meiner Sicht ziemlich
bescheuert.
Alternativen:
1. nimm nur und ausschließlich die externe RTC
2. versorge den Prozessor oder zumindest den verwendeten Timer mit einem
präzisen Takt, so dass die Software-Uhr genau ist
3. nimm einen Prozessor mit eingebauter RTC, passendem Uhrenquarz und
VBat Eingang für eine Pufferbatterie. Ja, auch sowas gibts.
Dann hast Du diese Probleme nicht.
fchk
Peter D. schrieb:> Man muß also intern z.B. 1ms Zählschritte erzeugen.
Dafür hat man beim ARM 'nen Systticktimer. Ein 1ms Timer oder
dergleichen wird immer benötigt.
man muss ja nicht zwingend alle Zeiten aus dem selben Takt ableiten. In
dem meisten Fällen wird wohl völlig OK sein, wenn man kurze Ereignisse
in nicht ganz genauen Millisekunden miss, während man Uhrzeiten aus der
RTC nimmt.
2022-12-01 12:06:01 Button was pressed for 231 ms
Irgend W. schrieb:> Viele RTC haben auch sowas wie einen Sekundenausgang.
Gute Idee! :-)
Peter D. schrieb:> Es sollte also reichen, den Korrekturwert einmalig zu ermitteln und im> EEPROM abzulegen.
Ja, das Gefühl habe ich auch.
Εrnst B. schrieb:> "natürlich" ist das nicht.
Warum?
Sebastian schrieb:> Ich meine der Arduino Nano hat meist nur einen Oszillator,
Eben.
Rüdiger B. schrieb:> Dann nehme doch einen TXCO für den 8MHz Takt.
Möchte den Nano nicht verbasteln.
Frank K. schrieb:> 1. nimm nur und ausschließlich die externe RTC
Dann müsste ich sie die ganze Zeit abfragen, ich meine mal in einem
Dallas Datenblatt gelesen zu haben, dass sie das nicht zwingend mögen.
Sollte dann ja schon mit min. 4 Hz passieren, eigentlich eher 10 Hz.
tnsz schrieb:> Peter D. schrieb:>> Man muß also intern z.B. 1ms Zählschritte erzeugen.
Das mache ich.
Steve van de Grens schrieb:> während man Uhrzeiten aus der> RTC nimmt.
Es geht nur um die Uhr, nichts weiter präzises. Nur eine Ihr die genau
laufen soll und ein paar Tasten hat.
Frank K. schrieb:> Das ganze Konzept mit zwei Uhren ist aus meiner Sicht ziemlich> bescheuert.
Ist aber weltweit im Einsatz. Jeder PC holt sich beim Einschalten die
Uhrzeit aus der RTC und zählt dann nur noch intern weiter.
Der Grund ist, auf internen Speicher kann viel schneller zugegriffen
werden, als z.B. über I2C auf eine RTC.
Auch kann eine SW-RTC automatisch auf Sommerzeit umstellen, was RTCs
üblicherweise nicht unterstützen.
Auch benutzt PC-Software oft intern 32Bit-Sekunden und rechnet nur zur
Anzeige in Menschenzeit um. Neben dem langsamen Lesen einer RTC, müßte
man daher noch jedesmal auf 32Bit-Sekunden umrechnen.
Es gibt allerdings auch einige moderne RTC-Chips, die gleich
32Bit-Sekunden zählen, statt im Sexagesimalsystem.
Maddin schrieb:> Dann müsste ich sie die ganze Zeit abfragen, ich meine mal in einem> Dallas Datenblatt gelesen zu haben, dass sie das nicht zwingend mögen.
Das betrifft ein ältere und billigere RTC.
Peter D. schrieb:> Frank K. schrieb:>> Das ganze Konzept mit zwei Uhren ist aus meiner Sicht ziemlich>> bescheuert.>> Ist aber weltweit im Einsatz. Jeder PC holt sich beim Einschalten die> Uhrzeit aus der RTC und zählt dann nur noch intern weiter.
Ja, ist so, weil der originale PC eben noch keine RTC hatte und der AT
möglichst kompatibel zum PC/XT sein musste. Das war der Grund.
> Der Grund ist, auf internen Speicher kann viel schneller zugegriffen> werden, als z.B. über I2C auf eine RTC.
Die IBM AT-RTC hing am ISA-Bus und war genauso direkt zu erreichen wie
Hauptspeicher. Hätte man also machen können.
> Auch kann eine SW-RTC automatisch auf Sommerzeit umstellen, was RTCs> üblicherweise nicht unterstützen.
Ja, das war eine der weniger geschickten Designentscheidungen. Die RTC
auf UTC laufen zu lassen macht viel weniger Probleme.
fchk
Maddin schrieb:> Rüdiger B. schrieb:>> Dann nehme doch einen TXCO für den 8MHz Takt.>> Möchte den Nano nicht verbasteln.
Dann füttere einen der Timereingänge T0 oder T1 mit einem präzisen Takt.
Wo ist das Problem?
fchk
Peter D. schrieb:> Ist aber weltweit im Einsatz. Jeder PC holt sich beim Einschalten die> Uhrzeit aus der RTC und zählt dann nur noch intern weiter.
Ok, aber einen PC kann man nicht mit einem kleinen mC vergleichen, der
nur die Uhrzeit anzeigen soll, und sonst nichts.
Maddin schrieb:> Es geht nur um die Uhr, nichts weiter präzises. Nur eine Ihr die genau> laufen soll und ein paar Tasten hat.
Ich habe auch vor ~3 Jahren an Uhr(en) gebastelt. Bei mir ist die DS1307
als RTC, die in Sekundentakt Interrupts erzeugt, wo sie dann ausgelesen
und auf dem LCD die Uhrzeit dargestellt wird. Auslesen in Sekundentakt
funktioniert und tut nicht weh.
Maddin schrieb:> Der Korrekturwert wird> jeden Tag morgens um 4 Uhr neu ermittelt, immer relativ zur aktuellen> Abweichung etwas addiert oder subtrahiert.
Ich würde das um 4:16 Uhr machen. Wieso? 4*60+16 = 256 passt genau in
8bit, somit ist der Überlauf maximal einfach zu detekteren.
Der DS3231 hat einen programmierbaren Takt-Ausgang.
Den auf 1024Hz einstellen, damit einen Interrupt auslösen, und im
Interrupt eine Variable hoch zählen.
Nach 1024 Interrups ist genau 1s vergangen.
So hat man eine Software-Uhr ,mit der selben Genauigkeit des DS3231, und
den Systick gibts kostenlos dazu.
Maddin schrieb:> Ich finde es nun aber sehr unschön den Sync nur alle 24h zu machen
Nach einem Tag weißt du dann ja, wie viel du korrigieren musst. Und dann
kannst du ja einfach im 1ms-Timertick nicht 1,000000 auf die Zeit
aufaddieren, sondern 1,000002 wenn die Uhr schneller sein soll, oder nur
0,999998 wenn sie langsamer sein soll. Man spart sich die
Fließkommarechnung und gewinnt Genauigkeit, wenn man das mit einer
Festkommazahl macht...
Maddin schrieb:> Das läuft alles soweit auch schon, für zu schnell gehende Arduino Uhren> und auch für zu langsam gehende.
Normalerweise benutzt man dann RTCLIB mit der Timelib..
Da der DS3231 bei zu vielen Abfragen auch Sekunden verliert kann man die
interne Uhr der Timelib / time.h mit setinterval(Sekunden) nur alle 20
Minuten mit nur einer Zeile und einer automatischen Abfrage synchen.
Der Frequenzausgang des DS3231 lohnt eigentlich nur für
Langezeitmessungen wie Stopuhren. Da kann man dann ein paar Stunden mit
1-3PPM auf 32khz schon recht genau messen.
Als pures AVR-GCC würde ich auch den Takteingang nehmen..
Ich habe mir da auch schonmal gedanken gemacht ;)
https://github.com/schuppeste/Precise-Time-Millis
Man kann ggf die Funktionen getrennt halten. Ein Timer-Tick von z.B. 1ms
läuft als Zähler stetig durch, ohne jede Synchronisation. Ob jemand
100ms wartet, oder 100,01ms, ist ja irrelevant. Unabhängig davon läuft
die RTC-Uhrzeit, die auch für Echtzeitevents wie "warten bis 15:30:00"
zur Verfügung steht.
Läuft der Tick auf einem RC-Oszillator, dann kann man z.B. bei den AVRs
den Justagewert der Oszillator-Hardware anhand der Differenz zwischen
den beiden Takten tunen. Damit ist der Tick genau und dennoch stetig,
weil sich nur die Periode geringfügig ändert.
Auch kann man die Anzahl Ticks pro Zeiteinheit des laufenden
Hires-Timers etwas anhand der Differenz zur RTC oder zu GPS variieren,
wenn man ihn selbst als Echtzeitquelle nutzen will. Auch das bleibt
stetig. Bei GPS empfiehlt sich ein grösser Abstand aufgrund dessen
Jitters.
Maddin schrieb:> Die Streuung unter den Arduino nanos (3-4€ Module) ist da schon echt> bemerkenswert. Aber was will man schon für den kleinen Preis erwarten ...
Der Preis interessiert die Streuung herzlich wenig.
Im Gegensatz zur RTC nutzen die meisten Arduinos keinen TCXO, sondern
einen Keramik Resonator. Die Dinger liegen bei einer Genauigkeit von
±0.5% und einer Stabilität von ±0.3%.
Gegenüber einem TCXO, der bei der DS3231 mit ±2ppm ... ±3.5ppm
spezifiziert ist (je nach Temperaturbereich), dürfen sich da schon
Unterschiede manifestieren, lt. Spezifikation etwa ein Faktor 1000.
Wolfgang schrieb:> dürfen sich da schon> Unterschiede manifestieren, lt. Spezifikation etwa ein Faktor 1000.
Wenn nicht mehr.. 5-10 Sekunden im Jahr bei Raumtemperatur waren meine
Erfahrung über 3 Jahre aus einer Zelle. Sogar bei 10 Stück DS3231 für
insgesamt 1,50€ aus China. (Während die beim großen C* für 8€ das Stück
gelistet waren)
Die Funktionen waren setsyncInterval und setsyncProvider der Time
Library. da braucht man nicht mehr viel selbst machen.
Beim der internen Uhr kommen soweit ich mich erinnere noch
Rundungsfehler dazu, da der von Millis abgeleitet wird.
(prx) A. K. schrieb:> Bei GPS empfiehlt sich ein grösser Abstand aufgrund dessen> Jitters.
Was hast du für einen GPS-Empfänger erwischt?
Der Jitter vom 1pps-Puls liegt meist im Bereich von wenigen 10ns.