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


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Reinhard #. (gruebler)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht lesenswert

von Benjamin S. (recycler)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.