Používám RTClib.h a TimeLib.h s Uno.
Už několik dní bojuji v porozumění různým dostupným knihovnám RTC a jak je používat s knihovnou času Arduino.
Otázka 1 .
Pokud nechci pokaždé ve smyčce vytvořit nový objekt now (), jak mohu každých x sekund synchronizovat knihovnu času s RTC? Kdykoli se pokusím použít funkci RTClib now.hour now.minute atd., Vyžaduje to, abych při vytváření objektu now () použil DateTime now = RTC.now ().
Existuje ekvivalentní funkce v RTCLib jako setSyncProvider (RTC.get) v knihovně DS1307RTC?
Existuje ekvivalent setSyncInterval (5000)
Otázka 2 .
Který RTCLib mám vyvolat? V příkladech se používá několik:
< RTClib.h >
“ RTClib “ pomocí uvozovek
< RTCLib.h > s velkým L
a někdy také vyvoláním jedné z těchto možností:
RTC_DS1307 RTC
nebo RTC_DS1307 rtc
nebo RTC_DS3231 rtc
Otázka 3
a. Jsou tmElements_t tm součástí knihovny DS1307RTC?
b. Jsou to tm.Hour tm.Minute z RTC?
c. Existuje ekvivalent v RTClib.h?
A nakonec jsem zveřejnil nějaký kód níže, abych ukázal své použití:
#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); }
Aktualizováno 5. listopadu 2020
Myslím, že téměř rozumím. Dejte mi prosím vědět, pokud tento kód dělá to, co si myslím, že dělá, konkrétně:
V nastavení:
Nastavte RTC na 5:10:30.
Nastavte časovou knihovnu na 9:27:05 s setTime ().
Nastavit časovou knihovnu na čas RTC s DateTime nyní (během psaní 9:27:05)?
Nastavit proměnné časové knihovny na RTC pomocí tm.Hour = now. Hodina atd.
Ve smyčce:
Každých 5 sekund aktualizujte hodinu (), minutu () sekundu () s časem RTC.
Každá aktualizace smyčky tm.hodina s hodinou () atd.
Vím, že to stále není správné, protože sériové výtisky ukazují tm.Hour, tm.Minute střídající každou smyčku, jak je znázorněno dole.
#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); }
Sériové výtisky:
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
Odpověď
Dovolte mi nejprve uvést základní informace o těchto knihovnách.
Knihovna času používá millis()
pro časomíra. Vzhledem k tomu, že to může podléhat významnému posunu, poskytuje prostředky k pravidelné synchronizaci s externím poskytovatelem času. Proto funkce setSyncProvider()
a setSyncInterval()
.
RTClib je určen k propojení s RTC. Sama o sobě neposkytuje měření času: aktuální čas získáte dotazem na RTC prostřednictvím jeho now()
metody.
Tyto dvě knihovny mohou každou pěkně doplnit jiné, protože RTClib lze použít jako poskytovatele času pro knihovnu Time:
// Provide the RTC time to the Time library. time_t time_provider() { return RTC.now().unixtime(); } void setup() { // ... setSyncProvider(time_provider); }
Pokud nechci vytvořit nový objekt now () […]
Ve skutečnosti se tomu říká DateTime
objekt.
Existuje ekvivalent [k
tmElements_t
] v RTClib
Ano, DateTime
třída . Upozorňujeme, že na rozdíl od struktury tmElements_t
nejsou datová pole DateTime
veřejné a k jejich získání musíte použít přístupové objekty: year()
, month()
, day()
…
Alternativní metoda měření času
Jelikož používáte Arduino Uno, existuje třetí způsob měření času chci zvážit. Místo dotazování RTC na každé iteraci smyčky (RTClib) nebo interpolace naměřených hodnot RTC pomocí millis()
(knihovna času) můžete směrovat 1 Hz výstup RTC na pin přerušení, a spočítat sekundy v ISR. časový kód avr-libc je navržen tak, aby poskytoval časování tímto způsobem. Všechno se scvrkává na:
// 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);
Další podrobnosti najdete v ukázce náčrtu interrupts1Hz.ino poskytované s RTClib.
Upravit 1 : Odpověď na komentář
ke kterému pinu se [pin přerušení Arduino] připojí na RTC?
Závisí to na RTC, který používáte. Předpokládám, že se jedná o DS1307, jak vyplývá z kódu ve vaší otázce. Podívejte se na datový list RTC.Na stránce 6 je tabulka s názvem „Popis kolíku“. Z této tabulky:
připnout : 7
name : SQW / OUT
funkce : Square Wave / Output Driver. Pokud je povolen, bit SQWE nastaven na 1, výstup SQW / OUT na výstupu má jednu ze čtyř čtvercových vln (1 Hz, 4 kHz, 8 kHz, 32 kHz). Pin SQW / OUT je otevřený odtok a vyžaduje externí pullup odpor. SQW / OUT pracuje buď s V CC nebo V BAT . Vytahovací napětí může být až 5,5 V bez ohledu na napětí na V CC . Pokud není použit, může tento pin zůstat plovoucí.
Pokud používáte RTC modul , budete muset zjistit kde je tento pin vystaven na konektoru modulu.
V každém případě budete muset povolit 1 Hz výstup obdélníkového tvaru pomocí
RTC.writeSqwPinMode(DS1307_SquareWave1HZ);
Upravit 2 : Komentování aktualizace otázky:
// Set the RTC Time to 5:10:30 Nov 3 2020 RTC.adjust(DateTime(2020,11,3,5,10,30));
Správně.
// Set Arduino Time Library different than RTC time 9:27:05 setTime(9, 27, 05, 14, 07, 2015);
Správně. Datum je 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();
Ne. Toto je pouze částečná inicializace tm
proměnná. Nemá to žádný vliv na představu, kterou má knihovna Time o aktuálním čase. Upozorňujeme, že pole s datem tm
nebyla v tomto okamžiku inicializována a mohla by být neplatná (například 23. měsíc, den 125).
setSyncProvider(RTC.now);
To je nesprávné a mělo být vygenerováno upozornění kompilátoru. setSyncProvider()
očekává funkci, která vrací aktuální čas jako Unixový čas (jednoduché celé číslo typu time_t
). Poskytujete funkci, která vrací aktuální čas v rozepsané podobě (rok, měsíc …) s typem DateTime
. Knihovna času tomu nerozumí a může přinést odpadky, například 18:00:00.
Čas vrácený RTC.now()
lze převést na čas Unixu pomocí metody unixtime()
. Proto jsem vám dal funkci time_provider()
.
Také byste neměli volat setSyncProvider()
a setSyncInterval()
při každé iteraci smyčky. Proveďte to jednou provždy v setup()
.
// Time Library time updates to RTC every 5 seconds tm.Hour = hour(); tm.Minute = minute(); tm.Second = second();
Znovu aktualizuje pouze proměnnou tm
. Nemá to žádný vliv na to, o čem se knihovna Time domnívá, že je aktuální čas.
Odpověď
Existuje v RTCLib ekvivalentní funkce jako setSyncProvider (RTC.get) v knihovně DS1307RTC?
Existuje ekvivalent k setSyncInterval (5000)
To jsou funkce TimeLib. Neexistuje ekvivalent “ “ protože používáte TimeLib.
První očekává pouze ukazatel na funkci, která r eturns a time_t
. Co je v této funkci, je na vás.
Který RTCLib mám vyvolat? V příkladech se používá několik:
Velká písmena by se měla shodovat s názvem souboru záhlaví. Windows to nezajímá a OS X to obvykle nezajímá, ale lze jej nakonfigurovat. Linux se stará a potřebuje, aby odpovídal. Pokud chcete, aby byl váš kód přenosný, musíte velká písmena ponechat stejná jako v souboru.
a někdy také vyvolat jednu z těchto možností:
Musíte vytvořit objekt, který odpovídá vašemu fyzickému RTC.
a. Jsou tmElements_t tm součástí knihovny DS1307RTC?
Ne. Jsou součástí TimeLib.
b. Jsou to tm.Hour tm.Minute z RTC?
Jsou tím, čemu je přiřazena funkce, která se volá. Jsou to jen proměnné. Mohou obsahovat cokoli.
c. Existuje ekvivalent v RTClib.h?
Ne. Ale pak už nemusíte být, pokud používáte TimeLib.
Takže: musíte
- Vytvořit funkci, která získá čas z RTC prostřednictvím jakékoli knihovny, kterou chcete použít (například RTCLib) a vypočítá počet sekund od 00:00:00 1. 1. 1970, kterou poté vrací jako
time_t
. - předat to TimeLib „s
setSyncProvider()
- Nastavte frekvenci synchronizace pomocí třídy
setSyncInterval()
.
Komentáře
-
now
je čas z RTC v okamžiku, kdy přiřadíte objektnow
..hour()
je pouze hodina obsažená v tomto objektu.hour()
je čas z knihovny TimeLib, ano. setSyncProvider () doesn ‚ Nezasílá nic do RTC, pravidelně získává čas z RTC a aktualizuje TimeLib o aktuální čas. - It ‚ je o něco složitější. TimeLib používá
millis()
sledovat čas. Pravidelně aktualizuje svou interní představu o tom, jaký je čas, v závislosti nasetSyncInterval()
. když požádáte ohour()
, pokud od posledního získání více času uplynulo v reálném čase, který jste zadali vsetSyncInterval()
, půjde čas z RTC. Jinak vám řekne, co si myslí čas podle vlastních interních výpočtů. - Aktualizoval jsem svůj příspěvek s pomocí nápovědy. Skoro to chápete.
- Protože ‚ neustále měníte poskytovatele synchronizace a interval. Nastavíte je jednou a jednou pouze v nastavení a už nikdy.
- To vypadá dobře, ano. Ačkoli vůbec ‚ nepotřebujete strukturu
tmElements_t
, protože vše, co ‚ řešíte s je jednoduchá čísla.tmElements_t
je jen vhodný způsob, jak je spojit dohromady, pokud je chcete předat jiné funkci. JenSerial.print(hour());