Sto usando RTClib.he TimeLib.h con uno Uno.
Ho lottato per giorni per comprendere le varie librerie RTC disponibili e come utilizzarle con Arduino Time Library.
Domanda 1 .
Se non voglio creare un nuovo oggetto now () ogni volta attraverso il ciclo, come faccio a sincronizzare la Time Library con lRTC ogni x secondi? Ogni volta che provo a utilizzare la funzione RTClib now.hour now.minute ecc.Mi richiede di utilizzare DateTime now = RTC.now () creando loggetto now ().
Esiste una funzione equivalente in RTCLib come setSyncProvider (RTC.get) nella libreria DS1307RTC?
Esiste un equivalente a setSyncInterval (5000)
Domanda 2 .
Quale RTCLib dovrei chiamare? Ce ne sono diversi usati negli esempi:
< RTClib.h >
” RTClib ” utilizzando le virgolette
< RTCLib.h > con la L maiuscola
e talvolta anche chiamando uno di questi:
RTC_DS1307 RTC
o RTC_DS1307 rtc
o RTC_DS3231 rtc
Domanda 3
a. TmElements_t tm fa parte della libreria DS1307RTC?
b. Sono queste tm.Hour tm.Minute dallRTC?
c. Cè un equivalente in RTClib.h?
E finalmente ho pubblicato del codice qui sotto solo per mostrare il mio utilizzo:
#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); }
Aggiornato il 5 novembre 2020
Penso di aver quasi capito. Per favore fatemi sapere se questo codice sta facendo quello che penso stia facendo, in particolare:
In Setup:
Imposta RTC a 5:10:30.
Imposta Time Library su 9:27:05 con setTime ().
Imposta la libreria dellora sullora RTC con DateTime adesso (scrivendo 9:27:05)?
Imposta le variabili della libreria dellora su RTC usando tm.Hour = now. Ora, ecc.
In loop:
Ogni 5 secondi aggiorna hour (), minute () second () con lora RTC.
Ogni loop aggiorna tm.hour con hour () , ecc.
So che non è ancora corretto poiché le stampe seriali mostrano tm.Hour, tm.Minute alternando ogni ciclo come mostrato in basso.
#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); }
Stampe seriali:
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
Risposta
Per prima cosa vorrei fornire alcune informazioni di base su queste librerie.
La libreria Time utilizza millis()
per cronometraggio. Poiché questo può essere soggetto a deviazioni significative, fornisce un mezzo per sincronizzarsi periodicamente con un provider di servizi orari esterno. Da qui le funzioni setSyncProvider()
e setSyncInterval()
.
RTClib ha lo scopo di interfacciare un RTC. Non fornisce il cronometraggio da solo: si ottiene lora corrente interrogando un RTC tramite il metodo “s now()
.
Queste due librerie possono integrarsi perfettamente altro, poiché RTClib può essere utilizzato come fornitore di orari per la libreria Time:
// Provide the RTC time to the Time library. time_t time_provider() { return RTC.now().unixtime(); } void setup() { // ... setSyncProvider(time_provider); }
Se non voglio creare un nuovo oggetto now () […]
In realtà si chiama DateTime
oggetto.
Esiste un equivalente [a
tmElements_t
] in RTClib
Sì, DateTime
class . Tieni presente che, a differenza della struttura tmElements_t
, i campi dati di DateTime
non lo sono public e devi utilizzare le funzioni di accesso per ottenerle: year()
, month()
, day()
…
Metodo di cronometraggio alternativo
Dato che stai usando un Arduino Uno, esiste un terzo metodo di cronometraggio che puoi voglio considerare. Invece di interrogare lRTC su ogni iterazione del loop (RTClib) o interpolare le letture dellRTC con millis()
(libreria temporale), puoi indirizzare unuscita a 1 Hz dellRTC a un pin di interrupt, e conta i secondi nellISR. Il codice di temporizzazione avr-libc è progettato per fornire il cronometraggio in questo modo. Tutto si riduce a:
// 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);
Per maggiori dettagli, guarda lo schizzo di esempio interrupts1Hz.ino fornito con RTClib.
Modifica 1 : Risposta a un commento
a quale pin si collega [il pin di interruzione di Arduino] sullRTC?
Dipende dallRTC che stai utilizzando. Presumo che sia un DS1307, come implica il codice nella tua domanda. Dai unocchiata al datasheet dellRTC.A pagina 6, è presente una tabella intitolata “Descrizione pin”. Da questa tabella:
pin : 7
name : SQW / OUT
: onda quadra / driver di uscita. Quando è abilitato, il bit SQWE è impostato su 1, il pin SQW / OUT emette una delle quattro frequenze a onda quadra (1Hz, 4kHz, 8kHz, 32kHz). Il pin SQW / OUT è a drain aperto e richiede un resistore pullup esterno. SQW / OUT funziona con V CC o V BAT applicato. La tensione di pullup può arrivare fino a 5,5 V indipendentemente dalla tensione su V CC . Se non viene utilizzato, questo pin può essere lasciato flottante.
Se stai usando un modulo RTC, dovrai capire dove è esposto questo pin sul connettore del modulo.
In ogni caso, dovrai abilitare luscita a onda quadra da 1 Hz con
RTC.writeSqwPinMode(DS1307_SquareWave1HZ);
Modifica 2 : commento sullaggiornamento alla domanda:
// Set the RTC Time to 5:10:30 Nov 3 2020 RTC.adjust(DateTime(2020,11,3,5,10,30));
Corretto.
// Set Arduino Time Library different than RTC time 9:27:05 setTime(9, 27, 05, 14, 07, 2015);
Esatto. La data è 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();
No. Questo sta inizializzando solo parzialmente tm
variabile. Non ha alcun effetto sullidea che la libreria Time ha dellora corrente. Tieni presente che i campi della data di tm
non sono stati inizializzati a questo punto e potrebbero non essere validi (come il mese 23, giorno 125).
setSyncProvider(RTC.now);
Ciò non è corretto e dovrebbe aver generato un avviso del compilatore. setSyncProvider()
si aspetta una funzione che restituisca lora corrente come ora Unix (un numero intero semplice, di tipo time_t
). Stai fornendo una funzione che restituisce lora corrente in forma scomposta (anno, mese …), con il tipo DateTime
. La libreria Time non lo capirà e potrebbe produrre spazzatura come, ad esempio, 18:00:00.
Lora restituita da RTC.now()
può essere convertita in tempo Unix con il metodo unixtime()
. Ecco perché ti ho fornito la funzione time_provider()
.
Inoltre, non dovresti chiamare setSyncProvider()
e setSyncInterval()
a ogni iterazione del ciclo. Fallo una volta per tutte in setup()
.
// Time Library time updates to RTC every 5 seconds tm.Hour = hour(); tm.Minute = minute(); tm.Second = second();
Di nuovo, questo sta solo aggiornando la variabile tm
. Non ha alcun effetto su ciò che la libreria Time ritiene essere lora corrente.
Risposta
Esiste una funzione equivalente in RTCLib come setSyncProvider (RTC.get) nella libreria DS1307RTC?
Esiste una equivalente a setSyncInterval (5000)
Queste sono funzioni TimeLib. Non esiste ” equivalente a ” poiché stai utilizzando TimeLib.
Il primo si aspetta solo un puntatore a una funzione che r restituisce un time_t
. Che cosa cè in quella funzione dipende da te.
Quale RTCLib dovrei chiamare? Ce ne sono diversi usati negli esempi:
Le lettere maiuscole devono corrispondere al nome del file di intestazione. A Windows non interessa, e OS X di solito non si preoccupa, ma può essere configurato per farlo. Linux se ne frega e ha bisogno che corrisponda. Se vuoi che il tuo codice sia portabile, devi mantenere le maiuscole uguali a quelle del file.
e talvolta anche chiamare uno di questi:
Devi creare un oggetto che corrisponda al tuo RTC fisico.
a. TmElements_t tm fa parte della libreria DS1307RTC?
No. Fanno parte di TimeLib.
b. Sono questi tm.Hour tm.Minute dallRTC?
Sono tutto ciò che viene loro assegnato da una funzione chiamata. Sono solo variabili. Possono contenere qualsiasi cosa.
c. Esiste un equivalente in RTClib.h?
No. Ma poi non è necessario che ci sia se stai usando TimeLib.
Quindi: devi
- Creare una funzione che prenda lora dallRTC attraverso qualsiasi libreria tu voglia usare (RTCLib per esempio) e calcoli il numero di secondi dalle 00:00:00 del 01/01/1970, che poi restituisce come
time_t
. - Passa a TimeLib “s
setSyncProvider()
- Imposta una frequenza di sincronizzazione con
setSyncInterval()
.
now
è lora dallRTC nel momento in cui assegni loggettonow
..hour()
è solo lora contenuta allinterno di quelloggetto.hour()
è lora dalla libreria TimeLib, sì. setSyncProvider () non ‘ Non inviare nulla allRTC, riceve regolarmente lora dallRTC e aggiorna TimeLib con lora corrente.millis()
per tenere traccia del tempo. Aggiorna regolarmente la sua idea interna di ciò che il tempo dipende dasetSyncInterval()
. quando chiedihour()
, se è trascorso più tempo dallultima volta che ha ottenuto il tempo reale specificato insetSyncInterval()
, verrà visualizzato lora dallRTC. Altrimenti ti dirà solo cosa pensa che sia il tempo in base ai suoi calcoli interni.tmElements_t
struct poiché tutti ‘ hai a che fare con i numeri semplici.tmElements_t
è solo un modo conveniente per raggrupparli tutti insieme se vuoi passarli a unaltra funzione. SoloSerial.print(hour());