Bibliothèque de temps Arduino et bibliothèques RTC

Jutilise RTClib.h et TimeLib.h avec un Uno.

Jai du mal depuis des jours pour comprendre les différentes bibliothèques RTC disponibles et comment les utiliser avec la bibliothèque de temps Arduino.

Question 1 .
Si je ne veux pas créer un nouvel objet now () à chaque fois dans la boucle, comment synchroniser la bibliothèque temporelle avec le RTC toutes les x secondes? Chaque fois que jessaye dutiliser la fonction RTClib now.hour now.minute, etc., cela moblige à utiliser DateTime now = RTC.now () pour créer lobjet now ().

Existe-t-il une fonction équivalente dans RTCLib comme setSyncProvider (RTC.get) dans la bibliothèque DS1307RTC?

Existe-t-il un équivalent à setSyncInterval (5000)

Question 2 .
Quel RTCLib dois-je appeler? Il y en a plusieurs utilisés dans les exemples:

< RTClib.h >

 » RTClib  » en utilisant des guillemets

< RTCLib.h > avec L majuscule

et parfois aussi en appelant lun de ceux-ci:

RTC_DS1307 RTC

ou RTC_DS1307 rtc

ou RTC_DS3231 rtc

Question 3
a. TmElements_t tm fait-il partie de la bibliothèque DS1307RTC?
b. Sagit-il de tm.Hour tm.Minute du RTC?
c. Y a-t-il un équivalent dans le RTClib.h?

Et enfin jai posté un code ci-dessous juste pour montrer mon utilisation:

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

Mis à jour le 5 novembre 2020

Je pense avoir presque compris. Sil vous plaît laissez-moi savoir si ce code fait ce que je pense quil fait, en particulier:

Dans la configuration:
Réglez le RTC sur 5:10:30.
Réglez la bibliothèque de temps sur 9:27:05 avec setTime ().
Réglez Time Library sur lheure RTC avec DateTime maintenant (au lieu de 9:27:05)?
Définissez les variables Time Library sur RTC en utilisant tm.Hour = now. Heure, etc.

En boucle:
Toutes les 5 secondes, mise à jour heure (), minute () seconde () avec heure RTC.
Chaque boucle mise à jour tm.hour avec heure () , etc.

Je sais que ce nest toujours pas correct puisque les impressions en série montrent tm.Hour, tm.Minute en alternant chaque boucle comme indiqué en bas.

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

Impressions série:

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 

Réponse

Permettez-moi dabord de vous donner un aperçu de ces bibliothèques.

La bibliothèque Time utilise millis() pour chronométrage. Étant donné que cela peut être sujet à une dérive significative, il fournit un moyen de se synchroniser périodiquement avec un fournisseur de temps externe. Doù les fonctions setSyncProvider() et setSyncInterval().

RTClib est destiné à interfacer un RTC. Il ne fournit pas de chronométrage à lui seul: vous obtenez lheure actuelle en interrogeant un RTC via sa méthode « s now().

Ces deux bibliothèques peuvent parfaitement compléter chacune autre, car RTClib peut être utilisé comme fournisseur de temps pour la bibliothèque Time:

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

Si je ne veux pas créer un nouvel objet now () […]

Il est en fait appelé un objet DateTime.

Y a-t-il un équivalent [à tmElements_t] dans le RTClib

Oui, le DateTime class . Notez que, contrairement à la structure tmElements_t, les champs de données de DateTime ne le sont pas public, et vous devez utiliser des accesseurs pour les obtenir: year(), month(), day()

Méthode alternative de chronométrage

Puisque vous utilisez un Arduino Uno, il existe une troisième méthode de chronométrage que vous pouvez veux considérer. Au lieu dinterroger le RTC à chaque itération de boucle (RTClib) ou dinterpoler les lectures du RTC avec millis() (bibliothèque de temps), vous pouvez router une sortie 1 Hz du RTC vers une broche dinterruption, et comptez les secondes dans lISR. Le code de synchronisation avr-libc est conçu pour fournir un chronométrage de cette manière. Tout se résume à:

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

Pour plus de détails, voir lexemple desquisse interrupts1Hz.ino fourni avec RTClib.


Modifier 1 : Répondre à un commentaire

À quelle broche [la broche dinterruption Arduino] se connecte-t-elle sur le RTC?

Cela dépend du RTC que vous utilisez. Je suppose que cest un DS1307, comme lindique le code de votre question. Jetez un œil à la fiche technique du RTC.À la page 6, il existe un tableau intitulé «Description des broches». À partir de ce tableau:

pin : 7
nom : SQW / OUT
fonction : onde carrée / pilote de sortie. Lorsquelle est activée, le bit SQWE est réglé sur 1, la broche SQW / OUT émet lune des quatre fréquences donde carrée (1 Hz, 4 kHz, 8 kHz, 32 kHz). La broche SQW / OUT est à drain ouvert et nécessite une résistance de rappel externe. SQW / OUT fonctionne avec V CC ou V BAT appliqué. La tension de pullup peut atteindre 5,5 V quelle que soit la tension sur V CC . Si elle nest pas utilisée, cette broche peut être laissée flottante.

Si vous utilisez un module RTC, vous devrez comprendre où cette broche est exposée sur le connecteur du module.

Dans tous les cas, vous devrez activer la sortie donde carrée 1 Hz avec

 RTC.writeSqwPinMode(DS1307_SquareWave1HZ);  

Modifier 2 : Commenter la mise à jour de la question:

 // 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. La date est le 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();  

Non. Cela ne initialise que partiellement le tm variable. Cela na aucun effet sur lidée que la bibliothèque Time se fait de lheure actuelle. Notez que les champs de date de tm nont pas été initialisés à ce stade et pourraient bien être invalides (comme le mois 23, le jour 125).

 setSyncProvider(RTC.now);  

Ceci est incorrect et devrait avoir généré un avertissement du compilateur. setSyncProvider() attend une fonction qui renvoie lheure actuelle sous forme dheure Unix (un entier simple, de type time_t). Vous fournissez une fonction qui renvoie lheure actuelle sous forme décomposée (année, mois …), de type DateTime. La bibliothèque Time ne comprendra pas cela et peut produire des déchets comme, par exemple, 18:00:00.

Lheure renvoyée par RTC.now() peut être convertie en heure Unix avec la méthode unixtime(). Cest pourquoi je vous ai donné la fonction time_provider().

De plus, vous nêtes pas censé appeler setSyncProvider() et setSyncInterval() à chaque itération de boucle. Faites-le une fois pour toutes dans setup().

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

Encore une fois, ceci met uniquement à jour la variable tm. Cela na aucun effet sur ce que la bibliothèque Time considère comme lheure actuelle.

Réponse

Existe-t-il une fonction équivalente dans RTCLib comme setSyncProvider (RTC.get) dans la bibliothèque DS1307RTC?

Existe-t-il un équivalent à setSyncInterval (5000)

Ce sont des fonctions TimeLib. Il ny a pas de  » équivalent à  » puisque vous utilisez TimeLib.

Le premier attend juste un pointeur vers une fonction qui r et renvoie un time_t. Ce qui est dans cette fonction dépend de vous.

Quel RTCLib dois-je appeler? Il y en a plusieurs utilisés dans les exemples:

La majuscule doit correspondre au nom du fichier den-tête. Windows ne se soucie pas, et OS X ne se soucie généralement pas, mais peut être configuré pour. Linux sen soucie et en a besoin pour correspondre. Si vous voulez que votre code soit portable, vous devez conserver la même majuscule que le fichier.

et parfois aussi appeler lun de ceux-ci:

Vous devez créer un objet qui correspond à votre RTC physique.

a. TmElements_t tm fait-il partie de la bibliothèque DS1307RTC?

Non. Ils font partie de TimeLib.

b. Sagit-il de tm.Hour tm.Minute du RTC?

Ce sont tout ce qui leur est assigné par une fonction qui est appelée. Ce ne sont que des variables. Ils peuvent contenir nimporte quoi.

c. Y a-t-il un équivalent dans le RTClib.h?

Non. Mais alors vous n « avez pas besoin d » y avoir si vous utilisez TimeLib.

Donc: vous devez

  • Créer une fonction qui récupère lheure du RTC à travers la bibliothèque que vous voulez utiliser (RTCLib par exemple) et calcule le nombre de secondes depuis 00:00:00 01/01/1970, quil renvoie ensuite sous forme de time_t.
  • Transmettez-le à TimeLib « s setSyncProvider()
  • Définissez une fréquence de synchronisation avec setSyncInterval().

Commentaires

  • now est lheure du RTC au moment où vous attribuez lobjet now. .hour() est juste lheure contenue dans cet objet. hour() est lheure de la bibliothèque TimeLib, oui. setSyncProvider () ne ‘ t envoyer quoi que ce soit au RTC, il obtient lheure du RTC régulièrement et met à jour le TimeLib avec lheure actuelle.
  • It ‘ est un peu plus complexe que cela. TimeLib utilise millis() pour garder une trace de lheure. Il met régulièrement à jour son idée interne de ce que lheure dépend de setSyncInterval(). lorsque vous demandez hour(), si plus de temps sest écoulé depuis la dernière fois que vous avez obtenu le temps réel que vous avez spécifié dans setSyncInterval(), il ira chercher lheure du RTC. Sinon, il vous dira simplement ce quil pense de lheure selon ses propres calculs internes.
  • Jai mis à jour mon message avec laide fournie. Je lai presque compris.
  • Parce que vous ‘ changez constamment le fournisseur et lintervalle de synchronisation. Vous ne les définissez quune seule fois dans la configuration, et plus jamais.
  • Cela semble correct, oui. Bien que vous nayez ‘ pas besoin de la structure tmElements_t puisque tout ce que vous ‘ traitez avec des nombres simples. tmElements_t est juste un moyen pratique de les regrouper si vous voulez le passer à une autre fonction. Juste Serial.print(hour());

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *