Go Down

Topic: [partage]Librairie simpleRTC (DS1307 / DS3231) avec heures été/hiver (Read 9999 times) previous topic - next topic

bricoleau

Bonjour

Petite librairie facile d'utilisation, pour ceux qui ont du remettre à l'heure leur DS1307 ou leur DS3231 le week end dernier  :D

La gestion des heures d'été / hiver est intégrée à la librairie, et calée sur l'heure de France Métropolitaine.
Les changements d'heure sont automatiques.

De surcroît, la librairie facilite la mise à jour par protocole NTP ou par protocole DCF77.

Voir aussi les exemples fournis

Header
Code: [Select]
class simpleRTC
{
  public :
    //Principales méthodes d'accès au circuit externe
    //Retournent true si accès ok, false sinon

    bool actualiser();
         //Actualisation des variables privées par lecture du circuit externe.
         //Idéalement : à exécuter une fois par seconde

    bool regler(uint8_t annee, uint8_t mois, uint8_t jour, uint8_t heure, uint8_t minute, uint8_t seconde);
         //Mise à jour à partir de valeurs date heure locales

    //Méthodes constantes pour consultation de l'horloge
    uint8_t annee() const       {return this->_annee;}
    uint8_t mois() const        {return this->_mois;}
    uint8_t jour() const        {return this->_jour;}
    uint8_t jourSemaine() const {return this->_joursem;} //0 dimanche, 1 lundi, 2 mardi, ...
    uint8_t heure() const       {return this->_heure;}
    uint8_t minute() const      {return this->_minute;}
    uint8_t seconde() const     {return this->_seconde;}

    bool heureEte() const       {return this->_ete;} //Permet de savoir si on est en heures d'été ou d'hiver


    //Méthodes secondaires
    //Retournent true si accès ok, false sinon

    bool reglerUTC(uint8_t annee, uint8_t mois, uint8_t jour, uint8_t heure, uint8_t minute, uint8_t seconde);
         //Mise à jour à partir de valeurs date heure UTC

    bool reglerNTP(uint32_t temps_unix);
         //Mise à jour dans le cadre d'une synchro NTP (secondes écoulées depuis le 01/01/1970 00:00:00 UTC)

    bool reglerDCF77(uint8_t annee, uint8_t mois, uint8_t jour, uint8_t heure, uint8_t minute, bool ete);
         //Mise à jour dans le cadre d'une synchro DCF77 (signal radio heure locale + indic heure d'été)

    uint8_t anneeUTC() const {return this->_anneeUTC;}
    uint8_t moisUTC() const  {return this->_moisUTC;}
    uint8_t jourUTC() const  {return this->_jourUTC;}
    uint8_t heureUTC() const {return this->_heureUTC;}

  private :
    void    _memoriser(uint8_t annee, uint8_t mois, uint8_t jour, uint8_t heure);
    uint8_t _annee, _mois, _jour, _joursem, _heure, _minute, _seconde;
    uint8_t _anneeUTC, _moisUTC, _jourUTC, _heureUTC;
    bool    _ete;
};
Tutoriels arduino : http://forum.arduino.cc/index.php?topic=398112.0

BrUnO14200

Bien joué , moi j'ai fait le feignant et juste un " temps.hour() = temps.hour() + 1 ; :D
Gimball home made  :https://forum.arduino.cc/index.php?topic=644439.0

rjnc38

trop fort Bricoleau !!!

le décorticage de la date NTP m'a pris 150 lignes de code (et beaucoup d'aspirine), la ou toi tu le fais en 20 lignes

chapeau bas

kamill

Bonjour Bricoleau,

Beau travail, mais j'ai une petite question: Y a t'il une raison pour que tu utilises le pointeur this? Car
Code: [Select]
    uint8_t annee() const       {return this->_annee;}
et
Code: [Select]
   uint8_t annee() const       {return _annee;}
sont équivalents

bricoleau

Bonjour,

C'est juste une habitude de coding, pour différencier les propriétés de l'objet par rapport aux autres variables.
A priori cela ne change rien au compilé (enfin j'espère  :P )

Pour les cas très simples, je remonte le corps de la fonction dans le header pour donner au compilo la possibilité de la mettre en inline là où elle est appelée (si je ne trompe pas : le inline est alors implicite, mais c'est le compilo qui décide de son application)
Tutoriels arduino : http://forum.arduino.cc/index.php?topic=398112.0

kamill

Effectivement je pense aussi que ça ne change rien au code généré. C'était juste pour savoir la raison de l'utilisation de this.

bricoleau

trop fort Bricoleau !!!

le décorticage de la date NTP m'a pris 150 lignes de code (et beaucoup d'aspirine), la ou toi tu le fais en 20 lignes

chapeau bas

Oups j'avais pas vu

Merci !!!!!

Perso c'est l'optimisation du calcul du jour de la semaine qui m'a fait le plus transpirer ;D
Je ne vois pas comment on pourrait le faire en moins de ticks.

Toutes ces fonctions ont été testées du 01/01/2000 au 31/12/2099 en vérifiant la validité du résultat pour chaque jour.
Tutoriels arduino : http://forum.arduino.cc/index.php?topic=398112.0

dfgh


bricoleau

Petit complément : pour maîtriser facilement le délai d'une seconde entre chaque actualisation de l'horloge, je conseille d'utiliser la librairie simpleMinuteur.h

Code: [Select]
#include "simpleRTC.h"
#include "simpleMinuteur.h"

simpleMinuteur synchroRTC(1000);

void setup()
{
  Wire.begin();
  ...
  synchroRTC.demarrer();
  RTC.actualiser();
}

void loop()
{
  if (synchroRTC) RTC.actualiser();
  ...
}


Et à partir de là, il n'y a plus à ce soucier du RTC.
Les dates / heures sont à jour en permanence, et disponibles en consultation par le reste du code.
Tutoriels arduino : http://forum.arduino.cc/index.php?topic=398112.0

luckymaxou

Bonjour,
je suis débutant et je me suis pris la tête gravement avec DOW sur la librairie RTClib, sans y arriver.
j'ai trouvé sur les forums plein de solutions beaucoup trop compliquées pour moi.
Avec ta librairie simpleRTC c'est GENIAL.
MERCI BEAUCOUP Bricoleau

ppzikos

#10
Dec 22, 2017, 11:24 pm Last Edit: Dec 23, 2017, 06:41 pm by ppzikos Reason: bug autre que la librairie , Certainement du à mon environement de travail
Bonjour bricoleau , merci beaucoup pour votre travail et pour votre partage.
j'ai trouver un petit bug qui empêche l'exécution du code permettant la mise à jour par Timestamp unix

Dans le fichier simpleRTC.cpp , Fonction: simpleRTC::reglerNTP(uint32_t temps_unix)

à la ligne 262
Code: [Select]
accesOK = this->reglerUTC(annee, mois, (uint8_t)jours, heure, minute, seconde);
corriger par
Code: [Select]
accesOK = this->reglerUTC(annee, mois, jours, heure, minute, seconde);


testé fonctionnel sur ESP32(vroom) avec ds3231 ,arduino 1.8.2

en tous cas un grand merci du fond du cœur pour la lib sur les ephemeride
http://forum.arduino.cc/index.php?topic=275902.0
et pour cette lib sur le rtc avec mise à jour timestamp , correction heure ete/hiver et gestion utc+1.

mon projet : une lampe qui s'allume en fonction du lever du soleil pour recréer un climat spécifique.
Merci a vous bricoleau

bricoleau

Fichtre !

Une ano dans ma bibliothèque?  ;D

J'ai vérifié et pourtant ça a l'air correct, au moins sur arduino.
Je suspecte une différence de compilo.

Dans la fonction reglerNTP(), la variable jours contient au départ le quantième dans l'année
Sa valeur initiale va de 1 à 366, d'où le fait qu'elle est déclarée en uint16_t

Ensuite, à partir de ce quantième, le programme calcule le mois et le jour dans le mois, de manière très simple :
Code: [Select]
uint8_t mois = 1;
uint8_t duree_mois = _RTCnbJoursMois(annee, mois);
while (jours > duree_mois)
{
  jours -= duree_mois;
  mois++;
  duree_mois = _RTCnbJoursMois(annee, mois);
}

à partir de là, la variable jours a une valeur comprise entre 1 et 31
Mais elle est toujours stockée sur deux octets en uint16_t

Pour la passer en paramètre d'appel de la fonction reglerUTC(), qui attend le jour du mois sur un seul octet en uint8_t, j'ai "casté" le type :
Code: [Select]
accesOK = this->reglerUTC(annee, mois, (uint8_t)jours, heure, minute, seconde);

Je ne vois vraiment pas ce qui pourrait clocher avec ça.

Pour isoler/reproduire le problème et tenter de comprendre ce qui pourrait clocher, je viens de passer ce code sur un arduino :
Code: [Select]
void setup() {
  Serial.begin(115200);
  uint16_t jours = 312;
  while (jours > 256) jours -= 30; //après quoi : jours = 252
  afficher((uint8_t)jours);
  afficher(jours);
}

void afficher(uint8_t jours) {
  Serial.println(jours);
}

void loop(){}


Ca compile, et ça affiche bien deux fois 252 sur le terminal

L'équivalent donnerait quoi sur l'esp32?
Tutoriels arduino : http://forum.arduino.cc/index.php?topic=398112.0

ppzikos

Sa fonctionne , le serial me répond 2 fois 252.

je vient de re-tester avec la ligne 262=

accesOK = this->reglerUTC(annee, mois, (uint8_t)jours, heure, minute, seconde);

et cette fois ci sa fonctionne impeccable , je doit avoir un bug dans mon IDE.

Hier j'ai fait la manip 2 fois et à chaque fois il fallait que je modifie la ligne 262 pour que sa fonctionne.
Je pense que je devrait réinstaller mon ide a neuf.

En tout cas vous faite vraiment un travail formidable et c'est très plaisant!


bricoleau

Bonjour

Effectivement, les DS1307 et DS3231 utilisent une interface de communication I2C, alors que le DS1302 est en SPI.

Deux options :
1) créer une variante de la bibliothèque simpleRTC qui fonctionne en SPI. Le code sera à 90% similaire.
2) remplacer le DS1302 par un DS3231 qui coûte une misère.
Tutoriels arduino : http://forum.arduino.cc/index.php?topic=398112.0

Go Up