Time via NTP

Bonjour,

J'utilise le source suivant pour obtenir l'heure via des serveurs ntp.
Il y a des problèmes de compilation pour cette librairie mais je les ai résolu avec l'aide du forum.
Néanmoins, je n'arrive pas à avoir l'heure.
Précisions:

  • mon shield ethernet version micro sdcard fonctionne avec les exemples de serveurs
  • je suis sur mon réseau interne avec une freebox v4
  • Bien qu'il ne devrait pas y avoir de pb avec le routage, j'ai quand meme essayé de mettre une regle de routage sur le port 123 vers mon ip 192.168.0.5
  • j'ai essayé aussi d'autres serveurs ntp ainsi qu'en mettant les paramètres gateway et mask

rien n'y fait, je ne parviens pas à avoir l'heure. blocage sur "waiting for NTP server ..."

Y a t il une bonne âme avec de bonnes idées ?

/*
 * Time_NTP.pde
 * Example showing time sync to NTP time source
 *
 * This sketch uses the Ethenet library with the user contributed UdpBytewise extension
 */
#include <SPI.h>
#include <Time.h>
#include <Ethernet.h>
#include <UdpBytewise.h>  

byte mac[] = {
  0x00, 0x11, 0x22, 0x33, 0x44, 0x55 };
byte ip[] = { 192, 168, 0, 5 };   // fill in your local Arduino ip adress
//byte mask[] = { 255, 255, 255, 0 };
//byte gw[] = { 192, 168, 0, 254 };
  
// byte SNTP_server_IP[] = { 192, 43, 244, 18}; // time.nist.gov
byte SNTP_server_IP[] = { 130,149,17,21}; // ntps1-0.cs.tu-berlin.de
//byte SNTP_server_IP[] = {  192,53,103,108}; // ptbtime1.ptb.de

time_t prevDisplay = 0; // when the digital clock was displayed

// time zone correction [sec]. e.g. CET = -3600 sec
const unsigned long add_time_zone=-3600UL;

void setup()
{
  //Ethernet.begin(mac,ip,gw,mask);  
  Ethernet.begin(mac,ip);
  Serial.begin(9600);
  Serial.println ("waiting for NTP server ...");
  setSyncProvider(getNtpTime);
  while(timeStatus()== timeNotSet)  
    ; // wait until the time is set by the sync provider
}

void loop()
{  
  if( now() != prevDisplay) //update the display only if the time has changed
  {
    prevDisplay = now();
    digitalClockDisplay();  
  }
}

void digitalClockDisplay(){
  // digital clock display of the time
  Serial.print(hour());
  printDigits(minute());
  printDigits(second());
  Serial.print(" sec ");
  Serial.print(day());
  Serial.print(".");
  Serial.print(month());
  Serial.print(".");
  Serial.print(year());
  Serial.println();
}

void printDigits(int digits){
  // utility function for digital clock display: prints preceding colon and leading 0
  Serial.print(":");
  if(digits < 10)
    Serial.print('0');
  Serial.print(digits);
}

/*-------- NTP code ----------*/

unsigned long getNtpTime()
{
  sendNTPpacket(SNTP_server_IP);
  delay(200); // for roundtriptiime in slow environtment
  if ( UdpBytewise.available() ) {
    for(int i=0; i < 40; i++){
      UdpBytewise.read(); // ignore every field except the time
    }    
    const unsigned long seventy_years = 2208988800UL+add_time_zone;        
    return getUlong() -  seventy_years;      
  }
  return 0; // return 0 if unable to get the time
}

unsigned long sendNTPpacket(byte *address)
{
  UdpBytewise.begin(123);
  UdpBytewise.beginPacket(address, 123);
  UdpBytewise.write(B11100011);   // LI, Version, Mode
  UdpBytewise.write(0);    // Stratum
  UdpBytewise.write(6);  // Polling Interval
  UdpBytewise.write(0xEC); // Peer Clock Precision
  write_n(0, 8);    // Root Delay & Root Dispersion
  UdpBytewise.write(49);
  UdpBytewise.write(0x4E);
  UdpBytewise.write(49);
  UdpBytewise.write(52);
  write_n(0, 32); //Reference and time stamps  
  UdpBytewise.endPacket();  
}

unsigned long getUlong()
{
  unsigned long ulong = (unsigned long)UdpBytewise.read() << 24;
  ulong |= (unsigned long)UdpBytewise.read() << 16;
  ulong |= (unsigned long)UdpBytewise.read() << 8;
  ulong |= (unsigned long)UdpBytewise.read();
  return ulong;
}

void write_n(byte what, int how_many)
{
  for( int i = 0; i < how_many; i++ )
    UdpBytewise.write(what);
}

Pour info ce code fonctionne si l'on ne met pas le moniteur serie (chez moi en tous cas)
qqun a t il une explication ??

Voici la réponse d'un newbie

quand tu dis "si on ne mets pas le moniteur série", cela veut dire :
1- que tu commentes les "serial.print" ?
2- que tu débranches ta liaison physique ?

Si 1, je pencherais pour erreur de codage (est-ce que minute et seconds sont bien de type entier, ou est-ce que le transtypage se fait bien, par exemple ?)

Si 2 : problème physique (peut-être faut-il que le moniteur acquiesse réception des trames, et donc pas possible d'envoyer une nouvelle trame) - y'a peut être aussi un probleme aussi au niveau du writeln

moniteur série = serial monitor
c'est à dire la fenetre sup que l'on peut ouvrir via l'environnement de développement arduino puis tools/serial monitor ou via le petit icone ad hoc

l'application semble se blquer sur cette ligne:
while(timeStatus()== timeNotSet)

donc les formats ne semblent pas en cause

par ailleurs je me suis rendu compte que le bug est toujours présent:
ma config,
arduino uno
ethernet shield sd card (wiznet)
aff lcd
sonde tempé DS18N20
sonde tempé/hum DHT11
programme tournant sur arduino avec interrogation serveur ntp via soft tel que ci-dessus
si je débranche la connexion usb de l'arduino qui est alimenté par une alim 9V et que je reset via le bouton reset sur ethernet shield,
ca ne fonctionne plus (ie. blocage au niveau de "while(timeStatus()== timeNotSet)" )
pour que ca refonctionne, il faut reconnecter l'usb à mon pc puis relancer l'environnement de dev arduino (a ce moment, ma carte arduino se reset seule, mais tjs bloqué au niveau indiqué), puis que j'ouvre le serial monitor (idem, reset auto mais tjs bloqué), puis que je referme le serial monitor et là débloquage sans que j'ai besoin d'intervenir autrement.
ensuite je peux débrancher l'usb.tout fonctionne par la suite.

curious indeed ...

Ah mais ça c'est normal !

A partir du moment où dans ton setup tu mets un Serial.begin, rien ne se lancera tant que la connexion ne sera pas établi (c'est à dire liaison physique ET port ouvert sur le PC, ce qui arrive quand tu lances le serial monitor).

OK grand merci
meme si ca ne resoud pas le pb , ca m'a mis sur la voie
en effet en enlevant toutes ref à serial, ca semblait marcher un peu mieux, c'est à dire que certains de blocages disparaissaient.
en revanche ca ne fonctionnait pas à chaque fois, notamment à la mise sous tension en autonome.
il a fallu que je change le code de la mise à jour tel que ceci:

while(timeStatus()== timeNotSet)
setSyncProvider(getNtpTime); // wait until the time is set by the sync provider

ciao