Ich verwende RTClib.h und TimeLib.h mit einem Uno.
Ich habe seit Tagen Probleme zum Verständnis der verschiedenen verfügbaren RTC-Bibliotheken und ihrer Verwendung mit der Arduino-Zeitbibliothek.
Frage 1 .
Wenn ich nicht jedes Mal durch die Schleife ein neues now () -Objekt erstellen möchte, wie synchronisiere ich die Zeitbibliothek alle x Sekunden mit der RTC? Jedes Mal, wenn ich versuche, die RTClib-Funktion now.hour now.minute usw. zu verwenden, muss ich DateTime now = RTC.now () verwenden, um das now () -Objekt zu erstellen.
Gibt es eine entsprechende Funktion in RTCLib als setSyncProvider (RTC.get) in der DS1307RTC-Bibliothek?
Gibt es ein Äquivalent zu setSyncInterval (5000)
Frage 2 .
Welche RTCLib soll ich aufrufen? In Beispielen werden mehrere verwendet:
< RTClib.h >
“ RTClib “ unter Verwendung von Anführungszeichen
< RTCLib.h > mit Großbuchstaben L
und manchmal auch mit einem der folgenden Elemente:
RTC_DS1307 RTC
oder RTC_DS1307 rtc
oder RTC_DS3231 rtc
Frage 3
a. Sind tmElements_t tm Teil der DS1307RTC-Bibliothek?
b. Sind diese tm.Hour tm.Minute von der RTC?
c. Gibt es ein Äquivalent in der RTClib.h?
Und schließlich habe ich unten einen Code gepostet, um meine Verwendung zu zeigen:
#include "RTClib.h" #include <Wire.h> #include <TimeLib.h> RTC_DS1307 RTC; void setup() { Serial.begin(9600); Wire.begin(); //sets up the I2C RTC.begin(); //initializes the I2C to the RTC if (! RTC.begin()) { Serial.println("Couldn"t find RTC"); } // Set the RTC Time to 5:10:30 Nov 3 2020 RTC.adjust(DateTime(2020,11,3,5,10,30)); //Set Arduino Time Library different than RTC time to see which is which setTime(9, 27, 05, 14, 07, 2015); } void loop() { /* // How do I sync Time Library to RTC after x seconds? setSyncProvider(RTC.get); // This is in the DS1307RTC.h Library setSyncInterval(5000); // Are there such functions in RTClib ? */ DateTime now = RTC.now(); // Pulls RTC time into now(). Does not sync with Time Library // Do not want to do this every loop. //Print RTC Time Serial.println(); Serial.print("RTC now.hour "); Serial.println(now.hour()); Serial.print("RTC now.minute "); Serial.println(now.minute()); Serial.print("RTC now.second: "); Serial.println(now.second()); Serial.println(); Serial.println(); //Print Arduino TimeLib Time Serial.print("Time Lib Hour: "); Serial.print(hour()); Serial.println(); Serial.print("Time Lib Min: "); Serial.print(minute()); Serial.println(); Serial.print("Time Lib Sec: "); Serial.print(second()); Serial.println(); Serial.println(); delay(1000); }
Aktualisiert am 5. November 2020
Ich glaube, ich verstehe es fast. Bitte lassen Sie mich wissen, ob dieser Code das tut, was ich denke, insbesondere:
Im Setup:
Stellen Sie die RTC auf 5:10:30 ein.
Setzen Sie die Zeitbibliothek auf 9:27:05 mit setTime ().
Setzen Sie die Zeitbibliothek jetzt mit DateTime auf RTC-Zeit (überschreiben Sie 9:27:05)?
Setzen Sie die Variablen der Zeitbibliothek mit tm.Hour = now auf RTC. Stunde usw.
In Schleife:
Alle 5 Sekunden aktualisieren Stunde (), Minute () Sekunde () mit der RTC-Zeit.
Jede Schleife aktualisiert tm.hour mit Stunde () usw.
Ich weiß, dass es immer noch nicht richtig ist, da die seriellen Ausdrucke tm.Hour, tm.Minute abwechselnd jede Schleife wie unten gezeigt anzeigen.
#include "RTClib.h" #include <Wire.h> #include <TimeLib.h> RTC_DS1307 RTC; time_t time_provider() { return RTC.now().unixtime(); } tmElements_t tm; //part of Time Library void setup() { //setSyncProvider(time_provider); Serial.begin(9600); Wire.begin(); //sets up the I2C RTC.begin(); //initializes the I2C to the RTC if (! RTC.begin()) { Serial.println("Couldn"t find RTC"); } // Set the RTC Time to 5:10:30 Nov 3 2020 RTC.adjust(DateTime(2020,11,3,5,10,30)); //Set Arduino Time Library different than RTC time 9:27:05 setTime(9, 27, 05, 14, 07, 2015); //Setting Time Library to RTC time DateTime now = RTC.now(); tm.Hour = now.hour(); tm.Minute = now.minute(); tm.Second = now.second(); } void loop() { setSyncProvider(RTC.now); setSyncInterval(5000); //Time Library time updates to RTC every 5 seconds tm.Hour = hour(); tm.Minute = minute(); tm.Second = second(); Serial.print("tm.Hour: "); Serial.print(tm.Hour); Serial.println(); Serial.print("tm.Minute: "); Serial.print(tm.Minute); Serial.println(); Serial.print("tm.Seconds: "); Serial.print(tm.Second); Serial.println(); Serial.println(); delay(1000); }
Serielle Drucke:
tm.Hour: 5 tm.Minute: 34 tm.Seconds: 56 tm.Hour: 18 tm.Minute: 0 tm.Seconds: 0 tm.Hour: 5 tm.Minute: 34 tm.Seconds: 56 tm.Hour: 18 tm.Minute: 0 tm.Seconds: 0 tm.Hour: 5 tm.Minute: 34 tm.Seconds: 56 tm.Hour: 18 tm.Minute: 0 tm.Seconds: 0
Antwort
Lassen Sie mich zunächst einige Hintergrundinformationen zu diesen Bibliotheken geben.
Die Zeitbibliothek verwendet millis()
für Zeitmessung. Da dies einer erheblichen Abweichung unterliegen kann, bietet es eine Möglichkeit zur periodischen Synchronisierung mit einem externen Zeitanbieter. Daher sind die Funktionen setSyncProvider()
und setSyncInterval()
.
RTClib als Schnittstelle für eine RTC gedacht. Es bietet keine eigene Zeitmessung: Sie erhalten die aktuelle Zeit, indem Sie eine RTC über die now()
-Methode abfragen.
Diese beiden Bibliotheken können jede gut ergänzen andere, da RTClib als Zeitanbieter für die Zeitbibliothek verwendet werden kann:
// Provide the RTC time to the Time library. time_t time_provider() { return RTC.now().unixtime(); } void setup() { // ... setSyncProvider(time_provider); }
Wenn ich kein neues now () -Objekt erstellen möchte […]
Es wird tatsächlich als DateTime
-Objekt bezeichnet.
Gibt es ein Äquivalent [zu
tmElements_t
] in der RTClib
Ja, die DateTime
-Klasse . Beachten Sie, dass im Gegensatz zur tmElements_t
-Struktur die Datenfelder von DateTime
dies nicht sind public, und Sie müssen Accessoren verwenden, um sie abzurufen: year()
, month()
, day()
…
Alternative Zeitnehmungsmethode
Da Sie ein Arduino Uno verwenden, gibt es möglicherweise eine dritte Zeitmessmethode möchte berücksichtigen. Anstatt die RTC bei jeder Schleifeniteration (RTClib) abzufragen oder die RTC-Messwerte mit millis()
(Zeitbibliothek) zu interpolieren, können Sie einen 1-Hz-Ausgang der RTC an einen Interrupt-Pin weiterleiten. und zähle die Sekunden im ISR. Der avr-libc-Timing-Code dient zur Zeitmessung auf diese Weise. Alles läuft auf Folgendes hinaus:
// Initialize the system time from the RTC. set_system_time(RTC.now().secondstime()); // Keep the time in sync using the 1 Hz output of the RTC. pinMode(pin1Hz, INPUT_PULLUP); attachInterrupt(digitalPinToInterrupt(pin1Hz), system_tick, FALLING);
Weitere Informationen finden Sie in der Beispielskizze Interrupts1Hz.ino wird mit RTClib bereitgestellt.
Bearbeiten Sie 1 : Beantworten eines Kommentars
Mit welchem Pin verbindet sich [der Arduino-Interrupt-Pin] auf der RTC?
Dies hängt von der verwendeten RTC ab. Ich gehe davon aus, dass es sich um einen DS1307 handelt, wie aus dem Code in Ihrer Frage hervorgeht. Sehen Sie sich das -Datenblatt der RTC an.Auf Seite 6 finden Sie eine Tabelle mit dem Titel „Pin-Beschreibung“. Aus dieser Tabelle:
Pin : 7
name : SQW / OUT
-Funktion : Rechteckwellen- / Ausgangstreiber. Wenn das SQWE-Bit auf 1 gesetzt ist, gibt der SQW / OUT-Pin eine von vier Rechteckwellenfrequenzen (1 Hz, 4 kHz, 8 kHz, 32 kHz) aus. Der SQW / OUT-Pin ist ein offener Drain und erfordert einen externen Pullup-Widerstand. SQW / OUT arbeitet entweder mit V CC oder V BAT. Die Pullup-Spannung kann unabhängig von der Spannung an V CC bis zu 5,5 V betragen. Wenn dieser Pin nicht verwendet wird, kann er frei bleiben.
Wenn Sie ein RTC -Modul verwenden, müssen Sie eine Abbildung erstellen Dort, wo dieser Pin am Anschluss des Moduls freigelegt ist.
In jedem Fall müssen Sie den 1-Hz-Rechteckwellenausgang mit
RTC.writeSqwPinMode(DS1307_SquareWave1HZ);
Bearbeiten Sie 2 : Kommentar zum Update der Frage:
// Set the RTC Time to 5:10:30 Nov 3 2020 RTC.adjust(DateTime(2020,11,3,5,10,30));
Richtig.
// Set Arduino Time Library different than RTC time 9:27:05 setTime(9, 27, 05, 14, 07, 2015);
Richtig. Datum ist der 14.07.2015.
// Setting Time Library to RTC time DateTime now = RTC.now(); tm.Hour = now.hour(); tm.Minute = now.minute(); tm.Second = now.second();
Nein. Dies initialisiert die tm
Variable. Dies hat keine Auswirkung auf die Vorstellung der Zeitbibliothek von der aktuellen Zeit. Beachten Sie, dass die Datumsfelder von tm
zu diesem Zeitpunkt noch nicht initialisiert wurden und möglicherweise ungültig sind (wie Monat 23, Tag 125).
setSyncProvider(RTC.now);
Dies ist falsch und sollte eine Compiler-Warnung generiert haben. setSyncProvider()
erwartet eine Funktion, die die aktuelle Zeit als Unix-Zeit zurückgibt (eine einfache Ganzzahl vom Typ time_t
). Sie stellen eine Funktion bereit, die die aktuelle Zeit in aufgeschlüsselter Form (Jahr, Monat …) mit dem Typ DateTime
zurückgibt. Die Zeitbibliothek versteht das nicht und kann zu Müll wie beispielsweise 18:00:00 führen.
Die von RTC.now()
zurückgegebene Zeit kann in Unix-Zeit konvertiert werden mit der Methode unixtime()
. Deshalb habe ich Ihnen die Funktion time_provider()
gegeben.
Außerdem sollten Sie setSyncProvider()
und nicht aufrufen setSyncInterval()
bei jeder Schleifeniteration. Führen Sie dies ein für alle Mal in setup()
durch.
// Time Library time updates to RTC every 5 seconds tm.Hour = hour(); tm.Minute = minute(); tm.Second = second();
Wieder dies aktualisiert nur die Variable tm
. Dies hat keine Auswirkung auf die aktuelle Zeitbibliothek.
Antwort
Gibt es in RTCLib eine äquivalente Funktion als setSyncProvider (RTC.get) in der DS1307RTC-Bibliothek?
Gibt es eine Äquivalent zu setSyncInterval (5000)
Dies sind TimeLib-Funktionen. Es gibt kein “ Äquivalent zu „, da Sie TimeLib verwenden.
Der erste erwartet nur einen Zeiger auf eine Funktion, die r gibt ein time_t
zurück. Was in dieser Funktion steckt, liegt bei Ihnen.
Welche RTCLib soll ich aufrufen? In Beispielen werden mehrere verwendet:
Die Großschreibung sollte mit dem Namen der Header-Datei übereinstimmen. Windows ist das egal, und OS X ist das normalerweise egal, kann aber so konfiguriert werden. Linux kümmert sich darum und muss es anpassen. Wenn Sie möchten, dass Ihr Code portabel ist, müssen Sie die Groß- und Kleinschreibung der Datei beibehalten.
und manchmal auch eines der folgenden Elemente aufrufen:
Sie müssen ein Objekt erstellen, das Ihrer physischen RTC entspricht.
a. Sind tmElements_t tm Teil der DS1307RTC-Bibliothek?
Nr. Sie sind Teil von TimeLib.
b. Sind diese tm.Hour tm.Minute von der RTC entfernt?
Sie sind alles, was ihnen von einer aufgerufenen Funktion zugewiesen wird. Sie sind nur Variablen. Sie können alles enthalten.
c. Gibt es ein Äquivalent in der RTClib.h?
Nr. Aber dann brauchen Sie es nicht, wenn Sie TimeLib verwenden.
Also: Sie müssen
- eine Funktion erstellen, die die Zeit von der RTC über die gewünschte Bibliothek (z. B. RTCLib) abruft und die Anzahl der Sekunden berechnet seit 00:00:00 01/01/1970, die dann als
time_t
zurückgegeben wird. - Übergeben Sie dies an TimeLibs
setSyncProvider()
- Legen Sie eine Synchronisierungsfrequenz mit
setSyncInterval()
fest.
Kommentare
-
now
ist die Zeit von der RTC zu dem Zeitpunkt, zu dem Sie das Objektnow
zuweisen..hour()
ist nur die Stunde, die in diesem Objekt enthalten ist.hour()
ist die Zeit aus der TimeLib-Bibliothek, ja. setSyncProvider () tut dies nicht ‚ sendet nichts an die RTC, es ruft regelmäßig die Zeit von der RTC ab und aktualisiert die TimeLib mit der aktuellen Zeit. - Es ‚ ist etwas komplexer als das. TimeLib verwendet
millis()
die Zeit verfolgen. Es aktualisiert regelmäßig seine interne Vorstellung von der Uhrzeit in Abhängigkeit vonsetSyncInterval()
. Wenn Sie nachhour()
fragen, wird mehr Zeit vergangen, seit es die insetSyncInterval()
angegebene Echtzeit erreicht hat die Zeit von der RTC. Andernfalls wird Ihnen nur mitgeteilt, was denkt , dass die Zeit nach eigenen internen Berechnungen ist. - Ich habe meinen Beitrag mit Hilfe der Hilfe aktualisiert. Fast haben Sie es verstanden.
- Weil Sie ‚ ständig den Synchronisierungsanbieter und das Intervall ändern. Sie stellen diese einmal und nur einmal im Setup ein und nie wieder.
- Das sieht richtig aus, ja. Obwohl Sie ‚ die Struktur
tmElements_t
überhaupt nicht benötigen, da Sie nur ‚ handeln mit ist einfache Zahlen.tmElements_t
ist nur eine bequeme Möglichkeit, sie alle zu bündeln, wenn Sie sie an eine andere Funktion übergeben möchten. NurSerial.print(hour());