Jeg bruker RTClib.h og TimeLib.h med en Uno.
Har slitt i flere dager for å forstå de forskjellige tilgjengelige RTC-bibliotekene og hvordan du bruker dem med Arduino Time Library.
Spørsmål 1 div
Hvis jeg ikke vil lage et nytt nå () -objekt hver gang gjennom sløyfen, hvordan synkroniserer jeg tidsbiblioteket til RTC hvert x sekund? Hver gang jeg prøver å bruke RTClib-funksjonen nå. Time nå. Minutt osv., Krever det at jeg bruker DateTime nå = RTC.now () for å lage nå () -objektet.
Er det en tilsvarende funksjon i RTCLib som setSyncProvider (RTC.get) i DS1307RTC-biblioteket?
Er det noe som tilsvarer setSyncInterval (5000)
Spørsmål 2 .
Hvilken RTCLib skal jeg ringe ut? Det er flere som brukes i eksempler:
< RTClib.h >
» RTClib » ved å bruke anførselstegn
< RTCLib.h > med store bokstaver
og noen ganger også kalle ut en av disse:
RTC_DS1307 RTC
eller RTC_DS1307 rtc
eller RTC_DS3231 rtc
Spørsmål 3
a. Er tmElements_t tm en del av DS1307RTC-biblioteket?
b. Er disse tm.Hour tm.Minute fra RTC?
c. Er det en ekvivalent i RTClib.h?
Og til slutt har jeg lagt ut noen kode nedenfor bare for å vise bruken min:
#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); }
Oppdatert 5. nov 2020
Jeg tror jeg nesten forstår. Gi meg beskjed hvis denne koden gjør det jeg tror den gjør, spesielt:
I oppsett:
Sett RTC til 5:10:30.
Sett tidsbiblioteket til 9:27:05 med setTime ().
Still tidsbiblioteket til RTC-tid med DateTime nå (over skriving 9:27:05)?
Sett tidsbibliotekets variabler til RTC ved hjelp av tm.Hour = nå. Time osv.
I sløyfe:
Hvert 5. sekund oppdaterer time (), minutt () sekund () med RTC-tid.
Hver løkkeoppdatering tm.time med time () osv.
Jeg vet at det fremdeles ikke stemmer siden serieutskriftene viser tm.Hour, tm.Minutt vekselvis hver sløyfe som vist nederst.
#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); }
Serietrykk:
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
La meg først gi litt bakgrunn om disse bibliotekene.
Tidsbiblioteket bruker millis()
i tidtaking. Siden dette kan være utsatt for betydelig drift, gir det et middel til periodisk å synkronisere med en ekstern tidsleverandør. Derfor er funksjonene setSyncProvider()
og setSyncInterval()
.
RTClib er ment å grensesnitt en RTC. Det gir ikke tidtaking på egenhånd: du får den aktuelle tiden ved å spørre en RTC gjennom den «s now()
-metoden.
Disse to bibliotekene kan fint utfylle hver annet, da RTClib kan brukes som tidsleverandør for 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 opprette et nytt nå () -objekt […]
Det kalles faktisk et DateTime
-objekt.
Er det en ekvivalent [til
tmElements_t
] i RTClib
Ja, DateTime
klasse . Vær oppmerksom på at, i motsetning til tmElements_t
-strukturen, er ikke datafeltene til DateTime
offentlig, og du må bruke aksessorer for å få dem: year()
, month()
, day()
…
Alternativ tidtaksmetode
Siden du bruker en Arduino Uno, er det en tredje metode for tidtaking som du kan vil vurdere. I stedet for å stille spørsmål ved RTC på hver loop-iterasjon (RTClib) eller interpolere RTC-avlesningene med millis()
(tidsbibliotek), kan du dirigere en 1 Hz-utgang fra RTC til en avbrytingspinne og tell sekundene i ISR. avr-libc timing code er designet for å gi tidtaking på denne måten. Det hele koker 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 eksemplets skisse avbryter1Hz.ino utstyrt med RTClib.
Rediger 1 : Svar på en kommentar
hvilken pin kobler [Arduino-avbruddspinnen] til på RTC?
Det avhenger av RTC du bruker. Jeg vil anta at det er en DS1307, som antydet av koden i spørsmålet ditt. Ta en titt på databladet til RTC.På side 6 er det en tabell med tittelen “Pin beskrivelse”. Fra denne tabellen:
pin : 7
navn : SQW / OUT
-funksjon : Square Wave / Output Driver. Når den er aktivert, er SQWE-biten satt til 1, SQW / OUT-pinnen sender ut en av fire firkantbølgefrekvenser (1Hz, 4kHz, 8kHz, 32kHz). SQW / OUT-pinnen er åpen avløp og krever en ekstern opptrekksmotstand. SQW / OUT fungerer enten med V CC eller V BAT . Uttrekksspenningen kan være opptil 5,5 V uavhengig av spenningen på V CC . Hvis den ikke brukes, kan denne pinnen stå flytende.
Hvis du bruker en RTC -modul , må du finne ut ut der denne pinnen er eksponert på modulens kontakt.
I alle fall må du aktivere 1 Hz firkantbølgeutgang med
RTC.writeSqwPinMode(DS1307_SquareWave1HZ);
Rediger 2 : Kommenterer oppdateringen til spørsmålet:
// Set the RTC Time to 5:10:30 Nov 3 2020 RTC.adjust(DateTime(2020,11,3,5,10,30));
Riktig.
// Set Arduino Time Library different than RTC time 9:27:05 setTime(9, 27, 05, 14, 07, 2015);
Riktig. 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();
Nei. Dette initialiseres bare delvis tm
variabel. Det har ingen innvirkning på ideen Time-biblioteket har av gjeldende tid. Vær oppmerksom på at datofeltene til tm
ikke er initialisert på dette tidspunktet, og kan godt være ugyldige (som måned 23. dag 125).
setSyncProvider(RTC.now);
Dette er feil, og burde ha generert en kompilatorvarsel. setSyncProvider()
forventer en funksjon som returnerer gjeldende tid som Unix-tid (et enkelt heltall, av typen time_t
). Du gir en funksjon som returnerer gjeldende tid i fordelt form (år, måned …), med typen DateTime
. Tidsbiblioteket vil ikke forstå det og kan gi søppel som for eksempel 18:00:00.
Tiden som returneres av RTC.now()
kan konverteres til Unix-tid med unixtime()
-metoden. Derfor ga jeg deg time_provider()
-funksjonen.
Du skal heller ikke ringe setSyncProvider()
og setSyncInterval()
på hver loop-iterasjon. Gjø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();
Igjen, dette oppdaterer bare variabelen tm
. Det har ingen innvirkning på det Time-biblioteket mener er nåværende tid.
Svar
Er det en tilsvarende funksjon i RTCLib som setSyncProvider (RTC.get) i DS1307RTC-biblioteket?
Er det en tilsvarer setSyncInterval (5000)
Dette er TimeLib-funksjoner. Det er ingen » som tilsvarer » siden du bruker TimeLib.
Den første forventer bare en peker til en funksjon som r eturns a time_t
. Hva er i den funksjonen er opp til deg.
Hvilken RTCLib skal jeg ringe ut? Det er flere som brukes i eksempler:
Store bokstaver skal samsvare med navnet på toppfilen. Windows bryr seg ikke, og OS X bryr seg vanligvis ikke, men kan konfigureres til. Linux bryr seg og trenger det for å matche. Hvis du vil at koden din skal være bærbar, må du beholde store bokstaver som filen.
og noen ganger også kalle ut en av disse:
Du må opprette et objekt som samsvarer med din fysiske RTC.
a. Er tmElements_t tm en del av DS1307RTC-biblioteket?
Nei. De er en del av TimeLib.
b. Er disse tm.Hour tm.Minute fra RTC?
De er det som blir tildelt dem av en funksjon som kalles. De er bare variabler. De kan inneholde hva som helst.
c. Er det en ekvivalent i RTClib.h?
Nei. Men da trenger du ikke være hvis du bruker TimeLib.
Så: du må
- Lag en funksjon som får tiden fra RTC gjennom hvilket bibliotek du vil bruke (for eksempel RTCLib) og beregner antall sekunder siden 00:00:00 01/01/1970, som den deretter returnerer som en
time_t
. - Gi den til TimeLib «s
setSyncProvider()
- Angi en synkroniseringsfrekvens med
setSyncInterval()
.
Kommentarer
-
now
er tiden fra RTC i det øyeblikket du tildelernow
-objektet..hour()
er bare timen inne i objektet.hour()
er tiden fra TimeLib-biblioteket, ja. setSyncProvider () gjør ikke ‘ Hvis du ikke sender noe til RTC, får det tiden fra RTC regelmessig og oppdaterer TimeLib med gjeldende tid. - Det ‘ er litt mer komplisert enn det. TimeLib bruker
millis()
for å holde styr på tiden. Den oppdaterer jevnlig sin interne ide om hva tiden er avhengig avsetSyncInterval()
. når du ber omhour()
, hvis det har gått mer tid siden sist den sanne tiden du angav isetSyncInterval()
, vil den gå og få tiden fra RTC. Ellers vil den bare fortelle deg hva den tenker tiden er i henhold til sine egne interne beregninger. - Jeg oppdaterte innlegget mitt med hjelp gitt. Har nesten forstått det.
- Fordi du ‘ endrer konstant synkroniseringsleverandøren og intervallet. Du setter dem en og en gang bare i oppsettet, og aldri igjen.
- Det ser riktig ut, ja. Selv om du ikke trenger ‘ trenger du ikke
tmElements_t
struct siden alt du ‘ har å gjøre med er enkle tall.tmElements_t
er bare en praktisk måte å pakke dem alle sammen hvis du vil overføre det til en annen funksjon. BareSerial.print(hour());