Arduino Time Library en RTC Libraries

Ik gebruik RTClib.h en TimeLib.h met een Uno.

Ik heb dagenlang geworsteld om de verschillende beschikbare RTC-bibliotheken te begrijpen en hoe ze te gebruiken met de Arduino Time Library.

Vraag 1 .
Als ik niet elke keer door de lus een nieuw now () -object wil maken, hoe synchroniseer ik de tijdbibliotheek dan elke x seconden met de RTC? Elke keer dat ik de RTClib-functie now.hour now.minute etc probeer te gebruiken, moet ik DateTime now = RTC.now () gebruiken om het now () -object te maken.

Is er een equivalente functie in RTCLib als setSyncProvider (RTC.get) in DS1307RTC-bibliotheek?

Is er een equivalent voor setSyncInterval (5000)

Vraag 2 .
Welke RTCLib moet ik aanroepen? Er worden er verschillende gebruikt in voorbeelden:

< RTClib.h >

” RTClib ” met aanhalingstekens

< RTCLib.h > met hoofdletter L

en soms ook een van deze:

RTC_DS1307 RTC

of RTC_DS1307 rtc

of RTC_DS3231 rtc

Vraag 3
a. Zijn tmElements_t tm onderdeel van de DS1307RTC-bibliotheek?
b. Zijn dit tm.Hour tm.Minute van de RTC?
c. Is er een equivalent in de RTClib.h?

En tot slot heb ik hieronder een code gepost om mijn gebruik te laten zien:

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

Bijgewerkt op 5 november 2020

Ik denk dat ik het bijna begrijp. Laat het me weten als deze code doet wat ik denk dat hij doet, met name:

In Setup:
Stel de RTC in op 5:10:30.
Stel Time Library in op 9:27:05 met setTime ().
Zet Time Library nu op RTC-tijd met DateTime (overschrijven 9:27:05)?
Stel Time Library-variabelen in op RTC met tm.Hour = now. Uur, etc.

In Loop:
Elke 5 seconden update uur (), minuut () seconde () met RTC-tijd.
Elke lus update tm.hour met uur () , enz.

Ik weet dat het nog steeds niet juist is, aangezien de seriële afdrukken tm.Hour, tm.Minute tonen, waarbij elke lus wordt afgewisseld zoals onderaan wordt weergegeven.

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

Seriële afdrukken:

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 

Antwoord

Laat me eerst wat achtergrondinformatie geven over deze bibliotheken.

De Time-bibliotheek gebruikt millis() voor tijdwaarneming. Aangezien dit aanzienlijk kan afwijken, biedt het een manier om periodiek te synchroniseren met een externe tijdaanbieder. Vandaar de functies setSyncProvider() en setSyncInterval().

RTClib is bedoeld om een RTC te koppelen. Het biedt op zichzelf geen tijdregistratie: u krijgt de huidige tijd door een RTC op te vragen via zijn “s now() -methode.

Deze twee bibliotheken kunnen elk mooi aanvullen anders, aangezien RTClib kan worden gebruikt als een tijdprovider voor de tijdbibliotheek:

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

Als ik geen nieuw now () object wil maken […]

Het wordt eigenlijk een DateTime -object genoemd.

Is er een equivalent [to tmElements_t] in de RTClib

Ja, de DateTime class . Houd er rekening mee dat, in tegenstelling tot de tmElements_t -structuur, de gegevensvelden van DateTime niet public, en je moet accessors gebruiken om ze te krijgen: year(), month(), day()

Alternatieve tijdregistratiemethode

Aangezien u een Arduino Uno gebruikt, is er een derde methode voor tijdregistratie die u kunt willen overwegen. In plaats van de RTC op elke lus-iteratie (RTClib) te bevragen of de RTC-metingen te interpoleren met millis() (tijdbibliotheek), kun je een 1 Hz-uitgang van de RTC naar een interrupt-pin sturen, en tel de seconden in de ISR. De avr-libc timingcode is ontworpen om op deze manier tijdregistratie te bieden. Het komt allemaal neer op:

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

Zie de voorbeeldschets voor meer details interrupts1Hz.ino voorzien van RTClib.


Bewerk 1 : Een opmerking beantwoorden

met welke pin maakt [de Arduino-interruptpin] verbinding op de RTC?

Het hangt af van de RTC die u gebruikt. Ik neem aan dat het een DS1307 is, zoals geïmpliceerd door de code in je vraag. Bekijk de datasheet van de RTC.Op pagina 6 is er een tabel met de titel “Pinbeschrijving”. Van deze tabel:

pin : 7
naam : SQW / OUT
functie : Square Wave / Output-stuurprogramma. Indien ingeschakeld, wordt de SQWE-bit ingesteld op 1, voert de SQW / OUT-pin een van de vier blokgolffrequenties uit (1 Hz, 4 kHz, 8 kHz, 32 kHz). De SQW / OUT-pin is open afvoer en vereist een externe pullup-weerstand. SQW / OUT werkt met ofwel V CC of V BAT toegepast. De pullup-spanning kan oplopen tot 5,5 V, ongeacht de spanning op V CC . Indien niet gebruikt, kan deze pin zwevend worden gelaten.

Als u een RTC module gebruikt, moet u erachter komen uit waar deze pin zichtbaar is op de connector van de module.

In elk geval moet u de 1 Hz blokgolfuitgang inschakelen met

 RTC.writeSqwPinMode(DS1307_SquareWave1HZ);  

Bewerken 2 : commentaar op de update van de vraag:

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

Correct.

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

Correct. Datum is 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();  

Nee. Dit is slechts gedeeltelijk het initialiseren van de tm variabele. Het heeft geen invloed op het idee dat de Time-bibliotheek heeft van de huidige tijd. Houd er rekening mee dat de datumvelden van tm op dit moment niet zijn geïnitialiseerd en mogelijk ongeldig zijn (zoals maand 23, dag 125).

 setSyncProvider(RTC.now);  

Dit is onjuist en zou een compilerwaarschuwing moeten hebben gegenereerd. setSyncProvider() verwacht een functie die de huidige tijd retourneert als Unix-tijd (een eenvoudig geheel getal, van het type time_t). U levert een functie die de huidige tijd in uitgesplitste vorm (jaar, maand …) retourneert, met het type DateTime. De tijdbibliotheek zal dat niet begrijpen en kan rotzooi opleveren zoals bijvoorbeeld 18:00:00.

De tijd die wordt geretourneerd door RTC.now() kan worden geconverteerd naar Unix-tijd met de unixtime() methode. Daarom heb ik je de functie time_provider() gegeven.

Het is ook niet de bedoeling dat je setSyncProvider() en setSyncInterval() bij elke herhaling van de lus. Doe het voor eens en voor altijd in setup().

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

Nogmaals, dit is alleen de variabele tm aan het updaten. Het heeft geen effect op wat de Time-bibliotheek denkt dat de huidige tijd is.

Antwoord

Is er een equivalente functie in RTCLib als setSyncProvider (RTC.get) in DS1307RTC-bibliotheek?

Is er een equivalent aan setSyncInterval (5000)

Dat zijn TimeLib-functies. Er is “geen ” equivalent aan ” aangezien je TimeLib gebruikt.

De eerste verwacht gewoon een pointer naar een functie die r eturns een time_t. Wat in die functie zit, is aan jou.

Welke RTCLib moet ik aanroepen? Er worden er verschillende gebruikt in voorbeelden:

Het hoofdlettergebruik moet overeenkomen met de naam van het headerbestand. Windows maakt het niet uit, en OS X maakt het meestal niet uit, maar kan worden geconfigureerd voor. Linux doet er wel om en heeft het nodig dat het overeenkomt. Als u wilt dat uw code overdraagbaar is, moet u het hoofdlettergebruik hetzelfde houden als het bestand.

en soms ook een van de volgende oproepen:

U moet een object maken dat overeenkomt met uw fysieke RTC.

een. Zijn tmElements_t tm onderdeel van de DS1307RTC-bibliotheek?

Nee. Ze maken deel uit van TimeLib.

b. Zijn dit tm.Hour tm.Minute van de RTC?

Het is alles wat eraan wordt toegewezen door een functie die wordt aangeroepen. Het zijn slechts variabelen. Ze kunnen alles bevatten.

c. Is er een equivalent in de RTClib.h?

Nee. Maar dan hoef je er niet te zijn als je TimeLib gebruikt.

Dus: je moet

  • Een functie maken die de tijd van de RTC haalt via welke bibliotheek dan ook die je wilt gebruiken (bijvoorbeeld RTCLib) en het aantal seconden berekent sinds 00:00:00 01/01/1970, die het vervolgens retourneert als een time_t.
  • Geef dat door aan TimeLib “s setSyncProvider()
  • Stel een synchronisatiefrequentie in met setSyncInterval().

Opmerkingen

  • now is de tijd van de RTC op het moment dat u het now -object toewijst. .hour() is alleen het uur dat zich in dat object bevindt. hour() is de tijd uit de TimeLib-bibliotheek, ja. setSyncProvider () niet ‘ stuur niets naar de RTC, het haalt regelmatig de tijd op van de RTC en werkt de TimeLib bij met de huidige tijd.
  • Het ‘ is iets complexer dan dat. TimeLib gebruikt millis() om de tijd bij te houden. Het werkt regelmatig zijn interne idee bij van hoe laat het is, afhankelijk van setSyncInterval(). als je om hour() vraagt, als er meer tijd is verstreken sinds de laatste keer de realtime die je hebt opgegeven in setSyncInterval(), wordt het de tijd van de RTC. Anders zal het je gewoon vertellen wat het denkt de tijd is volgens zijn eigen interne berekeningen.
  • Ik heb mijn bericht bijgewerkt met hulp. Heb het bijna begrepen.
  • Omdat u ‘ voortdurend de synchronisatieprovider en het interval wijzigt. Die stel je een keer in tijdens de installatie, en nooit meer.
  • Dat ziet er goed uit, ja. Hoewel je ‘ de tmElements_t -structuur helemaal niet nodig hebt, omdat je ‘ te maken hebt met met is eenvoudige cijfers. tmElements_t is gewoon een handige manier om ze allemaal samen te bundelen als je ze aan een andere functie wilt doorgeven. Gewoon Serial.print(hour());

Geef een reactie

Het e-mailadres wordt niet gepubliceerd. Vereiste velden zijn gemarkeerd met *