TigerJython | xx für Gymnasien |
Deutsch English |
Auf dem zusätzlich eingebauten LinkUp (mit dem ESP32 als Coprozessor) kann ein Webserver und sogar ein eigener Accesspoint eingerichtet werden. Loggt sich der LinkUp über das WLAN bei einem Accesspoint ein, der mit dem Internet verbunden ist, wird der micro:bit zu einem vernetzen IoT-Gerät, das beispielsweise Messdaten in einer Cloud speichern oder von einem Smartphone Steuerbefehle erhalten kann.
Die Kommunikation zwischen dem micro:bit und dem ESP32 erfolgt mit I2C, wobei der ESP32 sich wie ein I2C-Slave verhält. Die notwendigen Funktionen werden über das Moduls linkup zur Verfügung gestellt. |
Für die WLAN-Kommunikation gibt es grundsätzliche zwei Verbindungsmöglichkeiten:
Verwendung eines vorhandenen Accesspoints
Der mbRobot und die anderen Geräte (Smartphone, PC) loggen sich auf dem gleichen Accesspoint (mit SSID, Password) ein
Der mbRobot als Accesspoint
Auf dem mbRobot wird eine Accesspoint mit eigner SSID (und eventuell einem Passwort) gestartet und die anderen Geräte loggen sich über WLAN auf diesem Accesspoint ein.
Beispiel 1: Webserver einrichten und eine statische Webseite zur Verfügung stellen
Schritt 1: Webseite hochladen
Mit der Ausführung des untenstehenden Programms wird der HTML-Inhalt einer einfachen Webseite
auf den LinkUp hochgeladen und dort gespeichert.
# SaveHTMLWeb1.py from linkup import * html = """<!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width, initial-scale=1"> </head> <body> <h2>Welcome to the mbRobot</h2> <p>My first homepage</p> </body> </html> """ print("Saving HTML...") saveHTML(html) print("Done") |
Schritt 2: Webserver starten
Je nachdem, ob man die Verbindung über einen bestehenden Accesspoint oder einen Accesspoint auf dem Roboter erstellt, wird auf dem micro:bit das Programm WebServer1.py oder WebServer1a.py ausgeführt. Die beiden Programme unterscheiden sich nur in zwei Zeilen:
In WebServer1.py muss man die SSID und Passwort des bestehenden Accesspoint im Programm angeben. Damit man mit einem Smartphone- bzw. PC-Browser zugreifen kann, muss man die IP Adresse, die der mbRobot vom Accesspoint erhält, kennen. Diese wird von connectAP() zurückgegeben und auf dem LED-Display mit Scrolltext ausgeschrieben.
In WebServer2.py erzeugt man mit dem Befehl createAP() einen Accesspoint mit der SSID mbRobot und einem leeren Passwort. Für eine Verbindung mit dem Webserver, muss sich ein Gerät auf dieser SSID einloggen und dann im Browser die fixe URL 192.168.4.1 verwenden.
Nach dem Start des Webservers ist dieser bereit, auf Port 80 HTTP-Requests von irgendeinem Client zu empfangen. Jeder Requests wird als eine Ereignis aufgefasst, wobei das System automatisch die Callbackfunktion onRequest() aufruft, welche Informationen des Requests enthält (die IP Adresse des Clients, die eingegebene URL-Ressource (filename) und eventuelle URL-Parameter).
Da in diesen Programmen onRequest() ohne Rückgabewerte zurückkehrt, wird lediglich die vorher gespeicherte HTML-Seite an den Client zurückgesendet.
Verbindung über bestehenden Accesspoint | Accesspoint auf dem mbRobot | |
# WebServer1.py from linkup import * from mbrobot import * def onRequest(clientIP, filename, params): return ipAddress = connectAP(ssid="xx", password="yy") display.scroll(ipAddress, wait = False) startHTTPServer(onRequest) |
# WebServer1a.py from linkup import * from mbrobot import * def onRequest(clientIP, filename, params): return createAP(ssid="mbRobot", password="") startHTTPServer(onRequest) |
|
Schritt 3: Webseite anzeigen |
|
Erklärungen zum Programmcode:
viewport: Die Webseite wird an die Device-Breite angepasst. Damit wird sie auch auf einem Smartphone richtig angezeigt | |
def onRequest(): Callbackfunktion. Definiert, wie der mbRobot auf die HTTP-Requests reagieren soll. Hier wird nur eine statische Webseite an den Client zurück gesendet | |
createAP(): Erzeugt einen Accesspoint auf dem ESP32 Microkontroller | |
startHTTPServer: Startet den Webserver. Der Aufruf ist blockierend, d.h. der LinkUp muss für einen neuen Programm-Lauf resettet (oder aus-/eingeschaltet) werden |
Beispiel 2: Interaktive Webseite
Die auf dem mbRobot Webserver bereitgestellte Website enthält zwei Links. Durch Anklicken dieser Links werden die an den Webserver gesendeten Informationen zur Steuerung des Roboters verwendet. Der eingehende GET-Request triggert die Callback-Funktion onRequest(clientIP, filename, params) und der Parameter filename enthält den Parameter href des HTML <a>-Tags. Je nachdem, welcher Link gedrückt wurde, werden die Melodien JUMP_UP oder JUMP_DOWN abgespielt
Mit dem Programm SaveHTMLWeb2.py wird der HTML-Code hochgeladen.
# SaveHTMLWeb2.py from linkup import * html = """<!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width, initial-scale=1"> </head> <body> <h2>Welcome to the mbRobot</H2> <p><a href="jump_up">Play JUMP_UP </a></p> <p><a href="jump_down">Play JUMP_DOWN</a></p> </body> </html> """ print("Saving HTML...") saveHTML(html) |
WebServer2.py startet den Webserver:
# WebServer2.py from linkup import * from mbrobot import * from music import * def onRequest(clientIP, filename, params): if filename == "/jump_up": play(JUMP_UP) elif filename == "/jump_down": play(JUMP_DOWN) ipAddress = connectAP(ssid = "xxx", password = "yyy") display.scroll(ipAddress, wait = False) startHTTPServer(onRequest) |
|
Erklärungen zum Programmcode:
filename == "/jump_up": Der Parameter filename erhält den Wert jump_up, wenn der Benutzer auf den Link JUMP_UP klickt |
Beispiel 3: Mit einer interaktiven Webseite die LEDs des mbRobot ferngesteuert ein- und ausschalten
Wie im vorherigen Beispiel gezeigt, wird die Callback-Funktion onRequest (clientIP, filename, params) durch einen eingehende GET-Request ausgelöst. Anstelle eines HTML <a>-Tags werden hier Buttons verwendet, die eine gefälligere Darstellung ermöglichen. Der Parameter filename enthält die Werte "on" oder "off", je nachdem, welcher Button geklickt wurde.
So wie in den vorhergehenden Beispielen muss zuerst der HTML-Code auf dem Server gespeichert werden.
# SaveHTMLWeb3.py from linkup import * html = """<!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width, initial-scale=1"> </head> <body> <h2>Welcome to the mbRobot</H2> <button style="font-size:22px; height:50px;width:130px" onclick="window.location.href='on'">Light ON</button> <button style="font-size:22px; height:50px;width:130px" onclick="window.location.href='off'">Light OFF</button> </body> </html> """ print("Saving HTML...") saveHTML(html) print("Done") |
|
WebServer3.py startet den Webserver:
# WebServer3.py from linkup import * from mbrobot import * def onRequest(clientIP, filename, params): if filename == "/on": ledLeft.write_digital(1) ledRight.write_digital(1) elif filename == "/off": ledLeft.write_digital(0) ledRight.write_digital(0) print("Waiting for LinkUp...") ipAddress = connectAP(ssid = "xx", password = "yy") display.scroll(ipAddress, wait = False) startHTTPServer(onRequest) |
|
Erklärungen zum Programmcode:
if filename == "/on": Wenn der Parameter filename "/on" ist, werden beide LEDs eingeschaltet |
Beispiel 4: Roboter mit Smartphone steuern
Unter der Verwendung des Webservers und Accesspoints auf dem mbRobot ist es einfach, eine Fernsteuerung zu realisieren, ohne eine spezielle Smartphone-App zu installieren. Dazu wird auf dem mbRobot wird zuerst ein Accesspoint und dann ein Webserver gestartet den man mit der URL 191.168.4.1 erreicht Die Webseite zeigt 5 Buttons: forward, backward, left, right und stop zur Steuerung des Roboters.
Im HTML-Code wird ein Formular mit Submit-Buttons und eine Tabelle für die Positionierung der Buttons verwendet. Die name und value-Werte gelangen als HTTP-Request-Parameter an die Callbackfunktion onRequest(), und zwar in Form eines Dictionary {key:value,...}.
Um einen Feedback an den Benutzer zu senden, enthält die HTML-Seite einen Format-Parameter %s (bei "Current state:") Dieser soll vom Webserver durch einem String ersetzt werden. Um dies zu erreichen, muss der Callback onRequest() eine Liste mit allen Format-Parameter zurück geben.
# SaveHTMLWeb4.py (RemoteRover) from linkup import * html = """<!DOCTYPE html> <html> <head> <title>MicroBit Rover</title> <meta name="viewport" content="width=device-width, initial-scale=1"> </head> <body> <h1>MicroBit Rover</h1> <form method="get"> <table> <tr> <td></td> <td><input type="submit" style="font-size:22px; height:50px; width:110px" name="btn" value="Forward"/></td> <td></td> </tr> <tr> <td><input type="submit" style="font-size:22px; height:50px; width:110px" name="btn" value="Left"/></td> <td><input type="submit" style="font-size:22px; height:50px; width:110px" name="btn" value="Stop"/></td> <td><input type="submit" style="font-size:22px; height:50px; width:110px" name="btn" value="Right"/></td> </tr> <tr> <td></td> <td><input type="submit" style="font-size:22px; height:50px; width:110px" name="btn" value="Back"/></td> <td></td> </tr> </table> </form><br> Current state: %s<br> </body> </html> """ print("Saving HTML...") saveHTML(html) print("Done") |
Das HTML-Formularelement enthält Eingabefelder mit Name und Wert. Beim Absenden des Formulars werden die Informationen als ?name=value-Paare in die URL gepackt und auf dem Webserver der Callback onRequest (clientIP, filename, params) aufgerufen. Die Informationen können von params als Dictionary key-value-Paare abgeholt werden.
Das Programm verwendet die Zustandsprogrammierung. Nach Empfang eines Befehls wird der Roboter in einen bestimmten Bewegungszustand versetzt, der so lange erhalten bleibt, bis er mit einem neuen Befehl geändert wird.
# WebServerWeb4.py from linkup import * from mbrobot import * def onRequest(clientIP, filename, params): if 'btn' in params: state = params['btn'] if state == 'Left': leftArc(0.1) elif state == 'Right': rightArc(0.1) elif state == 'Forward': forward() elif state == 'Back': backward() elif state == 'Stop': stop() else: state = 'Stop' display.show(state[0]) return [state] stop() createAP(ssid = "mbRobot", password = "") startHTTPServer(onRequest) |
|
Erklärungen zum Programmcode:
display.show(state[0]) : Der erste Buchstabe des Zustandes wird auf dem LED-Display angezeigt | |
return [state] : Der Rückgabewert ist eine Liste mit Werten, die als Formatparameter verwendet werden (hier nur ein Wert bei bei Current State: %s). |