In diesem Beitrag möchte ich dir zeigen wie du dir eine Webseite zum steuern der SMD LEDs auf dem NodeMCU Dev Kit erstellen kannst.
Im Beitrag xyz habe ich dir das NodeMCU Dev Kit bereits ausgiebig anhand einiger Beispiel vorgestellt.
Du benötigst für dieses Projekt ein bestehendes WLAN Netzwerk von welchem du die SSID und das Passwort kennst.
benötigte Bibliotheken
In den bisher gezeigten Beispielen zum NodeMCU Dev Kit kamen wir ohne zusätzliche Bibliotheken aus. Jedoch für die Einbindung in ein WLAN Netzwerk und die Bereitstellung der Webseite benötigen wir zwei Bibliotheken. Diese haben wir jedoch schon mit dem Boardtreiber für den ESP8266 installiert und müssen diese “nur” wiefolgt einbinden.
#include <ESP8266WiFi.h>
Aufbau einer WiFi Verbindung
Als erstes bauen wir eine WiFi Verbindung auf, dieses habe ich bereits in diversen Beiträgen für die Microcontroller mit ESP Chip gezeigt. Hier zeige ich dir trotzdem ein kleines Programm inkl. Ausgabe auf dem seriellen Monitor und im Browser.
Das Programm musst du natürlich um deine SSID sowie dem Passwort erweitern bevor du dieses auf den Microcontroller speicherst.
#include <ESP8266WiFi.h> const char* ssid = ""; //SSID aus dem Router const char* password = ""; //Passwort für den Zugang zum WLAN WiFiServer server(80); //Port auf welchem der Server laufen soll. void setup() { Serial.begin(9600); Serial.print("Aufbau der Verbindung zu: "); //Ausgabe der SSID auf der Seriellen Schnittstelle. Serial.println(ssid); WiFi.begin(ssid, password); //Initialisieren der Wifi Verbindung. while (WiFi.status() != WL_CONNECTED) { //Warten bis die Verbindung aufgebaut wurde. delay(500); //Einen Punkt auf der Seriellen Schnittstelle ausgeben so das der Benutzer erkennt dass, das Sketch noch läuft. Serial.print("."); } Serial.println(""); //Bei erfolgreicher Verbindung wird der folgende Text ausgeben. Serial.print("Mit "); Serial.print(ssid); Serial.print(" erfolgreich verbunden!"); server.begin(); // Starten des Servers. Serial.println("Server gestartet"); //Ausgabe auf der Seriellen Schnittstelle das der Server gestartet wurde. // Ausgabe der IP Adresse Serial.print("Adresse : http://"); Serial.print(WiFi.localIP()); Serial.println("/"); } /** * Die Funktion gibt den HTML Kopf auf dem Client aus. * Dieses wird für jeden Respond verwendet. **/ void writeResponse(WiFiClient client){ client.println("HTTP/1.1 200 OK"); client.println("Content-Type: text/html"); client.println(""); client.println("<!DOCTYPE HTML>"); client.println("<html>"); client.println("<body>"); client.println("Hello from NodeMCU Dev Kit"); client.println("</body>"); client.println("</html>"); } void loop() { //Prüfen ob sich ein Client verbunden hat, wenn nicht die Loop "verlassen" WiFiClient client = server.available(); if (!client) { return; } // Wenn sich ein Client verbunden hat solange warten bis Daten gesendet werden. Serial.println("Neuer Client verbunden."); while(!client.available()){ delay(1); } String request = client.readStringUntil('\r'); Serial.println(request); client.flush(); writeResponse(client); delay(1); //1ms. Pause }
Aufbau der Webseite
Zunächst bauen wir eine kleine Webseite in einem Editor auf dem Computer. Ich nutze dazu den Notepad++, diesen Editor kannst du dir kostenfrei unter https://notepad-plus-plus.org/downloads/ herunterladen.
Es gibt auf dieser Seite für jede LED jeweils eine Schaltfläche (HTML-Tag button) welcher über jQuery die Click Aktion zugewiesen bekommt. Das Javascript Framework jQuery binde ich im HTML Quellcode von der Herstellerseite ein, dieses bedeutet das der Code nicht ohne eine aktive Internetverbindung funktioniert!
<script type='text/javascript' src='https://code.jquery.com/jquery-3.5.1.min.js'></script>
Die Seite erstelle ich wie bereits erwähnt zunächst in einem Editor und wenn diese so passt wie gewünscht dann wird sie in die Arduino IDE kopiert. Jedoch wird dieser Code noch etwas optimiert so das doppelter Code entfernt wird.
einbinden der Bibliotheken
Damit wir uns das auslesen der übergebenen Parameter etwas einfacher gestallten nutzen wir eine zusätzliche Bibliothek
#include <ESP8266WebServer.h> ESP8266WebServer server(80); //Port auf welchem der Server laufen soll.
Diese gibt uns die Möglichkeit über eine Schleife die Argumente in der URL zu durchlaufen.
for (int i = 0; i < server.args(); i++) { String parameterName = server.argName(i); String parameterValue = server.arg(i); Serial.println(parameterName); Serial.println(parameterValue); }
Webseite als String
Der HTML Quellcode inkl. JavaScript Funktionen wird in einem String gespeichert. Dazu ist es von nöten alle doppelten Anführungszeichen in einfache zu ersetzen. Dieses sollte man VORHER über den Editor lösen.
String htmlContent = ""; htmlContent += "<!DOCTYPE HTML>\n"; htmlContent += "<html>\n"; htmlContent += "<script type='text/javascript' src='https://code.jquery.com/jquery-3.5.1.min.js'></script>\n"; htmlContent += "<style>\n"; htmlContent += "label{width:60px;margin-right:10px;margin-bottom-5px;line-height:30px}\n"; htmlContent += "fieldset{width:300px;}\n"; htmlContent += ".active{background-color:#FF6C6C;}\n"; htmlContent += "</style>\n"; htmlContent += "<body>\n"; htmlContent += "<fieldset><legend>SMD LEDs</legend>\n"; htmlContent += appendLedControlls(1,"smdLed1", led1Status, led1Status == 0 ? "AUS" : "AN" ); htmlContent += appendLedControlls(2,"smdLed2", led2Status, led2Status == 0 ? "AUS" : "AN" ); htmlContent += appendLedControlls(3,"smdLed3", led3Status, led3Status == 0 ? "AUS" : "AN" ); htmlContent += appendLedControlls(4,"smdLed4", led4Status, led4Status == 0 ? "AUS" : "AN" ); htmlContent += appendLedControlls(5,"smdLed5", led5Status, led5Status == 0 ? "AUS" : "AN" ); htmlContent += appendLedControlls(6,"smdLed6", led6Status, led6Status == 0 ? "AUS" : "AN" ); htmlContent += "</fieldset>\n"; htmlContent += "<script>\n"; htmlContent += "$(function() {\n"; htmlContent += "$( '.smdLedBtn' ).click(function() {\n"; htmlContent += "led = $(this).attr('id');"; htmlContent += "status = $(this).attr('status');"; htmlContent += "\n"; htmlContent += "if(status == 1){ status = 0; } else { status = 1; }\n"; htmlContent += "url = 'http://192.168.178.50/leds?led='+led+'&status='+status;\n"; htmlContent += "console.log(url);\n"; htmlContent += "\n"; htmlContent += "$.get(url, function( data ) {location.reload();});\n"; htmlContent += "});\n"; htmlContent += "});\n"; htmlContent += "</script>\n"; htmlContent += "</body></html>\n";
Da der Code für die Schaltflächen sehr ähnlich ist wird dieser in einer Funktion ausgelagert und die Parameter übergeben.
String appendLedControlls(int numb, String id, int ledStatus, String btnText ) { String ledControlls = ""; ledControlls += "<label for = '" + id + "'>"+String(numb,DEC)+"</label>\n"; ledControlls += "<button id='" + id + "' class='smdLedBtn "; if (ledStatus == 0) { ledControlls += "'"; } else { ledControlls += "active'"; } ledControlls += " status='" + String(ledStatus, DEC) + "'>"; ledControlls += btnText; ledControlls += "</button><br/>\n"; return ledControlls; }
der fertige Quellcode
#include <ESP8266WiFi.h> #include <ESP8266WebServer.h> #define led1 2 #define led2 0 #define led3 4 #define led4 5 #define led5 14 #define led6 16 const char* ssid = ""; //SSID aus dem Router const char* password = ""; //Passwort für den Zugang zum WLAN ESP8266WebServer server(80); //Port auf welchem der Server laufen soll. int led1Status = 0; int led2Status = 0; int led3Status = 0; int led4Status = 0; int led5Status = 0; int led6Status = 0; void setup() { Serial.begin(9600); pinMode(led1, OUTPUT); pinMode(led2, OUTPUT); pinMode(led3, OUTPUT); pinMode(led4, OUTPUT); pinMode(led5, OUTPUT); pinMode(led6, OUTPUT); Serial.print("Aufbau der Verbindung zu: "); //Ausgabe der SSID auf der Seriellen Schnittstelle. Serial.println(ssid); WiFi.begin(ssid, password); //Initialisieren der Wifi Verbindung. while (WiFi.status() != WL_CONNECTED) { //Warten bis die Verbindung aufgebaut wurde. delay(500); //Einen Punkt auf der Seriellen Schnittstelle ausgeben so das der Benutzer erkennt dass, das Sketch noch läuft. Serial.print("."); } Serial.println(""); //Bei erfolgreicher Verbindung wird der folgende Text ausgeben. Serial.print("Mit "); Serial.print(ssid); Serial.print(" erfolgreich verbunden!"); server.begin(); // Starten des Servers. Serial.println("Server gestartet"); //Ausgabe auf der Seriellen Schnittstelle das der Server gestartet wurde. // Ausgabe der IP Adresse Serial.print("Adresse : http://"); Serial.print(WiFi.localIP()); Serial.println("/"); server.on("/leds", callHandleLeds); } void callHandleLeds() { String led = ""; for (int i = 0; i < server.args(); i++) { String parameterName = server.argName(i); String parameterValue = server.arg(i); Serial.println(parameterName); Serial.println(parameterValue); if (parameterName == "led") { led = parameterValue; Serial.println(led); } if (parameterName == "status") { int ledStatus = parameterValue.toInt(); Serial.println(ledStatus); if (led == "smdLed1") { led1Status = ledStatus; } else if (led == "smdLed2") { led2Status = ledStatus; } else if (led == "smdLed3") { led3Status = ledStatus; } else if (led == "smdLed4") { led4Status = ledStatus; } else if (led == "smdLed5") { led5Status = ledStatus; } else if (led == "smdLed6") { led6Status = ledStatus; } } setLedStatus(); } writeResponse(); } void setLedStatus() { digitalWrite(led1, led1Status == 0 ? HIGH : LOW); digitalWrite(led2, led2Status == 0 ? HIGH : LOW); digitalWrite(led3, led3Status == 0 ? HIGH : LOW); digitalWrite(led4, led4Status == 0 ? HIGH : LOW); digitalWrite(led5, led5Status == 0 ? HIGH : LOW); digitalWrite(led6, led6Status == 0 ? HIGH : LOW); } /** Die Funktion gibt den HTML Kopf auf dem Client aus. Dieses wird für jeden Respond verwendet. **/ void writeResponse() { String htmlContent = ""; htmlContent += "<!DOCTYPE HTML>\n"; htmlContent += "<html>\n"; htmlContent += "<script type='text/javascript' src='https://code.jquery.com/jquery-3.5.1.min.js'></script>\n"; htmlContent += "<style>\n"; htmlContent += "label{width:60px;margin-right:10px;margin-bottom-5px;line-height:30px}\n"; htmlContent += "fieldset{width:300px;}\n"; htmlContent += ".active{background-color:#FF6C6C;}\n"; htmlContent += "</style>\n"; htmlContent += "<body>\n"; htmlContent += "<fieldset><legend>SMD LEDs</legend>\n"; htmlContent += appendLedControlls(1,"smdLed1", led1Status, led1Status == 0 ? "AUS" : "AN" ); htmlContent += appendLedControlls(2,"smdLed2", led2Status, led2Status == 0 ? "AUS" : "AN" ); htmlContent += appendLedControlls(3,"smdLed3", led3Status, led3Status == 0 ? "AUS" : "AN" ); htmlContent += appendLedControlls(4,"smdLed4", led4Status, led4Status == 0 ? "AUS" : "AN" ); htmlContent += appendLedControlls(5,"smdLed5", led5Status, led5Status == 0 ? "AUS" : "AN" ); htmlContent += appendLedControlls(6,"smdLed6", led6Status, led6Status == 0 ? "AUS" : "AN" ); htmlContent += "</fieldset>\n"; htmlContent += "<script>\n"; htmlContent += "$(function() {\n"; htmlContent += "$( '.smdLedBtn' ).click(function() {\n"; htmlContent += "led = $(this).attr('id');"; htmlContent += "status = $(this).attr('status');"; htmlContent += "\n"; htmlContent += "if(status == 1){ status = 0; } else { status = 1; }\n"; htmlContent += "url = 'http://192.168.178.50/leds?led='+led+'&status='+status;\n"; htmlContent += "console.log(url);\n"; htmlContent += "\n"; htmlContent += "$.get(url, function( data ) {location.reload();});\n"; htmlContent += "});\n"; htmlContent += "});\n"; htmlContent += "</script>\n"; htmlContent += "</body></html>\n"; server.send(200, "text/html", htmlContent); } String appendLedControlls(int numb, String id, int ledStatus, String btnText ) { String ledControlls = ""; ledControlls += "<label for = '" + id + "'>"+String(numb,DEC)+"</label>\n"; ledControlls += "<button id='" + id + "' class='smdLedBtn "; if (ledStatus == 0) { ledControlls += "'"; } else { ledControlls += "active'"; } ledControlls += " status='" + String(ledStatus, DEC) + "'>"; ledControlls += btnText; ledControlls += "</button><br/>\n"; return ledControlls; } void loop() { server.handleClient(); }
Download
Hier nun der Quellcode zum einfachen Download.