Ora da NTP server su Arduino Mega2560 con ESP8266

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

}