NTP bleibt hängen

Hallo,
mein Programm holt sich die aktuelle Zeit über NTP von der Fritzbox alle 2 Stunden.
Hier bleib es bei Udp.beginPacket(address, 123); ca 1x die Woche hängen.
Ich gehe davon aus, das die Fritzbox keine Antwort innerhalb von 8s liefert und der Watchdog auslöst.
Gibt es hier evt eine Art Timeout um den Fehler abzufangen.
Denn beim anschließenden Neustart ist die Zeit wieder da. Von der gleichen Routiene abgefragt.

Zur Erklärung zur Variablen zProgPos:
Die wird im Noinit-Breich des Ram gespeichert. Das heißt, der Wert steht mir auch nach einen Reset
durch den Wotchdog zur Verfügung und wir beim setup auf die SD gespeichert.
So kann ich genau bestimmen, wo der Hänger war.

LG

uint8_t zProgPos __attribute__ ((section (".noinit")));     
uint32_t zFirstRun __attribute__ ((section (".noinit")));   

void setup(){
EEPROM.write(6, vCndNStart + 1);                          //Neustartzähler +1
  Serial<<vCndNStart + 1<<F(". Neustart")<<ende;
  if(zFirstRun != 0xDEAD0000){
    sprintf_P(vText, PSTR("~~~~~~ %d. N e u s t a r t ~~~~~~ nach Stromausfall"),vCndNStart + 1); ProtokollAufSD(true);          //Protokol auf SD
    zFirstRun = 0xDEAD0000;
  } else{
    sprintf_P(vText, PSTR("~~~~~~ %d. N e u s t a r t ~~~~~~  Absturzpostion = %d "),vCndNStart + 1, vAbsturzNr); ProtokollAufSD(true);
  }
}

void sendNTPpacket(char* address) {
  zProgPos = 20;                                            //Positionsnummer Watchdog-Auslösung
  // 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: 
  zProgPos = 201;
  Udp.beginPacket(address, 123); //NTP requests are to port 123
  zProgPos = 202;
  Udp.write(packetBuffer, NTP_PACKET_SIZE);
  delay(1);
  zProgPos = 203;
  Udp.endPacket();
}

schwierig mit Codeschnippsel...

aber

https://www.arduino.cc/en/Reference/EthernetUDPBeginPacket

Returns

Returns an int: 1 if successful, 0 if there was a problem resolving the hostname or port.

würde ich also probierern auszuwerten und nur im Erfolgsfall weitermachen.

noiasca:
Arduino - EthernetUDPBeginPacket

Returns

Returns an int: 1 if successful, 0 if there was a problem resolving the hostname or port.

würde ich also probierern auszuwerten und nur im Erfolgsfall weitermachen.

So wie ich den OP verstanden habe, kommt er da gar nicht erst hin, um etwas auszuwerten.

Ich würde, um das genauer einzugrenzen, ein wdt_disable() vor dem NTP-Abruf machen und danach wieder einschalten.
Innerhalb der Routine dann auf 0 prüfen und ggfls. dort versuchen in Erfahrung zu bringen, was da hängt.

my_xy_projekt:
Ich würde, um das genauer einzugrenzen, ein wdt_disable() vor dem NTP-Abruf machen und danach wieder einschalten.
Innerhalb der Routine dann auf 0 prüfen und ggfls. dort versuchen in Erfahrung zu bringen, was da hängt.

Ohne WD habe ich eine Hänger bis ich die Reset-Taste drücke!

Hi

Der WDT ist ein Notnagel - NICHT dafür da, schlampig zusammen gestrickte Programme halbwegs am Laufen zu halten.
Selber nutze ich den WDT um meine Arduino neu zu starten, wenn z.B. 10 Sekunden keine CAN-Nachricht empfangen wurde (irgendwer schwätzt hier IMMER) - wenn also Nichts empfangen wurde, hat sich ggf. das CAN-Modul verabschiedet - auch lasse ich Ihn damit gezielt resetten, wenn das CAN-Modul nicht beim Start korrekt eingerichtet werden konnte - während Dessen gibt der Arduino einen Blink-Code ab, damit der blöde Betrachter auch sieht, daß Da ein Problem besteht.
(auch kann ich per CAN ein Reset auslösen - man macht, was möglich ist :wink: ).

WO hängt sich Dein Arduino auf?
Vll. kommen wir so dem Problem näher?

MfG

Was heißt hier schlampig?

Die Routine ist 1 zu 1 aus github.com kopiert.

Macht ja nichts.
Du wolltest halt auch was schreiben.
Wenns auch nicht weiter hilft.

WO hängt sich Dein Arduino auf? schau mal auf Zeile 3 lesen musst du schon selber

Hi

Nun guck Mal - nicht Alles, was man auf YT findet, lässt sich in der Universität als Lehrmaterial verwenden - und nicht Alles, was - egal Wer - auf github präsentiert verdient das Prädikat fehlerfrei (mit großer Wahrscheinlichkeit sogar rein gar Nichts davon).

Da Du Dich hier persönlich auf den Fuß getreten fühlst, obwohl der ganze Code doch gar nicht von Dir ist - verwundert doch etwas.

Davon ab ist's Dein Problem - wenn Du keine Hilfe haben möchtest, verstehe ich Dein Auftreten hier noch viel weniger.
Also: WO hängt sich der Arduino auf?
Sofern Du Das gar nicht herausfinden willst: Das hilft hier nun überhaupt nicht weiter.

MfG

Wie ganz oben in Zeile 3 beschrieben ist
hängt es in der Zeile

Udp.beginPacket(address, 123);

das zum Thema WO

Ja, Hilfe möchte ich schon haben!
Aber nicht von jemanden der mir was von CAN und Blablablabla.....................

:wink:

Es gibt 2 Möglichkeiten für beginPacket:

// mit hostname
int EthernetUDP::beginPacket(const char *host, uint16_t port)
// und mit IP
int EthernetUDP::beginPacket(IPAddress ip, uint16_t port)

Du verwendest, so wie es aussieht, die mit hostname. Welchen Hostname übergibst Du? Das ist in dem Fragment nicht erkennbar.
Kann der Hostname aufgelöst werden? Code zum Testen kannst Du aus EthernetUDP.cpp Zeile 63ff entnehmen.

Gruß Tommy

Ich verwende "fritz.box"

Wenn ich das so ansehe ist es besser die IP zu verwenden, die muss nicht erst aufgelöst werden.

Eventuell löst das mein Problem.

Danke für den Denkanstoß!

EthernetUDP.cpp

int EthernetUDP::beginPacket(const char *host, uint16_t port)
{
  // Look up the host first
  int ret = 0;
  DNSClient dns;
  IPAddress remote_addr;

  dns.begin(Ethernet.dnsServerIP());
  ret = dns.getHostByName(host, remote_addr);
  if (ret != 1) return ret;
  return beginPacket(remote_addr, port);
}

int EthernetUDP::beginPacket(IPAddress ip, uint16_t port)
{
  _offset = 0;
  //Serial.printf("UDP beginPacket\n");
  return Ethernet.socketStartUDP(sockindex, rawIPAddress(ip), port);
}

Hallo,
ich hatte seit knapp einer Woche keinen Hänger mehr.
Offensichtlich ist das Problem gelöst.

ar182:
Hallo,
ich hatte seit knapp einer Woche keinen Hänger mehr.
Offensichtlich ist das Problem gelöst.

Wenn es mit direkter IP geht, mit Namen und DNS ab und zu nicht, dann hast Du ein Problem.
Das liegt nicht zwingend am Arduino.

Da empfehle Dir einen Mitschnitt der Netzwerkkommunikation mit und/oder an der Fritz!Box.
Dazu benötigst Du einen Netzwerkanalyser - z.B. Wireshark sowie einen Browser, der die ganze Zeit mitläuft.

Die Fritzbox selbst stellt SEINE Kommuniaktionsdaten bereit:

http://fritz.box/html/capture.html
oder
http://IP-ADRESSE-DER-FRITZBOX/html/capture.html

(Absichtlich nicht als link gemacht)

Du müsstest aber den gesamten Mitschnitt analysieren.

Mit wireshark allein kannst Du einstellen, das Du nur DNS-Anfragen aufzeichnen und die Filegröße begrenzen willst.

Bist Du mit einem Kabel direkt von Arduino nach FB verbunden oder noch mit Dosen und weiteren Kabeln?