Arduino Time Library și RTC Libraries

Folosesc RTClib.h și TimeLib.h cu un Uno.

Mă lupt de zile întregi în înțelegerea diferitelor biblioteci RTC disponibile și cum să le utilizați cu Arduino Time Library.

Întrebarea 1 .
Dacă nu vreau să creez un nou obiect now () de fiecare dată prin buclă, cum pot sincroniza biblioteca de timp cu RTC la fiecare x secunde? De fiecare dată când încerc să folosesc funcția RTClib now.hour now.minute etc îmi cere să folosesc DateTime now = RTC.now () creând obiectul now ().

Există o funcție echivalentă în RTCLib ca setSyncProvider (RTC.get) în biblioteca DS1307RTC?

Există un echivalent cu setSyncInterval (5000)

Întrebarea 2 .
Ce RTCLib ar trebui să sun? Există câteva exemple utilizate în exemple:

< RTClib.h >

” RTClib ” folosind ghilimele

< RTCLib.h > cu majuscule L

și uneori apelând și la unul dintre acestea:

RTC_DS1307 RTC

sau RTC_DS1307 rtc

sau RTC_DS3231 rtc

Întrebarea 3
a. TMElements_t tm face parte din biblioteca DS1307RTC?
b. Sunt acestea tm.Hour tm.Minute de la RTC?
c. Există un echivalent în RTClib.h?

Și în cele din urmă am postat câteva coduri mai jos, doar pentru a-mi arăta utilizarea:

#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); } 

Actualizat la 5 noiembrie 2020

Cred că aproape înțeleg. Vă rugăm să-mi spuneți dacă acest cod face ceea ce cred că face, în special:

În configurare:
Setați RTC la 5:10:30.
Setați biblioteca de timp la 9:27:05 cu setTime ().
Setați Time Library la ora RTC cu DateTime acum (peste scriere 9:27:05)?
Setați variabilele Library Time la RTC folosind tm.Hour = now. Ora etc.

În buclă:
La fiecare 5 secunde actualizare oră (), minut () secundă () cu timp RTC.
Fiecare actualizare buclă tm.hour cu oră () , etc.

Știu că încă nu este corect, deoarece imprimările seriale arată tm.Hour, tm.Minute alternând fiecare buclă așa cum se arată în partea de jos.

 #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); }  

Tipăriri seriale:

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 

Răspunde

Permiteți-mi să vă ofer mai întâi câteva informații despre aceste biblioteci.

Biblioteca Time folosește millis() pentru pontaj. Deoarece acest lucru poate fi supus unei derive semnificative, acesta oferă un mijloc de sincronizare periodică cu un furnizor extern de timp. Prin urmare, funcțiile setSyncProvider() și setSyncInterval().

RTClib este menit să interfețe un RTC. Nu oferă cronometrarea de la sine: obțineți ora curentă interogând un RTC prin metoda „s now().

Aceste două biblioteci pot completa frumos fiecare altul, deoarece RTClib poate fi folosit ca furnizor de timp pentru biblioteca Time:

 // Provide the RTC time to the Time library. time_t time_provider() { return RTC.now().unixtime(); } void setup() { // ... setSyncProvider(time_provider); }  

Dacă nu vreau să creez un nou obiect now () […]

Se numește de fapt un obiect DateTime.

Există un echivalent [la tmElements_t] în RTClib

Da, DateTime class . Rețineți că, spre deosebire de structura tmElements_t, câmpurile de date din DateTime nu sunt public și trebuie să utilizați accesorii pentru a le obține: year(), month(), day()

Metodă alternativă de cronometrare

Întrucât utilizați un Arduino Uno, există o a treia metodă de cronometrare. vreau să ia în considerare. În loc să interogați RTC pe fiecare iterație de buclă (RTClib) sau să interpolați citirile RTC cu millis() (biblioteca de timp), puteți direcționa o ieșire de 1 Hz a RTC către un pin de întrerupere, și numărați secundele în ISR. codul de sincronizare avr-libc este conceput pentru a oferi cronometrarea în acest mod. Totul se rezumă la:

 // 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);  

Pentru mai multe detalii, consultați schița de exemplu interrupts1Hz.ino furnizat cu RTClib.


Editați 1 : Răspunsul la un comentariu

la care pin se conectează [pinul de întrerupere Arduino] pe RTC?

Depinde de RTC pe care îl utilizați. Voi presupune că este un DS1307, așa cum implică codul din întrebarea dvs. Aruncați o privire la foaia tehnică a RTC.La pagina 6, există un tabel intitulat „Descriere pin”. Din acest tabel:

pin : 7
nume : SQW / OUT
: Pond pătrat / driver de ieșire. Când este activat, bitul SQWE setat la 1, pinul SQW / OUT emite una dintre cele patru frecvențe de undă pătrată (1Hz, 4kHz, 8kHz, 32kHz). Pinul SQW / OUT este golit și necesită un rezistor de extragere extern. SQW / OUT funcționează fie cu V CC , fie cu V BAT aplicat. Tensiunea de tragere poate fi de până la 5,5 V, indiferent de tensiunea de pe V CC . Dacă nu este utilizat, acest pin poate fi lăsat plutitor.

Dacă utilizați un RTC modul , va trebui să calculați unde este expus acest pin pe conectorul modulului.

În orice caz, va trebui să activați ieșirea undei pătrate de 1 Hz cu

 RTC.writeSqwPinMode(DS1307_SquareWave1HZ);  

Editează 2 : Comentează actualizarea la întrebarea:

 // Set the RTC Time to 5:10:30 Nov 3 2020 RTC.adjust(DateTime(2020,11,3,5,10,30));  

Corect.

 // Set Arduino Time Library different than RTC time 9:27:05 setTime(9, 27, 05, 14, 07, 2015);  

Corect. Data este 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();  

Nu. Aceasta inițializează doar parțial tm variabilă. Nu are niciun efect asupra ideii pe care biblioteca Time o are despre ora curentă. Rețineți că câmpurile de dată din tm nu au fost inițializate în acest moment și ar putea fi nevalide (cum ar fi luna 23, ziua 125).

 setSyncProvider(RTC.now);  

Acest lucru este incorect și ar fi trebuit să genereze un avertisment al compilatorului. setSyncProvider() așteaptă o funcție care returnează ora curentă ca timp Unix (un întreg simplu, de tip time_t). Furnizați o funcție care returnează ora curentă sub formă defalcate (an, lună …), cu tipul DateTime. Biblioteca Time nu va înțelege acest lucru și poate genera gunoi, cum ar fi, să zicem, 18:00:00.

Ora returnată de RTC.now() poate fi convertită în ora Unix cu metoda unixtime(). De aceea ți-am dat funcția time_provider().

De asemenea, nu trebuie să suni la setSyncProvider() și setSyncInterval() la fiecare iterație de buclă. Faceți-o o dată pentru totdeauna în setup().

 // Time Library time updates to RTC every 5 seconds tm.Hour = hour(); tm.Minute = minute(); tm.Second = second();  

Din nou, acest lucru actualizează doar variabila tm. Nu are niciun efect asupra a ceea ce biblioteca Time consideră că este ora curentă.

Răspuns

Există o funcție echivalentă în RTCLib ca setSyncProvider (RTC.get) în biblioteca DS1307RTC?

Există o echivalent cu setSyncInterval (5000)

Acestea sunt funcții TimeLib. Nu există ” echivalent cu ” deoarece folosiți TimeLib.

Primul se așteaptă doar la un pointer la o funcție care r generează un time_t. Ce funcție depinde de tine.

Ce RTCLib ar trebui să chem? Există mai multe folosite în exemple:

Scrierea cu majuscule trebuie să se potrivească cu numele fișierului antet. Windows nu are grijă, iar OS X de obicei nu are grijă, dar poate fi configurat la. Linux are grijă și are nevoie să se potrivească. Dacă doriți ca codul dvs. să fie portabil, trebuie să păstrați scrierea cu majuscule la fel ca fișierul.

și, uneori, să apelați una dintre acestea:

Trebuie să creați un obiect care să se potrivească cu RTC-ul dvs. fizic.

a. TMElements_t tm face parte din biblioteca DS1307RTC?

Nu Acestea fac parte din TimeLib.

b. Sunt aceste tm.Hour tm.Minute de la RTC?

Acestea sunt ceea ce li se atribuie printr-o funcție numită. Sunt doar variabile. Pot conține orice.

c. Există un echivalent în RTClib.h?

Nu. Dar atunci nu trebuie să existe dacă folosiți TimeLib.

Deci: trebuie să

  • Creați o funcție care obține timpul de la RTC prin orice bibliotecă doriți să utilizați (RTCLib de exemplu) și să calculeze numărul de secunde de la 00:00:00 01/01/1970, pe care apoi îl returnează ca time_t.
  • Transmiteți acest lucru către TimeLib „s setSyncProvider()
  • Setați o frecvență de sincronizare cu setSyncInterval().

Comentarii

  • now este timpul de la RTC în momentul în care atribuiți obiectul now. .hour() este doar ora conținută în interiorul acelui obiect. hour() este ora din biblioteca TimeLib, da. setSyncProvider () doesn ‘ nu trimiteți nimic către RTC, obține regulat timpul de la RTC și actualizează TimeLib cu ora curentă.
  • Acesta ‘ este puțin mai complex decât atât. TimeLib folosește millis() pentru a ține evidența timpului. Acesta își actualizează în mod regulat ideea internă a timpului în funcție de setSyncInterval(). când solicitați hour(), dacă a trecut mai mult timp de când a primit ultima dată timpul real pe care l-ați specificat în setSyncInterval() va merge și obține timpul de la RTC. În caz contrar, vă va spune doar ce crede este timpul potrivit propriilor calcule interne.
  • Mi-am actualizat postarea cu ajutorul oferit. Aproape ați înțeles-o.
  • Pentru că ‘ schimbați constant furnizorul și intervalul de sincronizare. Le setați o dată și o dată numai în configurare și niciodată.
  • Arată bine, da. Deși nu aveți ‘ de care aveți nevoie de structura tmElements_t, deoarece vă ocupați de ‘ cu este numere simple. tmElements_t este doar un mod convenabil de a le grupa pe toate dacă doriți să le transmiteți unei alte funcții. Doar Serial.print(hour());

Lasă un răspuns

Adresa ta de email nu va fi publicată. Câmpurile obligatorii sunt marcate cu *