Als Basis für die PEL035 dient das Chinamodul XY-FZ35. Dieses Modul kann Spannungen von 1,5 V ~ 25 V und Ströme bis 5A bei einer maximalen Belastung von 35W verarbeiten. Die Einstellung des Laststromes erfolgt mittels Drehimpulsgeber an der Frontplatte oder über eine serielle Schnittstelle. Siehe: https://www.peters-bastelkiste.de/elektronische-last-xy-fz35/

Für die drahtlose Steuerung kommt ein M5ATOM Lite zum Einsatz. Eine ADC-Unit zur Messung der Spannung am Lasteingang. Das FZ-35-Modul ermittelt diese Spannung zwar auch, verwendet sie aber nur intern. Ausserhalb steht sie nicht zur Verfügung. Die Lüftersteuerung erfolgt vom M5ATOM aus. Ein Spannungsteiler aus Widerstand und NTC liefert eine der Temperatur umgekehrt proportinale Spannung die vom internen ADC des M5ATOM gemessen wird. Dieser Wert wird zur 2-Punkt-Steuerung des Lüfters herangezogen (siehe https://www.peters-bastelkiste.de/temperaturmessung-mit-esp32-und-ntc/).

Netzteil

Das Netzteil liefert 5 Volt für den M5Atom und 12 Volt für den Lüfter und das FZ-35-Modul. Es ist ganz einfach mit AC/DC-Modulen aufgebaut. Allerdings habe ich es noch um einen Tiefpassfilter zum Netz hin und Kondensatoren am Ausgang ergänzt. Diese Maßnahmen werden von einigen Anbietern vorgeschlagen. Hi-Link schlägt sogar eine stromkompensierte Drossel vor.

M5Atom Adapter

Der M5ATOM bekommt einen Adapter, der zum Einen die Befestigung an der Frontplatte ermöglicht, zum Anderen die Anschlüsse des M5ATOM auf einer 14-poligen 2,54mm Stiftleiste sammelt.

PINBedeutung
1Ground
2Ground
3+ 3,3 Volt vom M5ATOM
4+ 3,3 Volt vom M5ATOM
5+ 5 Volt – Stromversorgung für M5ATOM
6+ 5 Volt – Stromversorgung für M5ATOM
7GPIO 23
8GPIO 19
9GPIO 33 – ADC1-5
10GPIO 22
11GPIO 21 – TX
12GPIO 25 – RX
13Grove – SCL
14Grove – SDA

Platine für den Adapter

Erste Version der Platine
V. 1.1 mit Lötads für 0,1µF Kondensator am ADC Eingang unten rechts

Steuerung

Die Steuerungsplatine dient in erster Linie der Signalverteilung zwischen den verschiedenen Baugruppen. Weiterhin enthält sie den NTC zur Temperaturmessung und einen Transistor zum Schalten des Lüfters.

Die Platine

Inzwischen habe ich eine Platine entworfen und fertigen lassen.

Fehler auf der Platine

  • Eine eventuelle Pegelanpassung der RX/TX-Signale zwischen FZ35 und M5ATOM fehlt.
  • Positive Spannung für FZ35 an PIN 4 der 5-poligen Verbindung fehlt.
Die korrigierte Version 1.1

Die Geschichte von einem der auszog ein Abenteuer zu erleben.

Elementare Grundkenntnisse vom Netzwerk sind mir ja bekannt. Meine LAN-Verkabelung habe ich alleine hinbekommen. Das beschränkte sich aber überwiegend darauf Stecker in Buchsen zu stecken, Kabel zu verlegen und die Kabelenden in die richtigen Kontakte zu pressen.

Mit der Softwareseite, geschweige denn WLAN habe ich mich bisher nicht auseinander gesetzt. Nun möchte ich aber, dass die M5Stack Geräte über WLAN kommunizieren. Dafür sind sie schließlich gemacht.

Die UIFlow-IDE bietet dazu unter Blockly nur sehr begrenzte Möglichkeiten. Also wenn es über HTTP gehen soll. MQTT z.B. funktioniert gut. Die HTTP-Blöcke habe ich aber noch nicht verstanden. Micropython hingegen bietet da eine ganze Menge.

Es sind offenbar mehre Schritte erforderlich:

  • Mit dem Netzwerk verbinden
  • Ein Socket installieren
  • Ein Übertragungsprotokoll installieren

Mit einem Netzwerk verbinden.

Meistens verbindet sich ein M5Stack Gerät gleich nach dem Einschalten mit dem Netzwerk, da diese Verbindung für die Programmierung benötigt wird.

<< Ausprobieren, ob auch bei USB-Betrieb, bzw. wenn eine App läuft eine WLAN-Verbindung hergestellt wird. >>

Damit ein eine WLAN-Verbindung eingerichtet oder eine vorhandene erkannt wird ist diese der Software bekannt zu machen. Dazu dient die Library network.

# network Library importieren
>>> import network

# WLAN Interface erzeugen und aktivieren
>>> wlan = network.WLAN(network.STA_IF)
>>> wlan.active(True)

# Mit Wlan verbinden
ssid = 'REPLACE_WITH_YOUR_SSID'
password = 'REPLACE_WITH_YOUR_PASSWORD'
wlan.connect(ssid, password)

# auf bestehende Verbindung prüfen
>>> wlan.isconnected()
True
# Oder auf Verbindung warten und ausgeben
>>> while wlan.isconnected() == False:
>>>   pass
>>> print('Connection successful')
>>> print(station.ifconfig())

# WLAN Daten abfragen (Geräte-IP, Netzwerkmaske, Gateway, DNS-Server)
>>> wlan.ifconfig()
('192.168.5.89', '255.255.255.0', '192.168.5.1', '192.168.5.1')

# Eigene IP-Adresse ermitteln
>>> netzwerk = wlan.ifconfig()
>>> netzwerk
('192.168.5.89', '255.255.255.0', '192.168.5.1', '192.168.5.1')
>>> netzwerk[0]
'192.168.5.89'
# So gehts am Kürzesten
>>> wlan.ifconfig()[0]
'192.168.5.89'

# Die vorhandenen Accesspoint suchen
>>> wlan.scan()
[(b'ESP_9235A1', b'P\x02\x91\x925\xa1', 1, -50, 0, False), (b'Kapest-Fritz', b'\x94\xb9~\x8d<e', 1, -55, 3, False), (b'Kapest-Fritz', b'\x9c\xc7\xa6\x16\xe51', 1, -77, 4, False)]

# WLAN Interface beenden
>>> wlan.active(False)

# MAC Adresse ermitteln
>>> wlan.config('mac')
b'\x94\xb9~\x8b\xb9X'

Nun kennt das Netzwerk meinen M5Stack und dieser das Netzwerk zu dem er jetzt gehört.

In mehrere bekannte Netzwerke automatisch einloggen.

Die Überschrift ist etwas irreführend. Natürlich kann sich der M5Stack immer nur in ein Netzwerk zur Zeit einloggen, aber es gibt vielleicht mehrere räumlich getrennte Netzwerke in die es sich automatisch einloggen soll, so wie wir das vom Handy kennen. Z.B. ins WLAN bei mir zu Hause oder in das des Attraktor, je nachdem, wo ich mich gerade befinde.

# zuerst immer ein WLAN erzeugen sonst geht nichts.
>>> import network
>>> wlan = network.WLAN(network.STA_IF)

# nun kann ich nach WLAN-AP's suchen
>>> wlan.scan()
[(b'ESP_9235A1', b'P\x02\x91\x925\xa1', 1, -50, 0, False), (b'Kapest-Fritz', b'\x94\xb9~\x8d<e', 1, -55, 3, False), (b'Kapest-Fritz', b'\x9c\xc7\xa6\x16\xe51', 1, -77, 4, False)]

# Das sieht nicht sehr übersichtlich aus. Mal sehen ob Micropython das auch so sieht:
>>> wlans = wlan.scan()
>>> wlans
[(b'ESP_9235A1', b'P\x02\x91\x925\xa1', 1, -45, 0, False), (b'Kapest-Fritz', b'\x9c\xc7\xa6\x16\xe51', 1, -77, 4, False)]
>>> type(wlans)
<class 'list'>

# Es wird also eine Liste mit den Daten der AP's in Tupels zurückgegeben.
# Ich benötige nur den String der SSID.

# Der versuch die AP-Tupel in einer Schleife auszulesen scheitert.
>>> wlans
[(b'ESP_9235A1', b'P\x02\x91\x925\xa1', 1, -45, 0, False), (b'Kapest-Fritz', b'\x9c\xc7\xa6\x16\xe51', 1, -77, 4, False)]

# So lassen sich alle erreichbaren AP's auflisten:
>>> for i in wlan.scan():
    print(i[0].decode("utf-8"))
    
ESP_9235A1
Kapest-Fritz
WILLY.TEL-71IU1DHQNW
FRITZ!Box 7560 LY
Brian
WLAN-807195
WLAN-372270
Telekom_FON
o2-WLAN79

# Eine einfache Version für Home und Attraktor sähe dann so aus:
>>> for i in wlan.scan():
    if (i[0].decode("utf-8")) == "Kapest-Fritz":
        print("Zu Hause")
    elif (i[0].decode("utf-8")) == "attraktor":
        print("Attraktor")
WARNING:root:Unexpected echo. Expected b'\r\n', got b''
# Es wird \r\n also eine neue Zeile Schaltung vermisst. Funktioniert ansonsten aber:
Zu Hause

''' Nachdem ich mit .decode("utf-8", errors='ignore') herumgespielt habe aber weiterhin diese Warnung erhalten habe. Habe ich aufgegeben und beschlossen die Warnung zu ignorieren. Seitdem ist sie weg.
'''
# Stefan May gab den Tip es mit "ascii" anstatt "utf-8" zu versuchen. Das klappt auch:
>>> for i in wlan.scan():
    if (i[0].decode("ascii")) == "Kapest-Fritz":
        print("Zu Hause")
    elif (i[0].decode("ascii")) == "attraktor":
        print("Attraktor")
        
Zu Hause

Einen Socket einrichten.

Ein Übertragungsprotokoll installieren

Übersetzung des entsprechenden Artikels von Lukasmaximus89 auf Hackster.io aus dem Englischen mit DeepL.com.

Link zum Orginal: https://www.hackster.io/lukasmaximus89/m5stack-micropython-simple-web-server-20a4c4

Verwenden Sie MicroPython, um Ihren M5Stack mit WiFi oder ein Gerät mit AP zu verbinden und eine einfache Webseite zu erstellen, um einige Funktionen des M5Stack zu steuern.

M5Stack MicroPython Simple Web Server

In diesem Projekt verwendete Dinge

Hardware-Komponenten

M5Stack Gerät: https://www.hackster.io/m5stack/products/esp32-basic-core-iot-development-kit?ref=project-20a4c4

Software-Apps und Online-Dienste

Micropython: https://www.hackster.io/micropython/products/micropython?ref=project-20a4c4

Visual Studio Code: https://www.hackster.io/microsoft/products/vs-code?ref=project-20a4c4

Geschichte

ESP32 ist fast zum De-facto-Standard für die IoT-Entwicklung geworden und es sieht nicht so aus, als würde sich das ändern. Egal, ob wir unseren ESP32-basierten M5Stack für die Automatisierung unseres Hauses, die Überwachung unserer Haustiere oder was auch immer Sie mit Ihrem M5Stack machen möchten, wir könnten eine Art Schnittstelle verwenden, auf die wir sowohl über einen Computer als auch über ein Mobiltelefon zugreifen können.

Der einfachste Weg, dies zu tun, ist das Hosten einer einfachen Webseite auf dem M5Stack mit Schaltflächen und Textfeldern, die die Hardware des M5Stack ansteuern und auch Anzeigen seines Verhaltens anzeigen können. Dabei können wir auch einige Grundlagen über Server, Clients und andere Netzwerkterminologie lernen.

Zu Beginn benötigen wir eine MicroPython-Firmware, die wir auf unser Gerät flashen müssen. Zum Zeitpunkt des Schreibens wird die Uiflow-Version 1.3.2 empfohlen. Flashen Sie Ihr Gerät mit dem Programm M5Burner, das Sie im Download-Bereich der M5Stack-Website finden. Wenn der Brenner aus irgendeinem Grund nicht funktioniert, können Sie immer das esptool aus der Kommandozeile verwenden, um es zu flashen.

Sobald Sie die Firmware geflasht haben, müssen Sie sich entscheiden, welche IDE Sie verwenden möchten, um den M5Stack in MicroPython zu programmieren. Es gibt Uiflow, unsere Online-Plattform für die Programmierung mit Blöcken und MicroPython (in diesem Tutorial werden wir nur die Python-Seite verwenden) oder unser neues Plugin für vscode. Sehen Sie hier, wie Sie es einrichten können.

Sobald Sie sich in der MicroPython-IDE Ihrer Wahl eingerichtet haben, können wir mit dem Schreiben des Programms beginnen, aber zuerst wollen wir versuchen, ein wenig über die Server-Client-Beziehung zu verstehen.

Sie denken bei einem Server vielleicht an einen großen, sperrigen, leistungsstarken Computer, der in einem supergekühlten Rechenzentrum untergebracht ist, aber tatsächlich kann auch ein so winziges Gerät wie Ihr M5Stack ein Server sein, der eine Website hostet. Wenn wir Ihren M5Stack kurz an Ihren Router anschließen, wird ihm eine IP-Adresse zugewiesen. Sie müssen Ihre IP-Adresse kennen, um sie in den Code einzugeben und auch um sie in den Browser auf Ihrem Computer einzugeben, um auf die auf dem M5Stack gehostete Website zuzugreifen. Der M5Stack fungiert als Webserver, der HTTP (Hyper Text Transfer Protocol) verwendet, ein Protokoll zur Weiterleitung von Webseiten, das Port 80 verwendet, um eine Kopie dieser Webseite jedem anderen Gerät (dem Client) zu zeigen, das eine Anfrage an seine IP-Adresse sendet. Um mit dem Gerät zu interagieren, setzen wir einige Schaltflächen auf der Seite im html. Wenn diese Schaltflächen gedrückt werden, wird eine http-Anfrage an das Gerät gesendet, das dann die RGB-Balken ein- oder ausschaltet oder den Lautsprecher piepsen lässt. Werfen wir einen Blick auf den Code. Hier importieren wir alle notwendigen Bibliotheken.

from m5stack import *  
from uiflow import *  
from m5ui import *  
import network ##only import if you want to connect to M5Stack AP
import wifiCfg  
import socket  

Hier setzen wir eine Variable für den Zustand der RGB-LED-Balken.

state = 0

Richten Sie eine Funktion zur Anzeige der Webseite ein.

#function for displaying the html   
def web_page():  
    if state == 0:  
        led_state="Off"  
    else:  
        led_state="On"  
    
 html = """<html><head> <title>M5Stack Web Server</title> <meta name="viewport" content="width=device-width, initial-scale=1">  
 <link rel="icon" href="data:,"> <style>html{font-family: Comic Sans MS; display:inline-block; margin: 0px auto; text-align: center;}  
 h1{color: #0F3376; padding: 2vh;}p{font-size: 1.5rem;}.button{display: inline-block; background-color: #0000FF; border: none;   
 border-radius: 4px; color: white; padding: 16px 40px; text-decoration: none; font-size: 40px; margin: 2px; cursor: pointer;}  
 .button2{background-color: #ff0000;}.button3{background-color: #ff00ff</style></head><body> <h1>M5Stack Web Server</h1>   
 <p>state: <strong>""" + str(state) + """</strong></p><p><a href="/?led=on"><button class="button">ON</button></a></p>  
 <p><a href="/?btn=on"><button class="button button3">Speaker</button></a></p>  
 <p><a href="/?led=off"><button class="button button2">OFF</button></a></p>  
 </html>"""  
 return html  

Weisen Sie die ifconfig-Funktion einer Variablen zu, damit wir unsere M5Stacks IP-Adresse auf dem Bildschirm ausgeben können.

ip = wifiCfg.wlan_sta.ifconfig()  

Erstellen Sie einige Beschriftungen, um einige Statusmeldungen auf dem M5Stack-Bildschirm anzuzeigen.

label1 = M5TextBox(0, 0, "Text", lcd.FONT_Default,0xFFFFFF, rotate=0)  
label2 = M5TextBox(0, 12, "Text", lcd.FONT_Default,0xFFFFFF, rotate=0)  
label3 = M5TextBox(0, 24, "Text", lcd.FONT_Default,0xFFFFFF, rotate=0)  
label4 = M5TextBox(0, 50, "Text", lcd.FONT_Default,0xFFFFFF, rotate=0)  
label5 = M5TextBox(120, 200, "Text", lcd.FONT_Default,0xFFFFFF, rotate=0)  

Geben Sie Ihr WiFi-Netzwerk und Passwort ein und richten Sie die Steckdose ein. HINWEIS: Lassen Sie die Zeichenfolge „Geben Sie Ihre IP hier ein, sobald Sie sie kennen“ leer, führen Sie das Programm einmal aus und geben Sie dann, sobald Sie die IP-Adresse auf dem Bildschirm Ihres M5Stack sehen, diese in dieses Feld ein.

response = None  
wifiCfg.doConnect('yournetwork', 'yourpassword')  
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  
s.bind(('enter your IP here once you know it', 80))  
s.listen(5)  

Wenn Sie Ihren M5Stack nicht mit dem Internet verbinden wollen und lieber

mit dem AP des Geräts verbinden möchten, entfernen Sie die Zeile wifiCfg und ersetzen Sie sie durch

ap = network.WLAN(network.AP_IF)
ap.active(True)
ap.config(essid='ESP32')
ap.config(authmode=3, password='123456789') 

Bei Verbindung IP-Adresse anzeigen.

if wifiCfg.wlan_sta.isconnected():  
    label1.setText('wifi connected')  
    label2.setText('Your IP Address is: ' + str(ip[0]))  
else:  
    label1.setText('wifi not connected')  
    wait_ms(2)  

Hauptschleife, richten Sie die http-Anfragen und Statusmeldungen ein.

while True:  
    conn, addr = s.accept()  
    request = conn.recv(1024)  
    request = str(request)  
    label4.setText('Content = %s' % request)  
    label3.setText('Got a connection from %s' % str(addr))  
    led_on = request.find('/?led=on')  
    led_off = request.find('/?led=off')  
    btn_press = request.find('/?btn=on')  

Prüfen Sie, ob die http-Anfrage empfangen wurde, wenn ja, schalten Sie die LED oder den Lautsprecher ein/aus.

    if led_on == 6:  
        state = 1  
        label5.setText('LED ON')  
        rgb.setColorAll(0xFF0000)  
    if led_off == 6:  
        state = 0  
        label5.setText('LED OFF')  
        rgb.setColorAll(0x000000)  
    if btn_press == 6:  
        speaker.tone(400,200)  
    response = web_page()  
    conn.send('HTTP/1.1 200 OK\n')  
    conn.send('Content-Type: text/html\n')  
    conn.send('Connection: close\n\n')  
    conn.sendall(response)  
    conn.close()      

Und das ist alles, was es zu tun gibt. Sie können dieses Tutorial auch mit demjenigen kombinieren, das ich zuvor für MIT APP Inventor geschrieben habe, um Ihren M5Stack über eine App Inventor-App zu steuern, die auf http-Anfragen antwortet. Ich hoffe, dieses Tutorial hat Ihnen gefallen, bleiben Sie dran für mehr.

Code

M5Stack Webserver

MicroPython
Code, um den Webserver einzurichten, die IP des Host-Geräts anzuzeigen und einige Statusmeldungen auf dem M5Stack zu drucken

from m5stack import *
from m5ui import *
from uiflow import *
import network

try:
    import usocket as socket
except:
    import socket

def web_page():
  html = """<html><head> <title>M5Stack Web Server</title> <meta name        ="viewport" content="width=device-width, initial-scale=1">
  <link rel="icon" href="data:,"> <style>html{font-family: Comic Sans MS;    display:inline-block; margin: 0px auto; text-align: center;}
  h1{color: #0F3376; padding: 2vh;}p{font-size: 1.5rem;}.button{display:     inline-block; background-color: #0000FF; border: none; 
  border-radius: 4px; color: white; padding: 16px 40px; text-decoration:     none; font-size: 40px; margin: 2px; cursor: pointer;}
  .button2{background-color: #ff0000;}.button3{background-color: #ff00ff     </style></head><body> <h1>M5Stack Web Server</h1> 
  <p>state: <strong>""" + str(state) + """</strong></p><p><a href="/?led     =on"><button class="button">ON</button></a></p>
  <p>Button State: <strong>""" + str(btnstate) + """</strong></p><p><a href   ="/?btn=on"><button class="button button3">Speaker</button></a></p>
  <p><a href="/?led=off"><button class="button button2">OFF</button></a></p   >
  </html>"""
  return html


ap = network.WLAN(network.AP_IF)
ap.active(True)
ap.config(essid='M5Stack')
ap.config(authmode=3, password='123456789')
lcd.clear()

response = None
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(('192.168.4.1',80))
s.listen(5)

while True:
    conn, addr = s.accept()
    request = conn.recv(1024)
    request = str(request)
    print ('Content = %s' % request)
    lcd.print('Content = %s' % request,0,50,0xffffff)
    if ap.isconnected() == True:
        lcd.print('connected',0,0,0xffffff)
    else:
        lcd.print('not connected',0,0,0xffffff)
    response = web_page()
    conn.send('HTTP/1.1 200 OK\n')
    conn.send('Content-Type: text/html\n')
    conn.send('Connection: close\n\n')
    conn.sendall(response)
    conn.close()

M5Stack Acess Point Webserver

MicroPython
Richten Sie Ihren M5Stack als Zugangspunkt ein und erlauben Sie Geräten den Zugriff auf eine darauf gehostete Webseite

from m5stack import *
from m5ui import *
from uiflow import *
import network

try:
    import usocket as socket
except:
    import socket

def web_page():
  html = """<html><head> <title>M5Stack Web Server</title> <meta name        ="viewport" content="width=device-width, initial-scale=1">
  <link rel="icon" href="data:,"> <style>html{font-family: Comic Sans MS;    display:inline-block; margin: 0px auto; text-align: center;}
  h1{color: #0F3376; padding: 2vh;}p{font-size: 1.5rem;}.button{display:     inline-block; background-color: #0000FF; border: none; 
  border-radius: 4px; color: white; padding: 16px 40px; text-decoration:     none; font-size: 40px; margin: 2px; cursor: pointer;}
  .button2{background-color: #ff0000;}.button3{background-color: #ff00ff     </style></head><body> <h1>M5Stack Web Server</h1> 
  <p>state: <strong>""" + str(state) + """</strong></p><p><a href="/?led     =on"><button class="button">ON</button></a></p>
  <p>Button State: <strong>""" + str(btnstate) + """</strong></p><p><a href   ="/?btn=on"><button class="button button3">Speaker</button></a></p>
  <p><a href="/?led=off"><button class="button button2">OFF</button></a></p   >
  </html>"""
  return html


ap = network.WLAN(network.AP_IF)
ap.active(True)
ap.config(essid='M5Stack')
ap.config(authmode=3, password='123456789')
lcd.clear()

response = None
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(('192.168.4.1',80))
s.listen(5)

while True:
    conn, addr = s.accept()
    request = conn.recv(1024)
    request = str(request)
    print ('Content = %s' % request)
    lcd.print('Content = %s' % request,0,50,0xffffff)
    if ap.isconnected() == True:
        lcd.print('connected',0,0,0xffffff)
    else:
        lcd.print('not connected',0,0,0xffffff)
    response = web_page()
    conn.send('HTTP/1.1 200 OK\n')
    conn.send('Content-Type: text/html\n')
    conn.send('Connection: close\n\n')
    conn.sendall(response)
    conn.close()