Forum: Mikrocontroller und Digitale Elektronik ESP 12E im WLAN. Seltsames Verhalten


von Reinhard #. (gruebler)


Lesenswert?

Hallo zusammen
Ich habe hier ein ModeMCU mit einem ESP 12E Modul
das ich als Server in meinem WLAN laufen lassen
will. Später sollen andere ESPs hier Messwerte
hinschicken, die ich dann über meinen Browser auslesen
möchte.
Ich habe erst mal ein kleines Testprogramm geschrieben,
um einen Taster und den Analogkanal abzurufen. Das
Funktioniert auch ganz prima mit dem folgenden Programm.
1
#include <ESP8266WiFi.h>
2
#include <ESP8266WebServer.h>
3
4
#define WLAN_OK D1 //LED leuchtet, wenn WLAN-Anbindung vorhanden
5
#define Messung D2 //LED leuchtet kurz, wenn DHT22 ausgewertet wird
6
#define Kontrol D3 //LED für Testzwecke
7
#define Poti    A0 //Analogeingang
8
#define Taste   D4 //Binäreingang geht auf LOW wenn Taste gedrückt
9
10
int AD_Wert = 0;
11
12
unsigned long letzterCheck = 0; //Speicher für den Zeitpunkt der letzten
13
unsigned long aktZeit = 0;      //Erfassung und den aktuellen Zeitwert in ms
14
const long Interval = 5000L;    //Unbedingt unsigned nehmen!!!
15
                                 //Der Messinterval ist 5 Sekunden
16
const char* SSID = "geheim";          //Name meines WLANs (SSID)
17
const char* NWSch = "sag ich nicht";  //Netzwerkschlüssel
18
19
ESP8266WebServer MiniServ(80);  //Mini-WEB-Server starten. Komunikation 
20
                                //über Port 80. Das ist ein Standartport
21
void Antwort_Root()
22
{
23
   MiniServ.send(200, "text/html", "Nichts im Root-Bereich");
24
}
25
26
void Antwort_Analog()
27
{
28
   AD_Wert = analogRead(Poti);
29
   MiniServ.send(200, "text/html", String(AD_Wert));
30
}
31
32
void Antwort_Taste()
33
{
34
   MiniServ.send(200, "text/html", String("Taste ist ") + 
35
                                   ((digitalRead(Taste)) ? "frei" : "betaetigt"));
36
}
37
void setup(void)
38
{
39
   pinMode(WLAN_OK, OUTPUT);
40
   pinMode(Messung, OUTPUT);
41
   pinMode(Kontrol, OUTPUT);
42
   pinMode(Taste, INPUT_PULLUP);
43
44
   //Verbindung zum WLAN herstellen
45
   WiFi.begin(SSID, NWSch);
46
47
   //LED blinkt während des Verbindungsaufbaus
48
   while (WiFi.status() != WL_CONNECTED)
49
   {
50
      digitalWrite(WLAN_OK, true);
51
      delay(150);
52
      digitalWrite(WLAN_OK, false);
53
      delay(150);
54
   }
55
   digitalWrite(WLAN_OK, true);  //WLAN-Verbindung steht
56
57
   MiniServ.on("/", Antwort_Root);
58
   MiniServ.on("/analog", Antwort_Analog);
59
   MiniServ.on("/Taste", Antwort_Taste);
60
   //Mini-Server starten
61
   MiniServ.begin();
62
}
63
64
void loop(void)
65
{
66
   //Prüft, ob anfragen von einem Client kommen
67
   MiniServ.handleClient();
68
}

Nun wollte ich in der "loop" den AD-Wert durch
Mittelwertbildung mehrerer Messungen etwas glätten.
Probeweise habe ich die "loop" so geschrieben
1
void loop(void)
2
{
3
   //Prüft, ob anfragen von einem Client kommen
4
   MiniServ.handleClient();
5
   AD_Wert = analogRead(Poti);
6
}

Nun läst sich der Mini-Server nicht mehr
ansprechen! Der Browser bricht wegen Zeitüberschreitung
ab. Warum??
Schreibt man die loop so, funktioniert es wieder.
1
void loop(void)
2
{
3
   //Prüft, ob anfragen von einem Client kommen
4
   MiniServ.handleClient();
5
   delay(1);
6
   AD_Wert = analogRead(Poti);
7
}

Kann mir das jemand erklären?

von John Doe (Gast)


Lesenswert?


von Benjamin S. (recycler)


Lesenswert?

Die loop ist eigentlich eine While (1) schleifen. Dabei kommen die 
Hintergrundthreads nicht dran. Das muss man explizit machen, z.B. über 
yield() oder über ein delay, was implizit die Hintergrundfunktionen 
aufruft.

Dabei gibt es noch einene Fallstrick. Ist das Delay zu groß (mehr als 
~2000 - 3000 ms) dann schlägt der Watchdog zu und es gibt einen Reset.

Versuchs einfach mal - entweder mit Delay oder mit yield().

von honk (Gast)


Lesenswert?

Benjamin S. schrieb:
> Die loop ist eigentlich eine While (1) schleifen. Dabei kommen die
> Hintergrundthreads nicht dran. Das muss man explizit machen, z.B. über
> yield() oder über ein delay, was implizit die Hintergrundfunktionen
> aufruft.
>
> Dabei gibt es noch einene Fallstrick. Ist das Delay zu groß (mehr als
> ~2000 - 3000 ms) dann schlägt der Watchdog zu und es gibt einen Reset.
>
> Versuchs einfach mal - entweder mit Delay oder mit yield().


So ein Quark. loop macht eben genau das, was auch yield() macht.
Schau mal in den Quellcode.
1
static void loop_wrapper() {
2
    static bool setup_done = false;
3
    preloop_update_frequency();
4
    if(!setup_done) {
5
        setup();
6
        setup_done = true;
7
    }
8
    loop();
9
    run_scheduled_functions();
10
    esp_schedule();
11
}

Also nix mit yield oder delay. John Doe hat Recht mit seiner Anmerkung.

Was den Watchdog angeht:
Hier muss man unterscheiden zwischen dem Software- und dem 
Hardware-Watchdog. Den Software-Watchdog kann man deaktivieren, dann hat 
man ein paar Sekungen mehr zur Verfügung.
Steht aber alles in den Dokus von Espressif.

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.