[partage]Librairie simpleRTC (DS1307 / DS3231) avec heures été/hiver

Bonjour

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

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

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

simpleRTC.zip (12.6 KB)

Bien joué , moi j'ai fait le feignant et juste un " temps.hour() = temps.hour() + 1 ; :D

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

Bonjour Bricoleau,

Beau travail, mais j'ai une petite question: Y a t'il une raison pour que tu utilises le pointeur this? Car

    uint8_t annee() const       {return this->_annee;}

et

   uint8_t annee() const       {return _annee;}

sont équivalents

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)

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.

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

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.

:) merci pour ce travail mis à disposition :)

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

#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.

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

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

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

corriger par

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

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 :

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 :

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 :

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?

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!

bonjour Dommage j'ai une 1302 :'(

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.

bonjour

  1. créer une variante de la bibliothèque simpleRTC qui fonctionne en SPI. Le code sera à 90% similaire.

ho, la,la je suis pas au niveau, malheureusement.

  1. remplacer le DS1302 par un DS3231 qui coûte une misère.

surement la plus sage solution… Mais bon sang j’ai déjà attendu deux mois mes Ardruino (clones).
Enfin j’avoue vos “petites” bibliothèque son tout simplement géniales. Merci de les avoir mis a notre disposition
alain

Déterrage:

pour avoir commencer avec un ds1302, je suis vite passé au ds3231 car le ds1302 n'est pas précis. je me demande pourquoi c'est encore vendu. Bon, mon ds1302 n'est pas perdu. j'ai utilisé le support de pile pour remplacer la pile bios bizarre d'un vieux pc compaq . Achetez le ds3231 et surtout pas le ds1302

Merci pour le code.

Bonjour, C'est vrai que le DS3231 est plus précis. Dans les faits,c'est surtout son oscillateur interne qui est précis. En utilisant le ds1302 avec un oscillateur du type ASH7KW qui a une dérive inférieur à 5PPM sur la plage de température 15-30°C,l'horloge aura une dérive de moins de 3mns/An.

  • Une revue d'électronique "ELE**** " a traité ce sujet dans la dernière revue parue. Bonne bidouille.

Salut et merci de partager votre taff ;D

j ' ai regarder les exemples fournis dans la bibliotheque et en particulier exemple auto et reglage manuel mais bon , ils sont trop fournis je trouve , du coup on perd de vu ce qu on cherche dans le code .

je n' ai pas vraiment trouver ce que je cherche pour le moment .

je voudrais mettre a jour mon RTCDS1307 par un serveur NTP une fois par jour .

alors dans le fichier source j ' ai bien vu cette methode :

bool simpleRTC::reglerNTP(uint32_t temps_unix)

mais ca donne l ' impression de faire l' inverse ... ca parait un peu aberant mais bon regler son serveur NTP avec un arduino pourquoi pas apres tout ! a condition d' avoir un serveur NTP ok , bon je sors =>>

je crois que je suis fatigué et que je suis plus en etat :grin:

je regarderai mieux demain .

Bonjour

Tu es la toute première personne qui indique que je mets trop d'exemples dans mes lib. D'habitude les retours sont plutôt le contraire.

Pour tes autres remarques, je te laisse remettre les yeux en face des trous. :)