Hallo,
ich benutze den ESP8266. Wenn ich nun den NTP Server de.pool.ntp.org
anfrage, bekomme ich keine Antwort "no packet yet". Was mache ich falsch
oder ist der Server komplett überlastet?
1
// send an NTP request to the time server at the given address
2
unsignedlongsendNTPpacket(IPAddress&address)
3
{
4
Serial.println("sending NTP packet...");
5
// set all bytes in the buffer to 0
6
memset(packetBuffer,0,NTP_PACKET_SIZE);
7
// Initialize values needed to form NTP request
8
// (see URL above for details on the packets)
9
packetBuffer[0]=0b11100011;// LI, Version, Mode
10
packetBuffer[1]=0;// Stratum, or type of clock
11
packetBuffer[2]=6;// Polling Interval
12
packetBuffer[3]=0xEC;// Peer Clock Precision
13
// 8 bytes of zero for Root Delay & Root Dispersion
14
packetBuffer[12]=49;
15
packetBuffer[13]=0x4E;
16
packetBuffer[14]=49;
17
packetBuffer[15]=52;
18
19
// all NTP fields have been given values, now
20
// you can send a packet requesting a timestamp:
21
udp.beginPacket(address,123);//NTP requests are to port 123
22
udp.write(packetBuffer,NTP_PACKET_SIZE);
23
udp.endPacket();
24
}
25
26
unsignedlongGet_NTP_Time()
27
{
28
//get a random server from the pool
29
WiFi.hostByName(ntpServerName,timeServerIP);
30
31
sendNTPpacket(timeServerIP);// send an NTP packet to a time server
32
// wait to see if a reply is available
33
delay(3000);
34
35
intcb=udp.parsePacket();
36
if(!cb){
37
Serial.println("no packet yet");
38
return(0);
39
}
40
else{
41
Serial.print("packet received, length=");
42
Serial.println(cb);
43
// We've received a packet, read the data from it
44
udp.read(packetBuffer,NTP_PACKET_SIZE);// read the packet into the buffer
45
46
//the timestamp starts at byte 40 of the received packet and is four bytes,
47
// or two words, long. First, esxtract the two words:
dost0011 schrieb:> Wenn ich nun den NTP Server de.pool.ntp.org anfrage, bekomme ich keine> Antwort
Du machst ja auch kein NTP, sondern nur SNTP (Simple ...). Das kann
keinen Pool nach der Zeit fragen, sondern nur einzelne Server.
Nimm gezielt einen NTP-Server und es sollte gehen.
Das ist bestenfalls unschön. Pakete sollten verarbeitet werden, wenn sie
ankommen.
1
>intcb=udp.parsePacket();
Was macht denn diese Funktion und was gibt sie zurück?
Laß doch mal zum Testen einen lokalen Server laufen und schaue Dir an,
was im Netzwerk passiert.
de.pool.ntp.org ist übrigens ein einzelner Server, wenn auch immer ein
anderer.
dost0011 schrieb:> sendNTPpacket(timeServerIP); // send an NTP packet to a time server> // wait to see if a reply is available> delay(3000);>> int cb = udp.parsePacket();
Das ist unschön. UDP ist ein verbindungsloses Protokoll. Du kannst keine
unmittelbare Antwort erwarten. Diese kommt irgendwann... oder auch gar
nicht.
Ich mache das beim ESP so, dass ich einmal den Request abfeuere und dann
in loop() zyklisch frage, ob was über UDP reinkommt.
Also mit dem Delay habe ich rumgespielt, ob es besser oder schlechter
wird. Spielt keine Rolle, ich kann es auch rausnehmen.
Es kommt einfach keine Antwort zurück - egal, ob ich warte oder nicht.
Kennt ihr das Phänomen?
Frank M. schrieb:> Du machst ja auch kein NTP, sondern nur SNTP (Simple ...). Das kann> keinen Pool nach der Zeit fragen, sondern nur einzelne Server.
Der DNS-Name de.pool.ntp.org liefert bei Übersetzung in eine IP-Adresse
eine von mehreren Adressen und ist daher in Programmen, die DNS-Namen
verstehen, üblicherweise direkt nutzbar. Oder hat die ESP-Lib spezielle
Probleme damit?
A. K. schrieb:> Oder hat die ESP-Lib spezielle Probleme damit?
Ich hatte es damals beim ESP8266 mit de.pool.ntp.org und SNTP nicht
hinbekommen. Ich hatte dann als Server 192.53.103.103 (ntp3.ptb.de)
probiert. Das ging sofort. Deshalb habe ich es dann auf den Pool im
Zusammenhang mit SNTP geschoben.
Eben habe ich es aber nochmal (unter Linux, habe gerade keinen ESP
parat) mit einem SNTP-Client probiert:
Das funktioniert. Kann sein, dass es damals ein anderes temporäres
Problem gab. Ich nehme daher meine Behauptung zurück ;-)
Ich werde es heute abend aber trotzdem nochmal auf dem ESP ausprobieren.
dost0011 schrieb:> IPAddress timeServerIP(192,53,103,103);>> funktioniert auch nicht.
Dies wollte ich Dir gerade auch vorschlagen, hätte ja sein können, dass
die Namensauflösung aus irgendeinem Grund nicht klappt. Obwohl, Du
könntest Dir ja mal die IP-Adresse ausgeben lassen, die von
WiFi.hostByName(ntpServerName, timeServerIP) ermittelt wird.
> Liegt vermutlich nicht an den tausenden Servern> sondern an meinem Code ;-)
Den habe ich schon mit meinem Code
https://www.mikrocontroller.net/svnbrowser/wordclock24h/ESP8266/ESP-WordClock/
verglichen. Ich kann keinen größeren Unterschied erkennen, bis auf das
Delay. Wie gesagt: Schick das Paket einmal ab und führe den Aufruf von
udp.parsePacket() & Co. zyklich in der Hauptschleife aus, ich hatte das
oben schon so skizziert.
Frank M. schrieb:> Wie gesagt: Führe den Aufruf von udp.parsePacket() & Co. zyklich> in der Hauptschleife aus, ich hatte das oben schon so skizziert.
Wobei der ESP eigentlich für ereignisorientiertes Arbeiten ausgelegt
ist, nicht für sequentielles Arbeiten mit Warterei. Also nicht
Anfrage senden
warten
Antwort auswerten
sondern
Anfrage senden
und unabhängig davon
Wenn ein UDP Paket eintrifft, dann
Paket auswerten
Damit habe ich bessere Erfahrungen gemacht. Allerdings war das in LUA.
A. K. schrieb:> Wobei der ESP eigentlich für ereignisorientiertes Arbeiten ausgelegt> ist, nicht für sequentielles Arbeiten mit Warterei.
Dann passt das ja zu meinem Vorschlag.
Und du bist dir sicher, dass die Pakete auch ins Internet gehen und die
Antworten auch richtig weitergeleitet werden? Nicht dass ne Firewall
oder fehlendes NAT dir dazwischenfunken ...
dost0011 schrieb:> packetBuffer[0] = 0b11100011; // LI, Version, Mode
Das ist falsch. Lies den Standard RFC4330.
LI: Bit 7-6, hier 3 (unsynchronisiert), ok
Version: Bit 2-0, hier 3, auch nicht falsch. Ich würde hier Version 1
nehmen.
Mode: Bit 5-3, hier 4, und das ist FALSCH.
Du musst hier als Client eine 3 reinschreiben, der Server muss mit
Mode=4 antworten. Mode=5 ist für Broadcasts.
fchk
foobar schrieb:> Nicht dass ne Firewall> oder fehlendes NAT dir dazwischenfunken ...
Bevor man große Sprünge macht, sollte man sich in kleinen Schritten
vergewisseren, daß die einfachen Sachen schon mal funktionieren?
Ping wird ausgeführt für de.pool.ntp.org [195.201.19.162] mit 32 Bytes
Daten:
Antwort von 195.201.19.162: Bytes=32 Zeit=76ms TTL=53 usw.
fchk schrieb:> Du musst hier als Client eine 3 reinschreiben, der Server muss mit> Mode=4 antworten. Mode=5 ist für Broadcasts.
Ich habe das mal unter Linux ausprobiert.
Sowohl
1
packetBuffer[0]=0b11100011;// vom TO verwendet
als auch
1
packetBuffer[0]=0b00011011;// findet man in diversen Quellen
2
// LI = 0, NV = 3, MODE = 3
werden von us.pool.ntp.org, de.pool.ntp.org und ntp3.ptb.de ohne Mucken
geschluckt. Offenbar interessiert sich keiner für die LI, NV und
MODE-Bits. Naja, nicht ganz: bei packetBuffer[0] = 0x00 antwortet keiner
mehr.
Ich habe sonst überhaupt keine Felder im Paket mehr gefüllt, also alles
bei 0 gelassen (durch memset).
Verwendeter Source:
https://lettier.github.io/posts/2016-04-26-lets-make-a-ntp-client-in-c.html
Ok, jetzt habe ich folgendes gemacht:
Bei den Arduino Beispiel Sketchen gibt es unter ESP8266Wifi-->NTPClient.
Diesen Sketch habe ich auf den ESP8266 geladen. Er verbindet sich
einwandfrei mit dem Internet und dann bekomme ich folgenden Output
sending NTP packet...
no packet yet
sending NTP packet...
packet received, length=48
Seconds since Jan 1 1900 = 3735663005
Unix time = 1526674205
The UTC time is 20:10:05
sending NTP packet...
no packet yet
sending NTP packet...
no packet yet
sending NTP packet...
no packet yet
sending NTP packet...
no packet yet
sending NTP packet...
no packet yet
sending NTP packet...
no packet yet
sending NTP packet...
no packet yet
sending NTP packet...
no packet yet
sending NTP packet...
no packet yet
sending NTP packet...
no packet yet
sending NTP packet...
no packet yet
sending NTP packet...
no packet yet
sending NTP packet...
no packet yet
sending NTP packet...
no packet yet
sending NTP packet...
no packet yet
sending NTP packet...
no packet yet
sending NTP packet...
no packet yet
sending NTP packet...
no packet yet
sending NTP packet...
no packet yet
Das bedeutet, dass es einmal funktioniert hat und dann nicht mehr. Das
reicht natürlich nicht. Wenn ich einen Reset mache, kann es sein, dass
er für 10min (dann habe ich abgebrochen) kein einziges Paket empfangen
habe...
Anpingen kann ich den Server vom Rechner aus.
Was ist da los? Kann mich erinnern, dass das vor einem Jahr sofort und
zuverlässig funktioniert hat...
dost0011 schrieb:> Das bedeutet, dass es einmal funktioniert hat und dann nicht mehr.
Kann es sein, dass der Timeserver dicht macht, wenn Du ihn so zuknallst?
Wie groß sind die zeitlichen Abstände?
Das Gerät, welches ich bauen möchte, kommt in einer Umgebung zum
Einsatz, wo es keinen weiteren Rechner gibt. Kann doch nicht sein, dass
man einen eigenen Zeitserver benötigt, weil die vorhandenen nicht
antworten. Ich habe doch bestimmt ein ganzes anderes Problem...
foobar schrieb:> Den lokalen Server benutzt du zum Testen und Debuggen.
Vor allem kannst Du dort problemlos einen Wireshark aktivieren oder
tcpdump laufen lassen.