problema rtc e ethernet sever

Salve, sto facendo un progettino che mi aggiorna l'ora da web e me la sistema sull rtc (ds1307).
fin qui tutto ok. il problema inizia quando aggiungo la chiamata Ethernet.begin(mac, ip) praticamente l'arduino non mi manda la richiesta udp al server time.
ho messo vari debug per vedere fino dove arriva l'esecuzione e si ferma su Udp.write(packetBuffer, NTP_PACKET_SIZE);

vi allego lo sketch.

grazie

#include <SPI.h>
#include <Ethernet.h> 
#include <EthernetUdp.h>
#include <Wire.h>
#include "RTClib.h"
//#include <SD.h>



byte mac[] = { 0xFE, 0xBD, 0xBE, 0xEF, 0xBD, 0xFE };
IPAddress ip(192, 168, 1, 36);
boolean agg_ora=false;
unsigned long millisora;
unsigned long millisrichiestaora;
byte rx;

//variabili x ora tramite udp
unsigned int localPort = 8888;
char timeServer[] = "time.nist.gov";
const int NTP_PACKET_SIZE = 48;
byte packetBuffer[ NTP_PACKET_SIZE];
EthernetUDP Udp;
RTC_DS1307 rtc;



void setup() {

  Udp.begin(localPort);
  Ethernet.begin(mac, ip);
  Wire.begin();
   Serial.begin(9600);

    while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }
 /*if (Ethernet.begin(mac) == 0) {
    Serial.println("Failed to configure Ethernet using DHCP");
    // no point in carrying on, so do nothing forevermore:
    for (;;)
      ;
  }
*/
}



void loop() {
richiediora();
 
  
  
  
  
  
  
  
  
  
  if (Serial.available() >0) // Controllo se il buffer di ricezione contiene qualcosa
    {
    rx = Serial.read(); // leggo il carattere ricevuto e lo memorizzo in rx
    Serial.flush(); // svuoto il buffer di ricezione seriale
if (rx=='o'){ DateTime now = rtc.now();
    
    Serial.print(now.year(), DEC);
    Serial.print('/');
    Serial.print(now.month(), DEC);
    Serial.print('/');
    Serial.print(now.day(), DEC);
    Serial.print(" (");
    //Serial.print(daysOfTheWeek[now.dayOfTheWeek()]);
    Serial.print(") ");
    Serial.print(now.hour(), DEC);
    Serial.print(':');
    Serial.print(now.minute(), DEC);
    Serial.print(':');
    Serial.print(now.second(), DEC);
    Serial.println();
    
    Serial.print(" since midnight 1/1/1970 = ");
    Serial.print(now.unixtime());
    Serial.print("s = ");
    Serial.print(now.unixtime() / 86400L);
    Serial.println("d");
}

  
}
}

void richiediora(){
millisrichiestaora=millis();
if (millisrichiestaora>millisora+30000&&agg_ora==false){
  
  millisora=millis();
 sendNTPpacket(timeServer);
delay(1000);
if (Udp.parsePacket()) {
  
 Udp.read(packetBuffer, NTP_PACKET_SIZE); 
 unsigned long highWord = word(packetBuffer[40], packetBuffer[41]);
    unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]);
   unsigned long secsSince1900 = highWord << 16 | lowWord;
    Serial.print("Seconds since Jan 1 1900 = ");
    Serial.println(secsSince1900);  
  Serial.print("Unix time = ");
  const unsigned long seventyYears = 2208988800UL;
  unsigned long epoch = secsSince1900 - seventyYears;
 Serial.println(epoch);
  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) {
      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);  
   
   rtc.adjust(epoch+3600); 
   agg_ora=true;
    }
  }
}
void sendNTPpacket(char* address) {
memset(packetBuffer, 0, NTP_PACKET_SIZE);
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;
  Udp.beginPacket(address, 123); //NTP requests are to port 123
  Udp.write(packetBuffer, NTP_PACKET_SIZE);
  Udp.endPacket();
}

Magari sarebbe utile sapere che schede stai usando...

arduino mega 2560 rev3, ethernet shield w5100 e rtc ds1307

Ethernet.begin(mac, ip); // Prima si inizializza la scheda
  Udp.begin(localPort); // Poi la UDP

e quel Mac Address e' errato

byte mac[] = { 0xFE, 0xBD, 0xBE, 0xEF, 0xBD, 0xFE }; // Mac errato

byte mac[] = { 0xFE, 0xBD, 0xBE, 0xEF, 0xBD, 0x47 }; // Mac corretto

Brunello:
[Prima si inizializza la scheda

byte mac[] = { 0xFE, 0xBD, 0xBE, 0xEF, 0xBD, 0x47 }; // Mac corretto

Ciao Brunello, grazie per la risposta.
ho fatto le modifiche da te suggerite.
non cambia nulla.
che altro posso fare?

Salve a tutti.
continuo a non trovare la soluzione a questo strano problema.
ho provato a cercare in rete ma non trovo un sketch dove ci sia l'aggiornamento dell'rtc da internet per poterlo confrontare e capire come mai nel momento in cui inizializzo l'ethernet il pacchetto udp non viene inviato.

grazie

pablos:
sbagli a chiamare il server NTP

è quello dell'esempio... come dovrei fare pablos?

Sono riuscito a venirne fuori. lo scrivo così che possa essere d'aiuto per qualcun altro sul forum.

praticamente ho dovuto dichiarare ip subnet gateway e richiamarla sul setup in questo modo:

byte mac[] = {0x65, 0xF1, 0xEB, 0x57, 0x47, 0xB0};
IPAddress dnServer(8, 8, 8, 8);
IPAddress gateway(192, 168, 1, 1);
IPAddress subnet(255, 255, 255, 0);
IPAddress ip(192, 168, 1, 36);

e nel setup chiamare l'ethernet in questo modo:

Ethernet.begin(mac, ip, dnServer, gateway, subnet);

grazie sempre a tutti per il supporto :slight_smile:

Dubito fortemente che sia quella la soluzione

in caso contrario ti posso dimostrare che se sei un server e vuoi un aggiornamento da server NTP queste 3 linee

IPAddress dnServer(8, 8, 8, 8);
IPAddress gateway(192, 168, 1, 1);
IPAddress subnet(255, 255, 255, 0);

non servono a nulla, occupano solo 12 byte di ram inutilmente, servono se sei un client, nel rifare lo sketch hai cambiato sicuramente qualcos'altro

Pablos non sono d'accordo...
per smentirmi fai questa prova.
prendi l'esempio udp ntp client e nel void setup togli

// start Ethernet and UDP
  if (Ethernet.begin(mac) == 0) {
    Serial.println("Failed to configure Ethernet using DHCP");
    // no point in carrying on, so do nothing forevermore:
    for (;;)
      ;
  }

in quanto mi serve l'ip statico e non necessito di dhcp .
quindi inizializzo la ethernet

Ethernet.begin(mac, ip);

(logicamente nelle fase d'inizio ho dichiarato l ip

IPAddress ip(192, 168, 1, 36);

a me cosi' senza l'aggiunta di dns, gateway e dns non aggiorna...

mistero

Non ho fatto prove, ma ho capito perchè ....
tu hai bisogno di risolvere il dominio perchè invece di mettere l'ip del server NTP che sarebbe 24.56.178.140 (ricavato col DNS online) hai messo char timeServer[] = "time.nist.gov";

i domini più usati sono:
time.nist.gov
pool.ntp.org
time.windows.com
Questi server sono registrati nelle apparecchiature più comuni connesse in rete che necessitano di un orario aggiornato e piuttosto preciso

Nel tuo sketch utilizzando il nome del server anzichè l'IP diretto ad arduino serve tutta una procedura complessa per ricavare l'IP, e l'unico modo che ha arduino è utilizzando il servizio DNS richiamando il server dns IPAddress dnServer 8, 8, 8, 8

In realtà le prime librerie dell'NTP indicavano un IP e non un nome del dominio da risolvere.

Siccome internet non funziona con nomi tipo "pippo.it" e "ciccio.com" ecc ma solo con numeri Si può fare in entrambi i modi:

  1. con IP è rapido e diretto si evitano procedure di giri e rigiri e non serve chiedere l'indirizzo
  2. utilizzando il nome del dominio qualora l'ip venisse cambiato il dns lo risolve ... perchè il nome difficilmente cambierà ma l'ip si, però impiega tempo e ram

domani faccio 2 prove e ti so dare conferma se queste linee sono obbligatorie o non ci siano inghippi strani
Forse basta solo Ethernet.begin(mac, ip, dnServer);

A dimostrazione di quello che ho scritto prima un sempio di 5 anni fa, che poi ha subito modifiche e ottimizzazioni grazie alle quali si sono ottenuti i giorni della settimana e gli anni bisestili
http://forum.arduino.cc/index.php?topic=73496.705
post #714 un orologio senza RTC esterno usando il timer del micro che comunque doveva connettersi ad un server NTP per metterlo in linea e aggiornarsi al fine di correggere l'errore di pochi secondi ogni 24h.
ciao

Ma davvero a te questo sketch non va?

#include <SPI.h>
#include <Ethernet.h>
#include <EthernetUdp.h>
 
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192, 168, 2, 177);
EthernetServer server(80);
unsigned int localPort = 8888;       
 
char timeServer[] = "time.nist.gov"; 
const int NTP_PACKET_SIZE = 48;  
byte packetBuffer[ NTP_PACKET_SIZE]; 

EthernetUDP Udp;
 
void setup(){
  Serial.begin(9600);
  Ethernet.begin(mac, ip);
  server.begin();
  Serial.print("server is at ");
  Serial.println(Ethernet.localIP());
  Udp.begin(localPort);
}
 
void loop(){
  sendNTPpacket(timeServer); 
  
  delay(800);
  if ( Udp.parsePacket() ) {   
    Udp.read(packetBuffer, NTP_PACKET_SIZE);    
    unsigned long highWord = word(packetBuffer[40], packetBuffer[41]);
    unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]);
    unsigned long secsSince1900 = highWord << 16 | lowWord; 
    const unsigned long seventyYears = 2208988800UL;   
    unsigned long epoch = secsSince1900 - seventyYears + 7200;
    Serial.print("Time : ");   
    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 ) {
      Serial.print('0');
    }
    Serial.println(epoch % 60);
  }
  delay(30000);
}
 
unsigned long sendNTPpacket(char* address){
 
  memset(packetBuffer, 0, NTP_PACKET_SIZE);
  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
  packetBuffer[12]  = 49;
  packetBuffer[13]  = 0x4E;
  packetBuffer[14]  = 49;
  packetBuffer[15]  = 52;
 
  Udp.beginPacket(address, 123); 
  Udp.write(packetBuffer, NTP_PACKET_SIZE);
  Udp.endPacket();
}

server is at 192.168.2.177
Time : 10:26:41
Time : 10:27:12
Time : 10:27:43