In diesem Beitrag möchte ich dir zeigen, wie du eine WiFi Verbindung mit dem M5Stamp Pico Mate herstellen kannst. Dabei gehe ich darauf ein, wie du den M5Stamp als AccessPoint sowie als WebServer verwenden kannst.
Benötigte Ressourcen für dieses Projekt
Wenn du die Beispiele aus diesem Beitrag nachbauen / programmieren möchtest, dann benötigst du:
- einen M5Stamp Pico Mate*,
- ein USB-Typ-C Datenkabel*,
- einen ESP32 Downloader*
Hinweis von mir: Die mit einem Sternchen (*) markierten Links sind Affiliate-Links. Wenn du über diese Links einkaufst, erhalte ich eine kleine Provision, die dazu beiträgt, diesen Blog zu unterstützen. Der Preis für dich bleibt dabei unverändert. Vielen Dank für deine Unterstützung!
einen AccessPoint programmieren
Wie du einen WebServer in der Arduino IDE programmierst habe ich dir bereits in einigen Beiträgen zum Wemos D1 Mini gezeigt. Dieses Programm kann man 1:1 auch für den M5Stamp übernehmen.
#include <Arduino.h> #include <WiFi.h> void setup() { //beginn der seriellen Kommunikation mit 115200 Baud Serial.begin(115200); //erzeugen eines AccessPoints mit //dem Namen "M5Stamp" und dem Passwort "testPw123" //Hinweis: das PW muss min. 8 Zeichen lang sein! WiFi.softAP("M5Stamp", "testPw123"); } void loop() { //Ausgabe der Anzahl der verbundenen Geräte. Serial.printf("Anzahl der Verbundenen Geräte= %d\n", WiFi.softAPgetStationNum()); //eine Pause von 5 Sek. delay(5000); }
Wenn man das Programm hochgeladen hat, dann kann man sich mit einem Handy, Tablet oder auch PC mit dem M5Stamp Pico Mate verbinden
In der WLAN Übersicht am Handy wird dieses neue Netzwerk als “M5Stamp” angezeigt.
Wenn man nun auf dieses tippt, dann muss man für die Verbindung ein Passwort eingeben.
Wenn das Passwort korrekt eingegeben wurde, dann wird die Verbindung aufgebaut.
Ggf. wird ein Hinweis angezeigt, ob wirklich zu diesem Netzwerk verbunden werden soll, denn es gibt ja keine aktive Internetverbindung.
In der Arduino IDE wird im seriellen Monitor die Ausgabe erzeugt, dass sich ein Gerät verbunden hat.
einen WebServer programmieren
Ein WebServer dient dazu einem benutzer Services zu bieten, dieses können zbsp. Tools wie das Komprimieren von Bilder / Videos sein, oder auch einfache Webseiten.
Als Erstes möchte, ich dir nun zeigen, wie du eine einfache HTML Seite auslieferst.
#include <WiFi.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(115200); //Baudrate für die Serielle Geschwindigkeit. delay(10); //10ms. Warten damit die Seriele Kommunikation aufgebaut wurde. 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.println(" 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("<head>"); client.println("</head>"); client.println("<body>"); client.println("<h1>Its Works!</h1>"); 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."); writeResponse(client); delay(1); //1ms. Pause }
Im ersten Schritt, schreiben wir eine einfache Zeile auf die Seite um zu testen, ob Daten an den Client ausgeliefert werden.
Nachdem nun dieser Test funktioniert, können wir mit einem komplexeren Beispiel fortfahren.
RGB LED per Webseite steuern
Im Beitrag Wemos D1 mini Shield: RGB LED per Webanwendung steuern habe ich dir bereits gezeigt, wie du am Wemos D1 Mini ein RGB LED Shield per Webseite steuern kannst. Hier möchte ich dir nun dieses kleine Programm für den M5Stamp Pico Mate umprogrammieren.
Auf dem GitHub Repository StefanDraeger/m5Stack unter m5stamp_pico_mate/wifi/controll_rgb_led/ findest du die gesamten Codes für den Mikrocontroller sowie für den Server.
Aufbau der Webseite
Auf der Webseite soll ein statisches Bild des M5Stamp Pico Mate angezeigt werden, daneben dann jeweils 3 Slider für die Farben rot, grün und blau, sowie ein Slider Element für die Helligkeit.
Des Weiteren wird ein kleines Vorschaubild der Farbe erstellt. Da die Farbe auf dem Monitor von der echten RGB Farbe abweichen kann, muss man mit einer kleinen Toleranz herangehen.
Sketch in der Arduino IDE
Hauptprogramm: “m5stamp_rgb_led_webpage.ino”
Zunächst zum Sketch / Programm in der Arduino IDE.
#include <WiFi.h> #include <FastLED.h> #include "credentials.h" #include "rgb_led.h" WiFiServer server(80); //Port auf welchem der Server laufen soll. void startWiFiConnection(); void setup() { Serial.begin(115200); //Baudrate für die Serielle Geschwindigkeit. delay(10); //10ms. Warten damit die Seriele Kommunikation aufgebaut wurde. startWiFiConnection(); FastLED.addLeds<SK6812, DATA_PIN, GRB>(leds, NUM_LEDS); } /** Aufbauen der WiFi Verbindung */ void startWiFiConnection() { 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.println(" 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("<head>"); client.println("<script type='text/javascript' src='http://progs.draeger-it.blog/m5stamp/rgbled/js/jquery-3.6.0.min.js'></script>"); client.println("<script type='text/javascript' src='http://progs.draeger-it.blog/m5stamp/rgbled/js/functions.js'></script>"); client.println("<link rel='stylesheet' href='http://progs.draeger-it.blog/m5stamp/rgbled/css/slider.css'/>"); client.println("<link rel='stylesheet' href='http://progs.draeger-it.blog/m5stamp/rgbled/css/styles.css'/>"); client.println("</head>"); client.println("<body>"); client.println(getIpAdressTag()); client.println("<div class='wrapper'>"); client.println(" <h1>M5Stamp Pico Mate - RGB LED</h1>"); client.println(" <div class='container'>"); client.println(" <img src='http://progs.draeger-it.blog/m5stamp/rgbled/image/m5stamp_pico_mate.png' width='200' height='*'/>"); client.println(" </div>"); client.println(" <div class='container'>"); client.println(getSliderElement("Rot", redValue, "redSlider", 0, 255)); client.println(getSliderElement("Grün", greenValue, "greenSlider", 0, 255)); client.println(getSliderElement("Blau", blueValue, "blueSlider", 0, 255)); client.println(getSliderElement("Helligkeit", brightnessValue, "brightnessSlider", 0, 100)); client.println(" </div>"); client.println(" <div class='container'>"); client.println(" <label>Vorschau</label>"); client.println(" <div class='preview'>"); client.println(" </div>"); client.println(" </div>"); client.println(" <div style='clear:both;'></div>"); client.println(" <div>"); client.println(" <input type='button' value='Absenden' onClick='sendValues();'/>"); client.println(" </div>"); client.println("</div>"); client.println("</body>"); client.println("</html>"); } String getSliderElement(String label, int value, String elementId, int minValue, int maxValue) { String slider = ""; slider = slider + "<label for='" + elementId + "'>" + label + "</label>"; slider = slider + "<div class='slidecontainer'><input type='range' min='" + minValue + "' max='" + maxValue + "' value='"; slider = slider + value; slider = slider + "' class='slider' id='" + elementId + "'/></div>"; return slider; } String getIpAdressTag() { String ipAdressTag = ""; ipAdressTag = ipAdressTag + ""; ipAdressTag = ipAdressTag + "<script>"; ipAdressTag = ipAdressTag + "var ipAdress='"; ipAdressTag = ipAdressTag + WiFi.localIP().toString(); ipAdressTag = ipAdressTag + "';"; ipAdressTag = ipAdressTag + "</script>"; return ipAdressTag; } void handleClientRequest(WiFiClient client) { //Lesen der Anfrage vom Client String request = client.readStringUntil('\r'); Serial.print("Vom Client empfangen: "); Serial.println(request); client.flush(); char d1 = '?'; char d2 = '&'; int counter = 0; for (int i = 0; i < request.length(); i++) { char c = request.charAt(i); if (c == d1 || c == d2) { String value = request.substring(i + 3, i + 6); int intValue = value.toInt(); Serial.println(value); if (counter == 0) { redValue = intValue; } else if (counter == 1) { greenValue = intValue; } else if (counter == 2) { blueValue = intValue; } else if (counter == 3) { brightnessValue = intValue; } Serial.println("found"); counter++; } } updateRgbLed(); } 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."); handleClientRequest(client); writeResponse(client); delay(1); //1ms. Pause }
Datei “credentials.h”
In der Datei credentials.h sind die Zugangsdaten für die WiFi-Verbindung zum lokalen WLAN Netzwerk hinterlegt.
const char* ssid = ""; //SSID aus dem Router const char* password = ""; //Passwort für den Zugang zum WLAN
Datei “rgb_led.h”
Die Datei “rgb_led.h” enthält die Funktion “updateRgbLed” sowie die Felder um die LED am M5Stamp Pico zu steuern.
#define NUM_LEDS 1 #define DATA_PIN 27 CRGB leds[NUM_LEDS]; int redValue = 0; int greenValue = 0; int blueValue = 0; int brightnessValue = 10; void updateRgbLed() { leds[0].red = redValue; leds[0].green = greenValue; leds[0].blue = blueValue; FastLED.setBrightness(map(brightnessValue,0,100,1,255)); FastLED.show(); }
Video
Hier nun das Video zum oben gezeigten Code.