Grazie cotestatnt, è stata una svolta!
L'esempio funziona alla grande. Ho solo aggiunto la correzione dell'ora locale, il codice per il modulo RTC e la conversione di DateTime in String (chce non è così immediata ed intuitiva).
Posto di seguito il mio codice funzionante e commentato se può essere utile a qualcuno.
Se ravvisate delle imprecisioni fatemi sapere.
/*
WiFiEsp example: UdpNTPClient
Modificato da Americo il 21/03/2023 per Arduino Mega2560
Aggiungendo il modulo RTC, gestione fuso orario e conversione di DateTime in Sting
N.B.: in Italia "time.nist.gov" dà dei problemi di comunicazione mandando
la richiesta UDP in timeout.
Meglio utilizzare "it.pool.ntp.org"
Get the time from a Network Time Protocol (NTP) time server.
Demonstrates use of UDP to send and receive data packets
For more on NTP time servers and the messages needed to communicate with them,
see http://en.wikipedia.org/wiki/Network_Time_Protocol
NOTE: The serial buffer size must be larger than 36 + packet size
In this example we use an UDP packet of 48 bytes so the buffer must be
at least 36+48=84 bytes that exceeds the default buffer size (64).
You must modify the serial buffer size to 128
For HardwareSerial modify _SS_MAX_RX_BUFF in
Arduino\hardware\arduino\avr\cores\arduino\SoftwareSerial.h
For SoftwareSerial modify _SS_MAX_RX_BUFF in
Arduino\hardware\arduino\avr\libraries\SoftwareSerial\SoftwareSerial.h
*/
#include "WiFiEsp.h" //Libreria per la comunicazione con l'ESP8266 (tramite comandi AT)
#include "WiFiEspUdp.h" //Libreria per protocollo UDP con il web
#include <RTClib.h> //Libreria per la gestione del modulo RTC
RTC_DS3231 rtc; //Crea un oggetto per il real time clock
WiFiEspUDP Udp; //Apre l'istanza per il server UDP
char ssid[] = "XXXXXX"; // Il nome della vostra rete WiFi
char pass[] = "123456"; //La password della vostra rete WiFi
int status = WL_IDLE_STATUS; // Stato della Wifi
char timeServer[] = "it.pool.ntp.org"; //NTP server "it.pool.ntp.org" , "time.nist.gov"
unsigned int localPort = 2390; //Porta locale per ricevere i pacchetti UDP dal Web
const int NTP_PACKET_SIZE = 48; // NTP timestamp is in the first 48 bytes of the message
const int UDP_TIMEOUT = 2000; // timeout in miliseconds to wait for an UDP packet to arrive
byte packetBuffer[NTP_PACKET_SIZE]; // buffer to hold incoming and outgoing packets
unsigned long ISTANTE = 0; //Fissa un punto nel tempo con millis()
unsigned long Old_ISTANTE = 0; //Vecchio valore di millis()
int Local_Ora = 1; //differenza di ora da UTC time
void setup()
{
Serial.begin(115200); //Inizializza serial monitor
//Inizializza la seriale per ESP8266
//(abbassare a 9600 se si usa SoftwareSerial)
//Modificare in Serial1 se la vostra scheda ha una sola seriale
Serial2.begin(115200);
WiFi.init(&Serial2); // Iniziallizza la comunicazione WiFi
//Inizializza il modulo RTC
Serial.println("Inizializzo modulo RTC");
if(!rtc.begin()){
Serial.println("Errore Modulo rtc");
return;
}
delay(50);
Serial.println("Modulo RTC Avviato");
// check for the presence of the shield
if (WiFi.status() == WL_NO_SHIELD) {
Serial.println("WiFi shield not present");
// don't continue
while (true);
}
// attempt to connect to WiFi network
while ( status != WL_CONNECTED) {
Serial.print("Attempting to connect to WPA SSID: ");
Serial.println(ssid);
status = WiFi.begin(ssid, pass); //Connect to WPA/WPA2 network
}
Serial.println("You're connected to the network");
Udp.begin(localPort); // you're connected now, so print out the data
}
void Ottieni_Data_Web() // Ottiene la data dal server NTP ed aggiorna l'RTC
{
sendNTPpacket(timeServer); // send an NTP packet to a time server
unsigned long startMs = millis(); // wait for a reply for UDP_TIMEOUT miliseconds
while (!Udp.available() && (millis() - startMs) < UDP_TIMEOUT) {}
Serial.println(Udp.parsePacket());
if (Udp.parsePacket())
{
Serial.println("packet received");
Udp.read(packetBuffer, NTP_PACKET_SIZE); // We've received a packet, read the data from it 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 = ");
secsSince1900 = secsSince1900 + (Local_Ora * 3600);
Serial.println(secsSince1900);
Serial.print("Unix time = "); // now convert NTP time into everyday time
const unsigned long seventyYears = 2208988800UL; // Unix time starts on Jan 1 1970. In seconds, that's 2208988800
unsigned long epoch = secsSince1900 - seventyYears; // subtract seventy years
Serial.println(epoch); // print Unix time:
rtc.adjust(DateTime(epoch));
delay(500);
DateTime Adesso = rtc.now();
// 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)
{
Serial.print('0');// In the first 10 minutes of each hour, we'll want a leading '0'
}
Serial.print((epoch % 3600) / 60); // print the minute (3600 equals secs per minute)
Serial.print(':');
if ((epoch % 60) < 10)
{
Serial.print('0'); // In the first 10 seconds of each minute, we'll want a leading '0'
}
Serial.println(epoch % 60); // Secondi dal 01/01/1970
Serial.print("Data salvata nell'RTC = " + Converti_Time_To_String(Adesso));
}
}
void sendNTPpacket(char *ntpSrv) // send an NTP request to the time server at the given address
{
memset(packetBuffer, 0, NTP_PACKET_SIZE); // set all bytes in the buffer to 0
// 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(ntpSrv, 123); //NTP requests are to port 123
Udp.write(packetBuffer, NTP_PACKET_SIZE);
Udp.endPacket();
}
String Converti_Time_To_String(DateTime dt) //Converte una variabile DateTime in String
{
char buffer [25] = "";
sprintf(buffer, "%04d/%02d/%02d, %02d:%02d:%02d", dt.year(), dt.month(), dt.day(), dt.hour(), dt.minute(), dt.second());
String datetime = buffer;
return datetime;
}
void loop()
{
ISTANTE = millis();
if (ISTANTE > Old_ISTANTE + 10000)
{
Ottieni_Data_Web();
Old_ISTANTE = millis();
}
}