Go Down

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

alaindepicardie

bonjour
Quote
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.

Quote
2) 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
http://forum.arduino.cc/index.php?topic=398112.0

pomme-poire

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.
 

Leptro

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.

iznobe

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 :
Code: [Select]
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  :smiley-mr-green:

je regarderai mieux demain .
serveur relais volets arrosage heures creuse : https://forum.arduino.cc/index.php?topic=493039.0

bricoleau

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.  :)
Tutoriels arduino : http://forum.arduino.cc/index.php?topic=398112.0

bricoleau

Ce dev un peu vieux, donc je viens de vérifier : les exemples fournis avec la lib sont classés & numérotés & avec un titre qui me semble assez clair.
Ils sont censés montrer les principaux cas d'usage, pas seulement celui qui t'amène ici.

Cette lib ne prend pas en charge la communication NTP : elle gère un DS1307 ou un DS3231.

L'interrogation NTP que tu dois mettre en place dans ton programme, te permet de récupérer l'heure UTC sous forme d'un timestamp Unix, c'est-à-dire un entier long non signé.

C'est cette valeur qu'il faut passer en paramètre d'appel de la méthode ci-dessous et hop ! ton RTC est à la bonne date et heure.

Code: [Select]
    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)
Tutoriels arduino : http://forum.arduino.cc/index.php?topic=398112.0

lesept

Je me suis permis d'extraire la fonction "heure d'été" pour aider un membres du forum qui voulait juste cette information. Merci Bricoleau !
A force d'essayer on finit par réussir... Donc, plus ça rate, plus on a de chances que ça marche (proverbe Sharduinok).

iznobe

Ce dev un peu vieux, donc je viens de vérifier : les exemples fournis avec la lib sont classés & numérotés & avec un titre qui me semble assez clair.
Ils sont censés montrer les principaux cas d'usage, pas seulement celui qui t'amène ici.

Cette lib ne prend pas en charge la communication NTP : elle gère un DS1307 ou un DS3231.

L'interrogation NTP que tu dois mettre en place dans ton programme, te permet de récupérer l'heure UTC sous forme d'un timestamp Unix, c'est-à-dire un entier long non signé.

C'est cette valeur qu'il faut passer en paramètre d'appel de la méthode ci-dessous et hop ! ton RTC est à la bonne date et heure.

Code: [Select]
   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)

Salut ,

et merci beaucoup pour ces infos que je viens de tester dans mon prog , j ' ai une erreur " reglerNTP was not declared in this scope ".

Pourtant il me semble que j' ai fait les choses bien ( enfin pas tant que ca surement ) pourtant a cette heure -ci , j ' y vois encore a peu pres clair  :smiley-lol:

voici ce que j ' ai fait :

ajout des libs :
Code: [Select]
#include <Wire.h>
#include "simpleRTC.h"


ajout dans void setup (); de :
Code: [Select]
Wire.begin();

ensuite dans la fonction du serveur UDP qui recupere le temps unix j ' ai ajouté :
Code: [Select]
reglerNTP(epoch); // met a jour la RTC par le serveur NTP[/code

la fonction complete du serveur UDP a l' air de fonctionner a la vue du moniteur serie qui affiche bien le temps unix , mais dans le doute la voici :
[code]void reglerHeureByNTP () {
 sendNTPpacket(timeServer); // send an NTP packet to a time server
 
 
 // wait to see if a reply is available
 delay (3000);
 if ( Udp.parsePacket() ) {
 // We've received a packet, read the data from it
 Udp.read(packetBuffer, NTP_PACKET_SIZE); // read the packet into the buffer

 //the timestamp starts at byte 40 of the received packet and is four bytes,
 // or two words, long. First, esxtract the two words:

 unsigned long highWord = word(packetBuffer[40], packetBuffer[41]);
 unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]);
 // combine the four bytes (two words) into a long integer
 // this is NTP time (seconds since Jan 1 1900):
 unsigned long secsSince1900 = highWord << 16 | lowWord;
 
 Serial.print("Seconds since Jan 1 1900 = " );
 Serial.println(secsSince1900);

 // now convert NTP time into everyday time:
 Serial.print("Unix time = ");
 // Unix time starts on Jan 1 1970. In seconds, that's 2208988800:
 const unsigned long seventyYears = 2208988800UL;
 // subtract seventy years:
 unsigned long epoch = secsSince1900 - seventyYears;
 // print Unix time:
 Serial.println(epoch);
 reglerNTP(epoch); // met a jour la RTC par le serveur NTP

 /*
 // print the hour, minute and second:
 Serial.print("The UTC time is ");       // UTC is the time at Greenwich Meridian (GMT)
 Serial.print((epoch  % 86400L) / 3600); // print the hour (86400 equals secs per day)
 Serial.print(':');
 if ( ((epoch % 3600) / 60) < 10 ) {
 // In the first 10 minutes of each hour, we'll want a leading '0'
 Serial.print('0');
 }
 Serial.print((epoch  % 3600) / 60); // print the minute (3600 equals secs per minute)
 Serial.print(':');
 if ( (epoch % 60) < 10 ) {
 // In the first 10 seconds of each minute, we'll want a leading '0'
 Serial.print('0');
 }
 Serial.println(epoch % 60); // print the second
 */
 }
 gestionnaireDeTache.registerAsyncCommand(188, 12*TIMER_A, reglerHeureByNTP ); // tourne en boucle
}


et la fonction de communication avec le serveur , juste au cas ou :
Code: [Select]
unsigned long sendNTPpacket(char* address) {
  // set all bytes in the buffer to 0
  memset(packetBuffer, 0, NTP_PACKET_SIZE);
  // Initialize values needed to form NTP request
  // (see URL above for details on the packets)
  packetBuffer[0] = 0b11100011;   // LI, Version, Mode
  packetBuffer[1] = 0;     // Stratum, or type of clock
  packetBuffer[2] = 6;     // Polling Interval
  packetBuffer[3] = 0xEC;  // Peer Clock Precision
  // 8 bytes of zero for Root Delay & Root Dispersion
  packetBuffer[12]  = 49;
  packetBuffer[13]  = 0x4E;
  packetBuffer[14]  = 49;
  packetBuffer[15]  = 52;

  // all NTP fields have been given values, now
  // you can send a packet requesting a timestamp:
  Udp.beginPacket(address, 123); //NTP requests are to port 123
  Udp.write(packetBuffer, NTP_PACKET_SIZE);
  Udp.endPacket();
}


je vois pas ce que j ' ai pu loupé .


petite question  subsidiare toute bete , je peux tres bien supprimer la lib RTClib et n ' utiliser que la tienne pour une fonction afficher dateHeure et recuper des trucs du  style  now.hour() , now.day() etx si je ne me trompe pas ca me fera gagner de la memoire .[/code]
serveur relais volets arrosage heures creuse : https://forum.arduino.cc/index.php?topic=493039.0

bricoleau

Oui reglerNtp() est une méthode de classe...

Inspire-toi de l'exemple relatif au NTP
Tutoriels arduino : http://forum.arduino.cc/index.php?topic=398112.0

iznobe

salut ,

finalement ca marche  ;D

j ' avais oublie de mettre " RTC. " devant ...

du coup j ' ai supprime la RTClib.h standard de mon programme .

Cependant , il me reste un point que je n' arrive pas a resoudre qui n' est pas directement lié a cette classe .

quand je n' ai pas internet de connecté ou parfois sans raison , sur la RTC , tout est a " 0 "  :smiley-mr-green:

pour mettre a jour uniquement quand le retour est bon , j ' ai mis ça :

Code: [Select]
if ( epoch > 1585951635UL ) {  // => date du 04 / 04 / 2020 .
RTC.reglerNTP(epoch); // met a jour la RTC par le serveur NTP
gestionnaireDeTache.registerAsyncCommand(108, 12*TIMER_A, reglerHeureByNTP ); // tourne en boucle
}
else gestionnaireDeTache.registerAsyncCommand(108, TIMER_A, reglerHeureByNTP );  // tourne en boucle


j ' espere ne pas avoir ecrit une betise , il devrait mettre la RTC a jour que si il trouve une valeur correcte de la variable epoch , non?
serveur relais volets arrosage heures creuse : https://forum.arduino.cc/index.php?topic=493039.0

hbachetti

Si la connexion est absente ou que le serveur NTPne répond pas, il devrait être assez facile de ne pas mettre à jour la RTC non ?
Je ne vois pas en qui comparer epoch à 04/04/2020 apporte quoi que ce soit, étant donné que si le serveur NTP n'est pas joignable, epoch ne devrait même pas être récupéré.
Linux is like a wigwam: no Windows, no Gates, and an Apache inside ...

iznobe

Si la connexion est absente ou que le serveur NTPne répond pas, il devrait être assez facile de ne pas mettre à jour la RTC non ?
Je ne vois pas en qui comparer epoch à 04/04/2020 apporte quoi que ce soit, étant donné que si le serveur NTP n'est pas joignable, epoch ne devrait même pas être récupéré.

Salut henri ,

justement je pensais que si epoch n ' etait pas recuperer avec ce que j' ai mis , ca ne ferait pas la mise a jour de la RTC , selon toi ce n' est pas le cas ?


voici la fonction complete :
Code: [Select]
void reglerHeureByNTP () {
 sendNTPpacket(timeServer); // send an NTP packet to a time server

 delay(3000);
 // wait to see if a reply is available
 if ( Udp.parsePacket() ) {
 // We've received a packet, read the data from it
 Udp.read(packetBuffer, NTP_PACKET_SIZE); // read the packet into the buffer

 //the timestamp starts at uint8_t 40 of the received packet and is four bytes,
 // or two words, long. First, esxtract the two words:

 unsigned long highWord = word(packetBuffer[40], packetBuffer[41]);
 unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]);
 // combine the four bytes (two words) into a long integer
 // this is NTP time (seconds since Jan 1 1900):
 unsigned long secsSince1900 = highWord << 16 | lowWord;

 // now convert NTP time into everyday time:
 Serial.print("Unix time = ");
 // Unix time starts on Jan 1 1970. In seconds, that's 2208988800:
 const unsigned long seventyYears = 2208988800UL;
 // subtract seventy years:
 unsigned long epoch = secsSince1900 - seventyYears;
 // print Unix time:
 Serial.println(epoch);
 if ( epoch > 1585951635UL ) {  // => date du 04 / 04 / 2020 .
 RTC.reglerNTP(epoch); // met a jour la RTC par le serveur NTP
 gestionnaireDeTache.registerAsyncCommand(108, 12*TIMER_A, reglerHeureByNTP ); // tourne en boucle
 }
 else gestionnaireDeTache.registerAsyncCommand(108, TIMER_A, reglerHeureByNTP );  // tourne en boucle
 }
}


il est censé faire la mise a jour de la RTC uniquement dans le cas ou la valeur de epoch est superieure a celle du 04/04/2020 donc , je vois pas pourquoi je me retrouve avec 0 partout .

j ' ai mis ça parceque j' ai fait ca ce matin , je pourrais mettre nimporte quel chiffre ca serait pareil , du moment qu ' il est non nul ( enfin je pense )
serveur relais volets arrosage heures creuse : https://forum.arduino.cc/index.php?topic=493039.0

hbachetti

Je serais plus prudent lors de la réception du paquet :

 if ( Udp.parsePacket() ) {   // ce test est insuffisant

Comment peux-tu être sûr d'avoir reçu les bonnes données si tu ne testes pas la taille de celles-ci ?
Tu te contentes de tester si taille > 0

bricofoy t'a donné un code qui a mon avis est bien plus robuste :

https://forum.arduino.cc/index.php?topic=674870.msg4542356#msg4542356

Code: [Select]

time_t getNtpTime()
{
  while (Udp.parsePacket() > 0) ; // discard any previously received packets
  Serial.println("Transmit NTP Request");
  sendNTPpacket(timeServer);
  uint32_t beginWait = millis();
  while (millis() - beginWait < 1500) {
    int size = Udp.parsePacket();
    if (size >= NTP_PACKET_SIZE) {
      Serial.println("Receive NTP Response");
      Udp.read(packetBuffer, NTP_PACKET_SIZE);  // read packet into the buffer
      unsigned long secsSince1900;
      // convert four bytes starting at location 40 to a long integer
      secsSince1900 =  (unsigned long)packetBuffer[40] << 24;
      secsSince1900 |= (unsigned long)packetBuffer[41] << 16;
      secsSince1900 |= (unsigned long)packetBuffer[42] << 8;
      secsSince1900 |= (unsigned long)packetBuffer[43];
      return secsSince1900 - 2208988800UL + timeZone * SECS_PER_HOUR;
    }
  }
  Serial.println("No NTP Response :-(");
  return 0; // return 0 if unable to get the time
}


Les premières lignes sont essentielles :

 while (Udp.parsePacket() > 0) ; // discard any previously received packets

   int size = Udp.parsePacket();
   if (size >= NTP_PACKET_SIZE) {

D'autre part il fait plusieurs essais de réception pendant 1.5 secondes.

Ensuite si la fonction retourne ZERO en cas d'échec, l'information est claire : ne pas prendre en compte cette valeur.
Il n'y a aucune raison de tester epoch > 1585951635UL
Soit c'est ZERO, soit c'est la bonne valeur.
Linux is like a wigwam: no Windows, no Gates, and an Apache inside ...

hbachetti

Tu aurais d'ailleurs mieux fait de continuer sur le sujet "Synchoniser RTC DS1307 par NTP sur mega2506" au lieu de polluer un tutoriel n'ayant rien à voir avec le NTP.
Linux is like a wigwam: no Windows, no Gates, and an Apache inside ...

ggdu621

bonjour,

on est bien d'accord que pour récupérer un protocole NTP il faut une communication au réseau domestique (internet)?

bon dimanche a tous

Go Up