Mega mit Ethernetshield Restart nach OTE und Watchdog Auslösung

Hallo,
ich nutze einen Aduino Mega (mit Optiboot 8) und Ethernetshield. Nach einem Kaltstart gibt es keine Probleme. Wenn der Watchdog auslöst oder ich ein Programm über Ethernet flashe, startet der Arduino nicht wieder (habe ich über ein externes Monitorprogramm geprüft). Wenn ich jetzt die Reset Taste drücke startet der Arduino wieder. Danach ich kann ich soviele Watchdog Auslösungen haben und soviele Programme über Ethernet übertragen wie ich will, es funktioniert immer. Das Verhalten ist reproduzierbar, egal welches Programm ich nutze (auch die einfachsten Bibliotheksbeispiele), welche Hardware Kombination für Arduino und Ethernet (Original, Clone) , welches Netzteil ich verwende und welchen Spannungsanschluss (VIN oder USB Buchse) ich verwende. Das einzige was ich festgestellt habe ist, dass das Verhalten nicht auftritt, wenn ich die Spannungsversorgung zuerst in die Netzsteckdose stecke und dann in den Arduino anschliesse (Timingproblem?). Da ich nach einem Stromausfall nicht immer zu den Arduinos laufen will und die Reset drücken, würde ich mich freuen, wenn ich über das Forum eine Lösungen finden kann.
Vielen Dank!

Also das widerspricht sich doch.
Beschreib doch mal was Du hast. Es gibt verschiedene Shields.
Dann wäre das zeigen des Code sehr gut - sonst wäre hier nur raten angesagt.

Wenn der Watchdog auslöst, wird nur von vorn angefangen. Es kann sein, das da Reste noch vorhanden sind, die einen Start verhindern. Das ist alles Spekulation.

Wenn Du den WD ständig brauchst, ist was faul.
Ansonsten auf einem Pin extern einen Timer zurücksetzen.
Wenn der Timer überläuft einfach den Reset-Pin am Arduino auslösen.
Beispiel (Nicht reset sondern komplett weg):
https://www.elektormagazine.de/news/kleine-schaltungen-neu-aufgelegt-watchdog-mit-555-folge-6
Kleine Variante:
https://easyeda.com/lynxlabeling/Watchdog_Timer_555_based-8909be089d58402e81f27c6a250625e9

Erstmal danke für deine Antwort. Das sich das widerspricht ist ja genau mein Problem.
Ich beziehe mich im folgenden auf das Programm https://github.com/jandrassy/ArduinoOTA/blob/master/examples/OTEthernet/OTEthernet.ino aus der OTA Biliothek.

Nach einem Kaltstart (d.h. anlegen der Versorgungsspannung) kann ich ein Programm über Ethernet flashen. Der Flashvorgang ist auch ok, aber der Arduino startet nicht wieder, sodaß ich entweder die Resettaste drücken muss oder erneut die Spannung anlegen

Wenn ich einen Kaltstart durchführe, dann die Resettaste drücke startet der Arduino selbststandig nach dem Flashen und auch alle folgenden Flashvorgänge werden so ausgeführt.

Es stellt sich die Frage was durch das zusätzliche Drücken der Resettaste bewirkt wird, dass danach dann alles ok ist.

Alle EthernetShields haben einen W5100 oder W5200 Chip. Ansonsten habe ich das Verhalten in allen Kombinationen zwischen Orignal Arduinos, OrginalShields und Clonen festgestellt

Noch eine Anmerkung zum Watchdog. Den habe ich hier nur angeführt, weil damit das gleiche Verhalten festzustellen ist: Der Watchdog arbeitet nur dann richtig wenn ich nach dem Kaltstart die Resettaste gedrückt habe.

Es werden (auch) alle Register zurück gesetzt.

Ich hatte sowas ähnliches Mal mit einem W5100/SD-Shield und einem MEGA als Controller und dem connect zu einer MySQL-DB.
Ich habe damals meinen kompletten Code in die Tonne gehauen und von vorn neu geschrieben.
Seither funktioniert das.

Irgendein Leck, was Dir irgendwas überschreibt.

Fürs Erste würde ich unter Datei - Voreinstellungen die Warnungen beim kompilieren einschalten und die Auswahl auf alle stellen.
kompilieren und sicher gehen, das da nichts rot in der Ausgabe ist.
(durchscrollen...)

Hallo my_xy_projekt, beim Compilieren treten keine Fehler/Warnungen auf. Habe jetzt nochmal folgendes mit einen Watchdog Testprogramm gemacht:
Per Usb geflasht ohne aufgestecktes Ethernetshield ==> ok
Ethernetshield aufgesteckt und neu gestartet ==> ok
Im Programm die Ethernet Libraries included und Ethernet inititialisiert (Ethernet.begin(...)) ==> nok, der Effekt tritt wieder auf, d.h. nach Neustart muss ich erst wieder die Resettaste dücken, dann funktionierts.
Wenn sonst keiner mehr eine Idee hat werde ich wohl eine der Hardwarelösungen realisieren, die du zu verlinkt hast.

Ich weiss es nicht besser - ich habe es oben schon beschrieben - Wenn Du irgendwo Probleme in Deinem Code hast, gehört das beseitigt!
Der Watchdog ist nicht dafür gedacht Probleme im Code zu beheben!

Es gibt aber auch keine andere Möglichkeit einen automatischen/Software Reset auszuführen.
Und damit gehört zur Kompromissmasse.

Das ist soweit richtig, aber wie man sehr gut an diesem Beispiel sieht, nutzt der (interne) WD nicht immer. Du hast es ja auch schon beschrieben.
Wenn es dauerhaft und nachvollziehbar wiederholt zum auslösen kommt, ist was faul.
Das gehört gelöst.
Notfalls eben mit neuem Ansatz durch komplettes neu schreiben.

na denn.

Wie ich schon erwähnte geht es mir nicht um den Watchdog sondern dass flashen von Programmen über Ethernet. Beim Watchdog tritt der gleiche Effekt auf, wie nach dem Flashen bei Programmen, das heisst es funktioniert nur wenn ich nach dem Kaltstart einmal die Resettaste drücke. Mit dem Watchdog kann ich mögliche Abstellmaßnahmen besser testen. Ich gehe davon aus dass alles was in der Kombination Aduino Mega/Ehternet-Shield/Ethernet Library einen "Soft" Reset auslösen kann nach dem gleichen Schema nicht funktioniert, es sei denn ich mache einaml einen Hard Reset mit dem Taster.

Doch, doch. Genau um den WD geht es auch.
Die Auslösung führt nicht dahin, wo Du hin willst.
Der Effekt entspricht dem OTE-flashen.
Nach dem flashen führt der Softreset nicht zum gewünschten Ergebnis.

Ich habe inzwischen eine Lösung für mein Problem gefunden. Ich habe den Resetpin über einen Widerstand mit einem anderen Pin (A0) verbunden. Da ich ich in meinem Programm erkennen kann, ob ein Kalt- oder Warmstart vorliegt, löse ich direkt nach einem Kaltstart einen Reset aus, indem ich A0 auf Masse setze. Danach funktioniert dann alles, d.h. ich kann ohne Probleme über Ethernet Programme übertragen (auch der Watchdog würde richtig arbeiten, wenn ich ihn denn verwenden würde).
Ich weiss, dass das eine Krücke ist, aber es funzt und ich möchte nicht noch mehr Zeit in die eigentliche Ursachenfindung stecken. Danke für Eure Hilfe.

Das soll doch bestimmt nicht Kaltstart heissen.
Jetzt als Ergänzung könntest noch zeigen, wie Du merkst, das der letzte Start kalt/warm ist.

Doch das soll Kaltstart heissen. Nach Anlegen der Spannung (= Kaltstart) und dessen Feststellung im Programm löse ich im Programm den Reset aus. Die Unterscheidung ob Kalt/Warmstart mache ich so:

const char signature [] = "Text";
char * p = (char *) malloc (sizeof (signature));
bool checkIfColdStart() {
  if (strcmp (p, signature) == 0) { // signature is in RAM this was reset
    return false;
  }
  else {  // signature not in RAM this was a power on
    // add the signature to be retained in memory during reset
    memcpy (p, signature, sizeof signature);  // copy signature into RAM
    return true;
  }
}

Bei einem Kaltstart ist der String nicht im RAM und wird reingeschrieben, bei RESET ist der String immer noch vorhanden.

Das geht evtl. noch etwas besser!
Ohne malloc().


#define NOINIT __attribute__ ((section (".noinit")))


bool isColdStart() 
{
  static const char signatureP[] PROGMEM {"Text"}; // Master im Flash
  static char signatureR[sizeof signatureP] NOINIT; // Kopie im RAM
  bool result = strcmp_P(signatureR, signatureP);
  memcpy_P(signatureR, signatureP, sizeof signatureP);
  return result;
}
1 Like

Danke @combie.

Sektion .noinit wird beim Kaltstart gar nicht initialisiert, enthält also nicht 0, sondern irgendwas.
Die Wahrscheinlichkeit, dass das "Text\0" ist, ist also äußerst gering.

Und signatureR (die Adresse) kann gut zur CompileZeit bestimmt werden, statt als Ergebnis der Initialisierung des RAM zur Laufzeit immer das gleiche Ergebnis zu liefern.

Was der Unterschied zwischen Heap und .noinit, speziell im Unterschied zwischen Reset und Kaltstart ist, wäre noch zu klären. Dass der Vergleichstext nicht in den RAM muss, ist jedenfalls richtig.

Gibt es nicht (avr-hardwarenah) eine Information, die nach Reset den Grund für den Reset liefert? Ich glaube mich zu erinnern, so etwas mal irgendwo gelesen zu haben.

1 Like

Ja, das MCU Status Register.
MCUSR

Dummerweise wird der Inhalt vom Booloader des Mega verschluckt.
Der moderne Optiboot legt eine Kopie in irgendeinem Register an, welches man auslesen könnte. Steht im Quellcode des Bootloaders