Hallo,
Der Time NTP Beispielcode funktioniert nicht, braucht die UdpBytewise.h und insgesamt scheint der Code mit den lib's nicht mehr zusammenzupassen.
Auch wird mit einem Delay(1000) auf eine mögliche Antwort gewartet, wenn man ein größeres Projekt hat und der Atmel noch was anderes zu tun hat geht sowas gar nicht.
Ich habe nun den Code etwas abgändert braucht keine UdpBytewise und läuft mit den aktuellen lib's
Mein oberste Prioität war: Wenn der Timeserver aus welche Gründen auch immer nicht erreichbar ist, darf die Funktion den Atmel nicht blockieren.
Hier mein pseudo Code incl. Sommer/Winterzeitumstellung (den Code habe ich von jurs "geklaut")
#include <Ethernet.h>
#include <EthernetUdp.h>
#include <Time.h>
byte timeServer[] = { 64,90,182,55 }; // time.nist.gov
const int NTP_PACKET_SIZE= 48; // NTP time stamp is in the first 48 bytes of the message
byte packetBuffer[ NTP_PACKET_SIZE]; //buffer to hold incoming and outgoing packets
EthernetUDP udp;
unsigned int localPort = 8888;
unsigned long startMillis;
boolean udpwait=true;
byte trying=0;
void setup() {
Ethernet.begin(mac,ip,dnsServer,gateway,subnet);
setSyncProvider(getNtpTime);
setSyncInterval(3600);
}
/*-------- utility code from jurs ----------*/
boolean summertime_EU(int year, byte month, byte day, byte hour, byte tzHours)
// European Daylight Savings Time calculation by "jurs" for German Arduino Forum
// input parameters: "normal time" for year, month, day, hour and tzHours (0=UTC, 1=MEZ)
// return value: returns true during Daylight Saving Time, false otherwise
{
if (month<3 || month>10) return false; // keine Sommerzeit in Jan, Feb, Nov, Dez
if (month>3 && month<10) return true; // Sommerzeit in Apr, Mai, Jun, Jul, Aug, Sep
if (month==3 && (hour + 24 * day)>=(1 + tzHours + 24*(31 - (5 * year /4 + 4) % 7)) || month==10 && (hour + 24 * day)<(1 + tzHours + 24*(31 - (5 * year /4 + 1) % 7)))
return true;
else
return false;
}
unsigned long getNtpTime()
{
if (udpwait) {
sendNTPpacket(timeServer); // send an NTP packet to a time server
udpwait=false;
trying=0;
// Serial.println("udp start");
startMillis = millis();
}
if( millis() - startMillis > 1000) // wait one second for the response without any delays
{
startMillis = millis();
// Serial.println("udp wait");
trying++;
if (trying > 5) udpwait=true; // no response up to 6 second - try again
int datain = udp.parsePacket();
if ( datain )
{
// Serial.println("Data incomming");
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;
// now convert NTP time into Arduino Time format:
// Time starts on Jan 1 1970. In seconds, that's 2208988800:
const unsigned long seventyYears = 2208988800UL;
// subtract seventy years:
unsigned long epoch = secsSince1900 - seventyYears+3600; // +3600 too MEZ;
tmElements_t pretime;
breakTime(epoch,pretime);
int real_year=pretime.Year+1970;
if (summertime_EU(real_year,pretime.Month,pretime.Day,pretime.Hour,1)) epoch+=3600;
udpwait=true;
return epoch;
}
}
return 0; // return 0 if unable to get the time
}
// send an NTP request to the time server at the given address
unsigned long sendNTPpacket(byte *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);
udp.write( packetBuffer,NTP_PACKET_SIZE);
udp.endPacket();
udp.flush();
}
Kritik ausdrücklich erwünscht, wenn ich einen Fehler drin habe oder was zu umständlich gemacht habe.
Und es wird wohl was zu finden sein, bin ja auch noch quasi Anfänger.
Laufen tut der Code jedenfalls, ist nun Teil von meiner Wetterstation mit Webinterface.
Dort habe ich den DCF Empfänger entfernt, macht auch keinen Sinn wenn der Arduino eh im Internet hängt