stabiler Webserver mit dem Arduino

stabiler Webserver mit dem Arduino

Ich hab wirklich lange gebraucht, um dahinter zu kommen.
Im Netz liest man auch öfters, dass der Adruino schnell abstürzt und als Webserver nicht so richtig geeignet wäre.

Solche Aussagen muss man sicherlich erst einmal immer in den richtigen Kontext setzen, welches bei den meisten Kommentaren ja nicht immer ganz so leicht fällt, da man den Hintergrund gar nicht kennt.

Schluss letztendlich ist es dann wie bei so vielen Dingen.
Probieren geht über studieren – Man weißt erst ob es funktioniert, wenn es läuft oder einem um die Ohren fliegt.

Ich möchte den Arduino nur als ganz kleinen Webserver mit einem REST-Interface einsetzen, um eben diesen darüber von außerhalb zu steuern. Im Hinblick auf ein Smarthome  – wer hat da nicht diese Anforderung.

Mein erster Test war allerdings desaströs – wobei wir bei dem „um die Ohren fliegen“ wären.
Ich dafür meinen Arduino mit dem LAN-Shield bestückt und das original Tutorial von der Seite ausprobiert.
https://www.arduino.cc/en/Tutorial/WebServer
Ich war enttäuscht.
Es lief – 1-2 mal (Zugriff über den Webbrowser auf den Arduino).
Danach stürzte der Arduino unregelmäßig, regelmäßig ab.
Wie sollte man so etwas unstabiles für ein Smarthome benutzen…

Nach einigem hin und her probieren bin ich dem eigentlichem Problem aber auf die schliche gekommen.
Wobei es mir immer noch rätselhaft ist, wie man das Tutorial nicht entsprechend ergänzt.

Das Problem ist, dass der Arduino maximal 4 Request zur gleichen Zeit verarbeiten kann – kommen mehr, läuft der Speicher über und das Gerät stürzt ab. Soweit die Fehlerklärung.

Dieser Fakt entsprach allerdings nicht meinem Versuchsaufbau.
Erst bei näherem Hinschauen (ins HTTP-Protokoll) sah ich das diverse Geräte in meinem Heimnetz Broadcast-Nachrichten auch an meinen Adruino verschickten.
Aber 4 Stück zeitgleich eher nicht.
Bei näherer Untersuchung der HTTP-Anfragen sah man aber, dass diese sich teilweise nicht richtig beendeten (warum auch immer – Verbindungsprobleme etc. wie auch immer). Aufjedenfall blieb der Server für verschiedene Clients offen, was natürlich fatal ist.

Problem erkannt – Probleme gebannt.
Ich bin sehr restriktiv vor gegangen – weil das Problem wirklich nervte – ich wollte einen möglichst stabilen Server!
Daher hab sind 1-2 Dinge ggf. doppelgemoppelt und 1-2 Dinge sehr auf meinen Anwendungsfall zugeschnitten (eine kurze Kommunikation zwischen Client und Server) aber mit dem Ergebnis eines stabilen Arduino-Webservers! 🙂

Das wohl Wichtigste ist es die Antwortzeit zu beschränken – wenn der Client sich nicht in einer Ihm zugewiesenen Zeit anmeldet wird er rausgeschmissen:

if(!client.connected()) {
return;
}

unsigned long timeOut = millis()+250;
while(!client.available() && (millis()<timeOut) ){
delay(1);
}
if(millis()>timeOut) {
Serial.println(„client connection timeOut!“);
return; //Abbruch
}

Dies sogt schon einmal dafür – das der Arduino nicht ständig abstürzt nur weil man ein paar mal hintereinander im Browser schnell die Seite aktualisiert. Anscheinend bricht Chrome die Kommunikation nämlich direkt ab und der Arduino-Prozess blieb hängen – jetzt nicht mehr 🙂

Das gleiche kann uns aber auch noch 1-2 Codestellen später passieren – also auch hier noch einmal:

if (client.available()) {
unsigned long timeOut = millis()+250;
while(client.findUntil(„pin“, „\n\r“) && (millis()<timeOut )){ // suchen bis Ende der Zeile nach „pin“
//warten bis alles eingeladen ist
eingabeAuswerten(client);
}
if(millis()>timeOut ){
Serial.println(„client-Daten unvollstaendig“);
return; //Abbruch
}
….

Hier hat der Client sich zwar angemeldet – aber übersendet nicht alle Daten – auch gemein – aber auch damit kann nun der Arduino umgehen 🙂
Die Länge der TimeOuts muss man je nach Anwendungsfall natürlich entsprechend anpassen.

Zu guter Letzt noch 1-2 Dinge, die ggf. für Stabilität sorgen:
Serial.println(„html erstellt“);
delay(1); //wir geben dem Browser Zeit die Daten auch zu lesen. Ursprung war hier das OriginalTutorial, allerdings gibt es auch:
client.flush();//alles raus senden…!!! und warten (laut Dokumentation), ist dies nicht eigentlich die bessere Wahl?
// close the connection:
client.stop();
Serial.println(„client disconnected“);

 

Mit diesen 2-3 Ergänzungen läuft mein Arduino wirklich stabil! Endlich 🙂
Wie man es sich vorstellt und von Anfang an auch erwartet und gewünscht hätte.

Viel Spaß damit 🙂

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.