Forum: Mikrocontroller und Digitale Elektronik ESP8266 12e Reset beim nach dem Starten


von Johannes B. (joba)


Angehängte Dateien:

Lesenswert?

Guten Abend,

Ich bin ein absoluter Neuling im Gebiet der Mikrokontroller und habe 
aktuell ein Problem mit meinem Sketch für den ESP.

Ein einfacher Blink Sketch läuft hervorragend.
Wenn ich nun meinen eigenen Sketch hochlade, dann kommt nach kurzer Zeit 
im Serial Monitor folgende Meldung:

 ets Jan  8 2013,rst cause:4, boot mode:(1,2)

wdt reset

Meine Pins sind wiefolgt angeschlossen:
VCC -> VCC
GND -> GND
IO15 -> LOW
IO00 -> LOW
EN -> HIGH

Da das Flashen und ausführen des Blink Sketches tadellos funktioniert, 
liegt es an meinem Code. Dieser hatte aber bereits einmal auf einem 
anderen ESP (gleiches Modell) funktioniert, deshalb frage ich mich, ob 
es auch an irgendwelchen Arduino IDE Einstellungen liegen kann (Bild der 
Einstellungen im Anhang)?

Parallel zum Anhang habe ich meinen Sketch Code auch auf Pastebin 
hochgeladen: https://pastebin.com/611pgETZ

//Edit:
Kurze Zusammenfassung was der Code macht:
Beim ersten Start ein WiFi Hotspot mit Webserver erstellen, dort gibt 
man die Adresse zum TCP Server an. Danach verbindet sich der ESP mit dem 
TCP Server und erwartet Hex-Farbwerte die er dann verarbeitet und ein 
angeschlossenen LED Strip steuert.

Vielen Dank!

: Bearbeitet durch User
von Joachim S. (oyo)


Lesenswert?

Informiere Dich am besten mal über "Watchdogs" (wdt = "watchdog timer") 
im Allgemeinen und die des Arduino-ESP8266-Frameworks im Speziellen.

Schon das "delay(5000)" am Ende Deines Codes z.B. dürfte unweigerlich 
den Watchdog auslösen. "delay" sollte man bei Arduino-ESP8266 am besten 
gar nicht erst benutzen.

von Einer K. (Gast)


Lesenswert?

Joachim S. schrieb:
> Schon das "delay(5000)" am Ende Deines Codes z.B. dürfte unweigerlich
> den Watchdog auslösen. "delay" sollte man bei Arduino-ESP8266 am besten
> gar nicht erst benutzen.

Das ist eine Fehlinformation.
Siehe hier: 
http://esp8266.github.io/Arduino/versions/2.3.0/doc/reference.html#timing-and-delays

Das Problem sind eher langlaufende Schleifen, ohne delay()


Aber davon ab, mir gefallen die delay() im Code auch nicht. Obwohl sie 
nicht DAS Problem sein werden, bringen sie andere Probleme mit sich.

von Stefan F. (Gast)


Lesenswert?

Mir kommt diese while Schleife verdächtig vor:
1
while(client.connected()) {
2
    client.readBytes(response,7);
3
    ...
4
}

Damit der ESP funktioniert, muss man nach maximal 20ms entweder

a) die loop() verlassen
b) die delay() Funktion aufrufen
c) die yield() Funktion aufrufen
d) irgendeine Library Funktion aufruden, die selbst wiederum delay() 
oder yield() enthält.

Jetzt müsste man mal in den Quelltext von client.readBytes() schauen, 
was diese Funktion genau tut.

oder einfach ein yield() hinzufügen.

von Joachim S. (oyo)


Lesenswert?

Arduino F. schrieb:
> Das ist eine Fehlinformation.
> Siehe hier:
> 
http://esp8266.github.io/Arduino/versions/2.3.0/doc/reference.html#timing-and-delays
>
> Das Problem sind eher langlaufende Schleifen, ohne delay()

Ooops, Asche auf mein Haupt, da habe ich wohl tatsächlich kompletten 
Blödsinn erzählt.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Zum Problem:

Ja, das sieht nach dem Watchdog aus. Wenn man längere Zeit in einer 
Schleite hängt, dann wird der ESP8266 resettet. delay() ist aber nicht 
das Problem, denn das fütttert den Watchdog regelmäßig. Braucht man 
tatsächlich längere Schleifen, dann hilft es, in regelmäßigen Abständen 
ein yield() einzustreuen.

Das hier finde ich sehr interessant:
1
    uint8_t i = 0;
2
    while (WiFi.status() != WL_CONNECTED) {
3
      if(i >= 60){
4
        Serial.println("Wifi Connect Timed Out. Hardreset.");
5
        ESP.reset();
6
      }

Der ESP soll also hart resettet werden, wenn keine Verbindung 
zustandekommt und die Variable i den Wert 60 erreicht hat. Abgesehen von 
der Tatsache, dass ein Reset des ESP sowieso keine Verbindungsprobleme 
löst, ist der ganze if-Block ohne Funktion, da die Variable i gar nicht 
hochgezählt wird.

Mein Eindruck: Da hat einer, der die ESP-Welt nur halb versteht, von 
einem anderen abgeschrieben (= Code zusammengeklaubt), der auch nicht so 
die rechte Ahnung hat.

Mal vom Problem abgesehen:

Das hier
1
if(RVal <= 15){
2
      sprintf(r, "0%x", RVal);
3
  }else{
4
    sprintf(r, "%x", RVal);
5
  }

lässt sich wesentlich eleganter schreiben, wenn man schon die 
Formatierungsfunktion sprintf() verwendet:
1
      sprintf(r, "%02x", RVal);

Diese Konstruktion kommt ein paar Mal vor.

Dem TO scheinen wichtige C-Grundkenntnisse zu fehlen. Er versucht sich 
aber bereits in diesem Stadium an Netzwerkprogrammierung... ein wenig zu 
früh für meinen Geschmack.

von Johannes B. (joba)


Angehängte Dateien:

Lesenswert?

Hallo zusammen,

Ich freue mich auf das zahlreiche Feedback!

Ich habe meinen Code nun etwas verändert.
An den meisten Stellen habe ich die delays wieder entfernt.
Ursprünglich waren diese auch nicht vorgesehen, allerdings hatte ich ein 
paar resets in der handleRoot() Funktion und dachte es liegt daran, dass 
Aufrufe wie webserver.stop(); und WiFi.softAPdisconnect(true); ein 
kurzen delay danach gut vertragen könnten.

Die Schleife:
1
while (WiFi.status() != WL_CONNECTED) {
2
      if(i >= 60){
3
        Serial.println("Wifi Connect Timed Out. Hardreset.");
4
        ESP.reset();
5
      }
6
      
7
      digitalWrite(LED, HIGH);
8
      delay(500);
9
      digitalWrite(LED, LOW);
10
      Serial.print(WiFi.status());
11
      Serial.print(".");
12
      i++;
13
    }


Habe ich soweit erstmal gelassen, die Zählervariable i wurde schon 
vorher am Ende hochgezählt ;) Ich hatte beobachtet, dass sich manchmal 
der ESP nicht zu meinem WLAN verbindet. Der ESP sollte sich also nach 
30sek resetten. Grund für den kompletten Reset ist, dass ja die 
eingegeben Zugangsdaten im HTML Formular falsch sein könnten und nach 
dem reset der Hotspot mit Webserver wieder startet.


Die info() Funktion konnte ich erfolgreich kürzen Dank Franks Hinweis!!
1
void info(){
2
  char r[3], g[3], b[3];
3
4
  sprintf(r, "%02x", RVal);
5
  sprintf(g, "%02x", GVal);
6
  sprintf(b, "%02x", BVal);
7
8
  sprintf(valInfo,"#%s%s%s",r,g,b);
9
}
Ich muss mich dringend mit der Doku über den Format-String auseinander 
setzen, doof das ich das nicht vorher gefunden habe.


In der loop() Funktion habe ich ebenso erstmal kaum was verändert, außer 
ein yield() am Ende der while(client.connected()) Schleife gesetzt. 
Stefans 4 Vorschläge werde ich definitiv später einmal genauer 
anschauen, allerdings wird der wdt reset aktuell nicht durch die loop() 
ausgelöst. Ich erhalte nämlich keine einzigen Serial Prints aus dem 
setup().

Nach den ganzen Anpassungen Uploade ich den Sketch und im Serial Monitor 
erscheint nun/immer noch:
1
 
2

3
 ets Jan  8 2013,rst cause:4, boot mode:(1,7)
4
5
wdt reset
Nachdem ich das Fragezeichen gesehen habe, habe ich die Serial Monitor 
Einstellungen überprüft aber nichts gefunden:
- No line ending
- 115200 baud


Ich bedanke mich aufjedenfall für das tolle Feedback und die 
Verbesserungsvorschläge!
Ich glaube es liegt an irgendeinem banalen Fehler, da der Code bereits 
zuvor funktionierte.
Ich habe auch gerade mal getestet den Code in einen neuen Sketch zu 
kopieren, gleiches Ergebnis.

von Oliver S. (phetty)


Lesenswert?

Nimm mal DOUT Flashmode. Ich kenne die Unterschiede nicht, es wird aber 
in diversen esp-Foren empfohlen.

von Johannes B. (joba)


Lesenswert?

Oliver S. schrieb:
> Nimm mal DOUT Flashmode. Ich kenne die Unterschiede nicht, es wird aber
> in diversen esp-Foren empfohlen.

Gleiches Ergebnis

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Johannes B. schrieb:
> Die info() Funktion konnte ich erfolgreich kürzen Dank Franks
> Hinweis!!
1
> void info(){
2
>   char r[3], g[3], b[3];
3
> 
4
>   sprintf(r, "%02x", RVal);
5
>   sprintf(g, "%02x", GVal);
6
>   sprintf(b, "%02x", BVal);
7
> 
8
>   sprintf(valInfo,"#%s%s%s",r,g,b);
9
> }

Geht noch kürzer und spart Herumkopierei:
1
void info(){
2
  sprintf(valInfo,"#%02x%02x%02x", RVal, GVal, Bval);
3
}

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Johannes B. schrieb:
> Nach den ganzen Anpassungen Uploade ich den Sketch und im Serial Monitor
> erscheint nun/immer noch:
>  ets Jan  8 2013,rst cause:4, boot mode:(1,7)
> wdt reset

Dann streu doch mal an signifikanten Stellen ein paar von
1
    Serial.println ("Wir sind gerade hier");
2
    Serial.flush();

ein, damit Du siehst, wo der Watchdog zuschlägt.

: Bearbeitet durch Moderator
von Schwarzseher (Gast)


Angehängte Dateien:

Lesenswert?

Johannes B. schrieb:
> VCC -> VCC
> GND -> GND
> IO15 -> LOW
> IO00 -> LOW
> EN -> HIGH

Nach dem Programmieren muss IO0 -> HIGH, beachtet?

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Johannes B. schrieb:
> ets Jan  8 2013,rst cause:4, boot mode:(1,7)

Schwarzseher schrieb:
> Nach dem Programmieren muss IO0 -> HIGH, beachtet?

Die 1 bei "boot mode:(1,7)" besagt doch, dass IO0 High ist, oder habe 
ich das falsch verstanden?

von Johannes B. (joba)


Lesenswert?

Hmm okay ich habe den Fehler.
Verdammt, damit hab ich nun gar nicht gerechnet.
Der Watchdog schlägt im direkt am Anfang des Setups nach "Setting 
PinModes" Alarm:
1
  Serial.begin(115200);
2
  Serial.println("Setting Hostname");
3
  WiFi.hostname("ESP_" + ID);
4
5
  Serial.println("Setting PinModes");
6
  pinMode(LED, OUTPUT);
7
  pinMode(REDPIN, OUTPUT);
8
  pinMode(GREENPIN, OUTPUT);
9
  pinMode(BLUEPIN, OUTPUT);

Also meine Pinnummern sind falsch!?

Ganz am Anfang werden die wiefolgt definiert:
1
#define LED 2
2
#define REDPIN 6
3
#define GREENPIN 5
4
#define BLUEPIN 2

Ich habe die Informationen aus folgenden Bild:
https://acrobotic.com/acr-00021

von Schwarzseher (Gast)


Lesenswert?

Frank M. schrieb:
> Die 1 bei "boot mode:(1,7)" besagt doch, dass IO0 High ist, oder habe
> ich das falsch verstanden?

hmmm "In the bootup message 'boot mode:(x,y)' three low bits of x are 
{MTDO, GPIO0, GPIO2}."

interpretiere ich als "GPIO2 ist LSB", also GPIO2=H, alle anderen L.

von Johannes B. (joba)


Lesenswert?

Schwarzseher schrieb:
> Nach dem Programmieren muss IO0 -> HIGH, beachtet?

Nach dem Upload startet der ESP direkt das Programm, daher muss ich den 
IO00 nur auf HIGH/Nichts setzen, wenn ich den ohne Upload neustarten 
möchte.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Johannes B. schrieb:
> #define LED 2
> #define REDPIN 6
> #define GREENPIN 5
> #define BLUEPIN 2

Damit sind die GPIO-Nummern gemeint, ist Dir das bewusst?

LED und BLUEPIN haben denselben Wert? Oder ist LED was anderes?

Finger weg von GPIO6 bis GPIO11! Die sind für den externen 
Flash-Anschluss über SPI zuständig und nicht selbst verwendbar!

REDPIN musst Du also woanders hinlegen.

von Johannes B. (joba)


Lesenswert?

Verdammt.
Ich habs gerade auch korrigiert.
1
#define LED 2
2
#define REDPIN 12
3
#define GREENPIN 14
4
#define BLUEPIN 4

Dann startet der richtig.
LED ist die BUILTIN_LED

Darauf hätte ich auch selbst kommen können, sorry!

Danke für alle Antworten und die rege Teilnahme :)

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.