Forum: Mikrocontroller und Digitale Elektronik ESP32 gleichzeitig MQTT und Webserver


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 R. K. (rkr)


Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen,

ich habe mal eine Frage zum gleichzeitigen Einsatz eines ESP32 als 
Webserver und als MQTT-Client. Ich möchte über MQTT Daten empfangen und 
diese über den Webserver als HTML darstellen.

Bisher benutze ich folgende Struktur (ich habe nur die relevanten Teile 
eingefügt):
1
#include <WiFi.h> 
2
#include <PubSubClient.h> 
3
4
WiFiClient espClient; 
5
PubSubClient client(espClient); 
6
7
// Set web server port number to 80 
8
WiFiServer server(80); 
9
10
void setup(){ 
11
    client.setServer(mqtt_server, 1883); 
12
    client.setCallback(callback); 
13
14
    //Subscribe to topics 
15
    ... 
16
}
17
18
void loop(){ 
19
    client.loop)=; 
20
21
    WiFiClient client = server.available();   // Listen for incoming clients 
22
23
    if (client) { 
24
        while (client.connected()){ 
25
            //Print HTML 
26
            ... 
27
        } 
28
    } 
29
}

Wenn der ESP32 rebootet funktioniert er als MQTT Client. Die Nachrichten 
sind auf dem seriellen Monitor sichtbar. Sobald ich allerdings die HTML 
über einen Browser aufrufe, empfängt er keine MQTT-Nachrichten mehr. Ich 
gehe davon aus, dass der HTTP-Request des Browsers den Client 
reinitialisiert und daher die MQTT-Einstellungen weg sind. Wie im Code 
zu sehen, habe ich auch das HTTP-Client-Objekt schon umbenannt, damit es 
nicht beides mal "client" heißt, hat aber nicht geholfen. Hat jemand 
eventuell eine Idee, wie man das lösen könnte? Oder vielleicht einen 
Beispiel-Code? Wäre sehr dankbar.

Beste Grüße

: Bearbeitet durch User
von Dunno.. (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Sorry, aber so gekürzt ist dein Codeschnipsel nichtssagend.

von Stefan ⛄ F. (stefanus)


Bewertung
0 lesenswert
nicht lesenswert
Vermutlich hast du in deiner while Schleife blockierende Funktionen. Ich 
wette, du kannst auch nicht mehrere Webseiten gleichzeitig abrufen (über 
mehrere Verbindungen).

Es ist wichtig, dass du keine Warteschleifen baust und nur dann Daten an 
den Client sendest, wenn der ESP genug Pufferspeicher frei hat. 
Ansonsten wartet er nämlich doch.

Eventuell hilft Dir der Artikel 
http://stefanfrings.de/esp8266/index.html#tcpsketch . Dieses Code 
Beispiel kann mehrere Verbindungen gleichzeitig bedienen. Da siehst du, 
wie man auf Input warten kann, ohne zu blockieren, also ohne klassische 
Warteschleife.
Beim Senden habe ich es einfach, weil die Antworten so klein sind dass 
sie immer in den Sendepuffer passen. Da musst du für deine Anwendung 
vielleicht etwas mehr Hirnschmalz rein stecken.

Vielleicht hilft dazu auch der Artikel 
http://stefanfrings.de/multithreading_arduino/index.html

: Bearbeitet durch User
von Sascha W. (sascha-w)


Bewertung
0 lesenswert
nicht lesenswert
@r.k.

wie hast du dir das vorgestellt, per HTML holt der Client Daten vom 
Server ab die zu diesem Zeitpunkt schon zur Verfügung stehen müssen. Er 
darf/kann nicht warten bis über MQTT wieder mal was kommt. Du musst die 
MQTT-Daten zwischenspeichern (wie lang?) und dann ausliefern wenn eine 
Anfrage kommt (Puffer dann leeren), der Client muss dann regelmäßig die 
Seite abrufen um Änderungen mitzubekommen. Geht aber nur mit genau einem 
Client. Das beste währe allerdings die Verwendung einer 
Websocket-Verbindung da kannst du die eingehenden Nachrichten zum 
Webclient live durchreichen.
Für den Webserver gibts auch eine Lib für AsyncHTMLServer oder 
AsyncWebServer (weiß grad nicht den genauen Namen) die wie der MQTT 
nicht blockierend arbeitet.

Sascha

von R. K. (rkr)


Bewertung
0 lesenswert
nicht lesenswert
@Stefan
Danke für den Tipp! Tatsächlich war in der loop ein delay(1000) 
eingebaut. Nachdem ich das entfernt habe funktioniert es. Wäre nicht 
darauf gekommen, dass es daran liegt...

@Sascha
Die Daten werden von ESP zwischengespeichert und sind schon vorbereitet, 
wenn der HTTP-Request kommt. Da über MQTT nur etwa jede Stunde eine neue 
Nachricht kommt, ist es auch ok, wenn die Website die Daten nicht 
automatisch aktualisiert. Ich werde aber trotzdem mal auch eine Variante 
mit Websocket versuchen. Danke!

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.