M5Stamp Pico Mate #5: WiFi Verbindung programmieren

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.

M5Stamp Pico Mate - Aufbau einer WiFi-Verbindung
M5Stamp Pico Mate – Aufbau einer WiFi-Verbindung

Benötigte Ressourcen für dieses Projekt

Wenn du die Beispiele aus diesem Beitrag nachbauen / programmieren möchtest, dann benötigst du:

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.

Aufbau einer WiFi-Verbindung mit einem Android Handy - Schritt 1
Aufbau einer WiFi-Verbindung mit einem Android Handy – Schritt 1

Wenn man nun auf dieses tippt, dann muss man für die Verbindung ein Passwort eingeben.

Aufbau einer WiFi-Verbindung mit einem Android Handy - Schritt 2
Aufbau einer WiFi-Verbindung mit einem Android Handy – Schritt 2

Wenn das Passwort korrekt eingegeben wurde, dann wird die Verbindung aufgebaut.

Aufbau einer WiFi-Verbindung mit einem Android Handy - Schritt 3
Aufbau einer WiFi-Verbindung mit einem Android Handy – Schritt 3

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.

Arduino IDE - AccessPoint mit M5Stamp
Arduino IDE – AccessPoint mit M5Stamp

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.

einfacher Webserver am M5Stamp Pico Mate
einfacher Webserver am M5Stamp Pico Mate

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.

Webseite zum steuern der RGB LED auf dem M5Stamp Pico Mate
Webseite zum steuern der RGB LED auf dem M5Stamp Pico Mate

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&uuml;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.

M5Stamp Pico Mate - RGB LED per Webseite steuern
Dieses Video ansehen auf YouTube.

Kommentar hinterlassen

Deine E-Mail-Adresse wird nicht veröffentlicht.