Arduino Time Library og RTC Libraries

Jeg bruger RTClib.h og TimeLib.h med en Uno.

Har kæmpet i flere dage for at forstå de forskellige tilgængelige RTC-biblioteker, og hvordan man bruger dem med Arduino Time Library.

Spørgsmål 1 div
Hvis jeg ikke ønsker at oprette et nyt nu () -objekt hver gang gennem sløjfen, hvordan synkroniserer jeg tidsbiblioteket med RTC hvert x sekund? Hver gang jeg prøver at bruge RTClib-funktionen nu. Time now.minute osv., Kræver det, at jeg bruger DateTime nu = RTC.now () opretter objektet now ().

Er der en tilsvarende funktion i RTCLib som setSyncProvider (RTC.get) i DS1307RTC-biblioteket?

Er der en ækvivalent med setSyncInterval (5000)

Spørgsmål 2 .
Hvilken RTCLib skal jeg ringe til? Der er flere anvendte i eksempler:

< RTClib.h >

” RTClib ” ved hjælp af anførselstegn

< RTCLib.h > med store bogstaver L

og undertiden også kalde en af disse:

RTC_DS1307 RTC

eller RTC_DS1307 rtc

eller RTC_DS3231 rtc

Spørgsmål 3
a. Er tmElements_t tm en del af DS1307RTC-biblioteket?
b. Er disse tm.Time tm.Minute fra RTC?
c. Er der en ækvivalent i RTClib.h?

Og til sidst har jeg sendt nogle kode nedenfor bare for at vise min brug:

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

Opdateret 5. nov 2020

Jeg tror, jeg næsten forstår. Giv mig besked, hvis denne kode gør, hvad jeg tror, den gør, specifikt:

I opsætning:
Indstil RTC til 5:10:30.
Indstil tidsbiblioteket til 9:27:05 med setTime ().
Indstil tidsbiblioteket til RTC-tid med DateTime nu (overskrivning 9:27:05)?
Indstil tidsbibliotekets variabler til RTC ved hjælp af tm.Hour = nu. Time osv.

I loop:
Hver 5. sekund opdateres time (), minut () sekund () med RTC-tid.
Hver løkkeopdatering tm. Time med time () osv.

Jeg ved, at det stadig ikke er korrekt, da serietrykkene viser tm.Hour, tm.Minut skiftevis hver løkke som vist i bunden.

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

Serietryk:

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 

Svar

Lad mig først give lidt baggrund om disse biblioteker.

Tidsbiblioteket bruger millis() til tidtagning. Da dette kan være udsat for betydelig drift, giver det et middel til periodisk at synkronisere med en ekstern tidsudbyder. Derfor er funktionerne setSyncProvider() og setSyncInterval().

RTClib er beregnet til at interface en RTC. Det giver ikke tidtagning alene: Du får den aktuelle tid ved at spørge en RTC gennem den “s now() -metoden.

Disse to biblioteker kan pænt supplere hver andet, da RTClib kan bruges som tidsudbyder til tidsbiblioteket:

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

Hvis jeg ikke vil oprette et nyt nu () -objekt […]

Det kaldes faktisk et DateTime -objekt.

Er der en ækvivalent [til tmElements_t] i RTClib

Ja, DateTime klasse . Bemærk, at i modsætning til tmElements_t strukturen, er datafelterne for DateTime ikke offentlig, og du skal bruge accessorer for at få dem: year(), month(), day()

Alternativ tidtagningsmetode

Da du bruger en Arduino Uno, er der en tredje metode til tidtagning, du kan vil overveje. I stedet for at stille spørgsmålstegn ved RTC på hver loop-iteration (RTClib) eller interpolere RTC-aflæsningerne med millis() (tidsbibliotek), kan du dirigere en 1 Hz-udgang af RTC til en afbrydelsesstift, og tæl sekunderne i ISR. avr-libc timing-kode er designet til at give tidtagning på denne måde. Det hele koger ned til:

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

For flere detaljer, se skitsen på eksemplet afbryder1Hz.ino forsynet med RTClib.


Rediger 1 : Besvarelse af en kommentar

hvilken pin forbinder [Arduino-afbrydestiften] til på RTC?

Det afhænger af den RTC, du bruger. Jeg antager, at det er en DS1307 som antydet af koden i dit spørgsmål. Se på databladet af RTC.På side 6 er der en tabel med titlen “Pin beskrivelse”. Fra denne tabel:

pin : 7
navn : SQW / OUT
funktion : Firkantbølge / outputdriver. Når denne er aktiveret, SQWE bit sat til 1, SQW / OUT pin udgange en af fire firkantbølgefrekvenser (1Hz, 4kHz, 8kHz, 32kHz). SQW / OUT-stiften er åben afløb og kræver en ekstern pullup-modstand. SQW / OUT fungerer med enten V CC eller V BAT anvendt. Trækspændingen kan være op til 5,5 V uanset spændingen på V CC . Hvis den ikke bruges, kan denne stift efterlades flydende.

Hvis du bruger et RTC modul , bliver du nødt til at finde ud af ud, hvor denne pin er eksponeret på modulets stik.

Under alle omstændigheder bliver du nødt til at aktivere 1 Hz firkantbølgeoutput med

 RTC.writeSqwPinMode(DS1307_SquareWave1HZ);  

Rediger 2 : Kommenterer opdateringen til spørgsmålet:

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

Korrekt.

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

Korrekt. Dato er 2015-07-14.

 // Setting Time Library to RTC time DateTime now = RTC.now(); tm.Hour = now.hour(); tm.Minute = now.minute(); tm.Second = now.second();  

Nej. Dette initialiseres kun delvist tm variabel. Det har ingen indflydelse på den idé, Time-biblioteket har af den aktuelle tid. Bemærk, at datofelterne for tm ikke er initialiseret på dette tidspunkt og meget vel kan være ugyldige (som måned 23. dag 125).

 setSyncProvider(RTC.now);  

Dette er forkert og skulle have genereret en kompilatoradvarsel. setSyncProvider() forventer en funktion, der returnerer det aktuelle tidspunkt som Unix-tid (et simpelt heltal, af typen time_t). Du leverer en funktion, der returnerer den aktuelle tid i opdelt form (år, måned …) med typen DateTime. Tidsbiblioteket forstår det ikke og kan give affald som f.eks. 18:00:00.

Den tid, der returneres af RTC.now(), kan konverteres til Unix-tid med metoden unixtime(). Derfor gav jeg dig funktionen time_provider().

Det er heller ikke meningen, at du skal ringe til setSyncProvider() og setSyncInterval() på hver loop-iteration. Gør det en gang for alle i setup().

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

Igen dette opdaterer kun variablen tm. Det har ingen indflydelse på, hvad Time-biblioteket mener er det aktuelle tidspunkt.

Svar

Er der en ækvivalent funktion i RTCLib som setSyncProvider (RTC.get) i DS1307RTC-biblioteket?

Er der en svarende til setSyncInterval (5000)

Det er TimeLib-funktioner. Der er ingen ” svarende til ” da du bruger TimeLib.

Den første forventer bare en markør til en funktion, der r eturner en time_t. Hvad der er i denne funktion er op til dig.

Hvilken RTCLib skal jeg ringe til? Der er flere anvendte i eksempler:

Store bogstaver skal svare til navnet på headerfilen. Windows er ligeglad, og OS X plejer normalt ikke, men kan konfigureres til. Linux bryder sig og har brug for det til at matche. Hvis du vil have din kode til at være bærbar, skal du holde store og store bogstaver som filen.

og undertiden også kalde en af disse op:

Du skal oprette et objekt, der matcher din fysiske RTC.

a. Er tmElements_t tm en del af DS1307RTC-biblioteket?

Nej. De er en del af TimeLib.

b. Er disse tm.Hour tm.Minute fra RTC?

De er det, der bliver tildelt dem af en funktion, der kaldes. De er bare variabler. De kan indeholde alt.

c. Er der en ækvivalent i RTClib.h?

Nej. Men så behøver du ikke være der, hvis du bruger TimeLib.

Så: du skal

  • Opret en funktion, der får tiden fra RTC gennem det bibliotek, du vil bruge (f.eks. RTCLib) og beregner antallet af sekunder siden 00:00:00 01/01/1970, som den derefter returnerer som en time_t.
  • Send den til TimeLib “s setSyncProvider()
  • Indstil en synkroniseringsfrekvens med setSyncInterval().

Kommentarer

  • now er tiden fra RTC i det øjeblik du tildeler now -objektet. .hour() er kun timen inde i objektet. hour() er tiden fra TimeLib-biblioteket, ja. setSyncProvider () gør ikke ‘ ikke sender noget til RTC, det får tiden fra RTC regelmæssigt og opdaterer TimeLib med det aktuelle tidspunkt.
  • Det ‘ er lidt mere kompleks end det. TimeLib bruger millis() for at holde styr på tiden. Den opdaterer regelmæssigt sin interne idé om, hvad tiden er afhængig af setSyncInterval(). når du beder om hour(), hvis der er gået mere tid siden sidst fik den rigtige tid, du angav i setSyncInterval(), vil den gå og hente tiden fra RTC. Ellers fortæller det dig bare, hvad det tænker tiden er i henhold til sine egne interne beregninger.
  • Jeg opdaterede mit indlæg med hjælp. Næsten har det forstået.
  • Fordi du ‘ ændrer konstant synkroniseringsudbyderen og -intervallet. Du indstiller dem en gang og en gang kun i opsætningen og aldrig igen.
  • Det ser rigtigt ud, ja. Selvom du slet ikke ‘ har brug for tmElements_t strukturen, da alt hvad du ‘ har at gøre med med er enkle tal. tmElements_t er bare en bekvem måde at samle dem alle sammen, hvis du vil overføre det til en anden funktion. Bare Serial.print(hour());

Skriv et svar

Din e-mailadresse vil ikke blive publiceret. Krævede felter er markeret med *