Access Point
läuft auf Pico W
unter CircuitPython !!
Bildbox 1 (klick hier)
Hardware / Software
- Raspberry Pi Pico W
- Neopixelring (12 LED)
- Micro USB Kabel
- Firmware CircuitPython
- Thonny IDE
Access Point
läuft auf Pico W
unter CircuitPython !!
Bildbox 1 (klick hier)
- Neopixelring (12 LED)
- Micro USB Kabel
- Firmware CircuitPython
- Thonny IDE
Nach der
Einrichtung des Pico W mit der Firmware CircuitPython
kommt hier eine praktische Anwendung. Seit einiger Zeit schon suche ich im Netz nach einem Beispiel für einen
Pico W Access Point, der unter CircuitPython läuft. Das einzige was ich bisher gefunden habe,
ist ein HTTP-Server bei Adafruit, bei dem eine Kuh ein Display im Bauch hat. Alle anderen Vorschläge landeten
letztlich immer wieder bei MicroPython. Also hab ich die Kuh mal vom 'Partydisplay' befreit, die html-Seite bearbeitet
und eine eigene Möglichkeit zum Steuern des Neopixelrings ergänzt. Das hat sehr gut funktioniert.
Nun wollte ich aber meine Anwendung unabhängig vom heimischen WLAN-Netz laufen lassen, also sollte es ein
Access Point werden. Der braucht keine Verbindung zum Internet, was man dem Pico auch nicht abverlangen muss. Aber
das Handy kann sich mit dem Access Point verbinden und über die Button im Browserfenster lassen sich Funktionen
steuern (hier als Beispiel die interne LED und der Neopixelring). Darüber hinaus wird die Temperatur vom internen
Sensor angezeigt.
Was muss man wissen, bevor es losgeht?
Unter CircuitPython wird der WLAN-Chip automatisch beim Anstecken der USB-Verbindung gestartet und er befindet sich im
s.g. 'station mode'. Da der Access Point (AP) aber 'access mode' erfordert,
muss 'station mode' zunächst angehalten werden, bevor der AP gestarted wird. Im unteren Fenster sieht man, wie der
Access Point mit wenigen Programmzeilen seine 'Arbeit' aufnimmt.
import wifi
# station mode stoppen
wifi.radio.stop_station()
# ssid und password definieren
ap_ssid = "pico_w_ap"
ap_password = "raspberry"
# AP mit ssid und password starten
wifi.radio.start_ap(ssid=ap_ssid, password=ap_password)
# MAC-Address und IP-Address definieren
ap_bssid = wifi.radio.mac_address_ap
print(ap_bssid)
ipv4 = wifi.radio.ipv4_address_ap
print(ipv4)
Im Text erkennt man auch, dass die 'ssid' und das 'password' festgelegt werden. Die sind vom Nutzer frei wählbar.
Wichtig ist die Ermittlung der 'IP-Address', damit sie für die Eingabe im Handybrowser später bekannt ist.
Der AP arbeitet somit schon mal und sollte in den WLAN-Einstellungen des Handy angezeigt werden. Bei Eingabe des Passwortes
verbindet sich das Smartphone mit dem AP, auf dem aber noch keine Anwendung läuft.
Los geht's
Hier noch einmal der Quellcode bis zu dieser Stelle mit allen importierten Bibliotheken (Zeilen 1 -19), der ausgeschalteten Onboard-LED
(Zeilen 21 - 24) und dem Aufruf des internen Temperatursensors (Zeile 27) sowie dem Start des AP. In Zeile 12 wird das Programm 'effekte.py'
importiert, welches für den Neopixelring später genutzt wird.
1 import os
2 import time
3 import ipaddress
4 import wifi
5 import socketpool
6 import busio
7 import board
8 import microcontroller
9 import displayio
10 import terminalio
11 import neopixel
12 import effekte
13 from rainbowio import colorwheel
14 from digitalio import DigitalInOut, Direction
15 from adafruit_httpserver.server import HTTPServer
16 from adafruit_httpserver.request import HTTPRequest
17 from adafruit_httpserver.response import HTTPResponse
18 from adafruit_httpserver.methods import HTTPMethod
19 from adafruit_httpserver.mime_type import MIMEType
20
21 # onboard LED setup
22 led = DigitalInOut(board.LED)
23 led.direction = Direction.OUTPUT
24 led.value = False
25
26 # scan for temp sensor
27 temp = str(int((microcontroller.cpu.temperature + 0.5) * 10) / 10)
28
29 # this STA becomes a STA+SoftAP
30 wifi.radio.stop_station()
31 ap_ssid = "pico_w_ap"
32 ap_password = "raspberry"
33 wifi.radio.start_ap(ssid=ap_ssid, password=ap_password)
34 ap_bssid = wifi.radio.mac_address_ap
35 ipv4 = wifi.radio.ipv4_address_ap
36
37 pool = socketpool.SocketPool(wifi.radio)
38 server = HTTPServer(pool)
39
In den Zeilen 40 bis 72 wird nun die Funktion, welche die Webseite im Browser darstellt definiert. Da es sich hier um html-Code innerhalb
dieser Website handelt, müssen Sie diesen Teil selbst per 'copy&paste' in die Thonny IDE ab Zeile 40 einsetzen.
Pico W - LED steuern:
Neopixelring steuern:
"""
return html
Danach werden die Funktion, welche die Anfrage an die Website stellt ( Zeilen 73 -79) und die Funktion,
welche prüft ob ein Button auf der Website gedrückt wurde (Zeilen 81 - 105), definiert. Wurde ein Button
gedrückt, so wird eine Aktion ausgelöst und die Website aktualisiert.
73 # route default static IP
74 @server.route("/")
75 def base(request: HTTPRequest): # pylint: disable=unused-argument
76 # serve the HTML f string
77 # with content type text/html
78 with HTTPResponse(request, content_type=MIMEType.TYPE_HTML) as response:
79 response.send(f"{webpage()}")
80
81 # if a button is pressed on the site
82 @server.route("/", method=HTTPMethod.POST)
83 def buttonpress(request: HTTPRequest):
84 # get the raw text
85 raw_text = request.raw_request.decode("utf8")
86 print(raw_text)
87 # if the led on button was pressed
88 if "LED_ON" in raw_text:
89 # turn on the onboard LED
90 led.value = True
91 # if the led off button was pressed
92 if "LED_OFF" in raw_text:
93 # turn the onboard LED off
94 led.value = False
95 # if the pixel 1 button was pressed
96 if "PIXEL_1" in raw_text:
97 # turn on the Neopixeleffekt 1
98 effekte.effekt_1()
99 # if the pixel 2 button was pressed
100 if "PIXEL_2" in raw_text:
101 # turn on the Neopixeleffekt 2
102 effekte.effekt_2()
103 # reload site
104 with HTTPResponse(request, content_type=MIMEType.TYPE_HTML) as response:
105 response.send(f"{webpage()}")
106
Erklärung der Aktionen:
* 'led.value = True' bzw. 'led.value = False' : schaltet die interne LED an bzw. aus.
* 'effekte.effekt_1()' und 'effekte.effekt_2()' : schaltet den Neopixelring mit dem jeweiligen Effekt.
Wie bereits erwähnt, wird in Zeile 12 die Datei 'effekte.py' importiert, welche
durch die Zuweisung der Variable 'main' nicht selbständig ausgeführt wird. Erst wenn die Funktionen
'effekt_1()' bzw. 'effekt_2()' vom Hauptprogramm aufgerufen
werden. Dieses Beispiel zeigt anschaulich, wie man Funktionen in andere Programme (Module) auslagern kann und so das Hauptprogramm
übersichtlich hält. Es können dort auch jederzeit andere Effekte eingefügt werden.
Die Datei 'effekte.py' können Sie
hier bei mir downloaden
oder mit Hilfe der Ausführungen zum
Experiment mit dem Neopixelring
selbst erstellen.
Im verbleibenden Programmcode lauscht der AP auf eingehende Anforderungen auf dem Port 80. Außerdem wird alle
30 Sekunden der Variable 'temp' die Temperatur des internen Sensors zugewiesen. Kopieren Sie diesen Code noch in Ihr Projekt, bevor
Sie den AP testen.
107 print("starting server..")
108 # startup the server
109 try:
110 server.start(str(wifi.radio.ipv4_address_ap))
111 print("Listening on http://%s:80" % wifi.radio.ipv4_address_ap)
112 # if the server fails to begin, restart the pico w
113 except OSError:
114 time.sleep(5)
115 print("restarting..")
116 microcontroller.reset()
117 ping_address = ipaddress.ip_address("8.8.4.4")
118
119 clock = time.monotonic()
120
121 while True:
122 try:
123 # every 30 seconds update temp reading
124 if (clock + 30) < time.monotonic():
125 clock = time.monotonic()
126 temp = str(int((microcontroller.cpu.temperature + 0.5) * 10) / 10)
127
128 # poll the server for incoming/outgoing requests
129 server.poll()
130 # pylint: disable=broad-except
131 except Exception as e:
132 print(e)
133 continue
Nachdem der AP gestartet wurde, wählen Sie ihn in den WLAN-Einstellungen Ihres Smartphones aus und verbinden sich mit dem von
Ihnen vergebenen Passwort. Danach öffnen Sie einen Browser und geben die Addresse: http://192.168.4.1:80 ein.
Jetzt sollte die Website wie im Bild oben zu sehen sein. Wenn sich jetzt die interne LED und der Neopixelring schalten lassen, sind Sie
erfolgreich am Ziel. Glückwunsch.
Unter dem Strich bleibt allerdings die Frage: Was kann man sinnvoll damit anfangen? Eine interne LED an- und ausschalten verändert nicht gerade
die Welt. Deshalb hab ich mich einmal umgeschaut und bei dem englischen Hersteller 'sb-components' folgendes entdeckt:
Es handelt sich um speziell für den Pico entwickelte Relaisboards (klick auf das Bild), die Spannungen bis 230V bei max. 7A schalten können.
Dabei ist der Pico über Optokoppler getrennt, so dass durch die 230V keine Gefahr für den Microkontroller besteht. Das Relaisboard mit einem
Relais wird mit dem GPIO 6 geschaltet. Ein einfaches Schaltungsbeispiel zum Test wäre das folgende:
1 import time
2 import board
3 from digitalio import DigitalInOut, Direction
4
5 # Relaissetup as GP6 for output
6 relais1 = DigitalInOut(board.GP6)
7 relais1.direction = Direction.OUTPUT
8 relais1.value = False
9
10 while True:
11 # relaistest
12 relais1.value = True # Turn on Relay
13 time.sleep(1)
14 relais1.value = False # Turn off Relay
15 time.sleep(1)
Jetzt kommen mir sofort einige Ideen, wie man z.B. Lampen, Lüfter oder andere Geräte im Garten, der Garage u.s.w. vom
Smartphone damit schalten kann.
Weitere verwandte Projekte:
import wifi # station mode stoppen wifi.radio.stop_station() # ssid und password definieren ap_ssid = "pico_w_ap" ap_password = "raspberry" # AP mit ssid und password starten wifi.radio.start_ap(ssid=ap_ssid, password=ap_password) # MAC-Address und IP-Address definieren ap_bssid = wifi.radio.mac_address_ap print(ap_bssid) ipv4 = wifi.radio.ipv4_address_ap print(ipv4)
1 import os 2 import time 3 import ipaddress 4 import wifi 5 import socketpool 6 import busio 7 import board 8 import microcontroller 9 import displayio 10 import terminalio 11 import neopixel 12 import effekte 13 from rainbowio import colorwheel 14 from digitalio import DigitalInOut, Direction 15 from adafruit_httpserver.server import HTTPServer 16 from adafruit_httpserver.request import HTTPRequest 17 from adafruit_httpserver.response import HTTPResponse 18 from adafruit_httpserver.methods import HTTPMethod 19 from adafruit_httpserver.mime_type import MIMEType 20 21 # onboard LED setup 22 led = DigitalInOut(board.LED) 23 led.direction = Direction.OUTPUT 24 led.value = False 25 26 # scan for temp sensor 27 temp = str(int((microcontroller.cpu.temperature + 0.5) * 10) / 10) 28 29 # this STA becomes a STA+SoftAP 30 wifi.radio.stop_station() 31 ap_ssid = "pico_w_ap" 32 ap_password = "raspberry" 33 wifi.radio.start_ap(ssid=ap_ssid, password=ap_password) 34 ap_bssid = wifi.radio.mac_address_ap 35 ipv4 = wifi.radio.ipv4_address_ap 36 37 pool = socketpool.SocketPool(wifi.radio) 38 server = HTTPServer(pool) 39
Pico W - LED steuern:
Neopixelring steuern:
""" return html73 # route default static IP 74 @server.route("/") 75 def base(request: HTTPRequest): # pylint: disable=unused-argument 76 # serve the HTML f string 77 # with content type text/html 78 with HTTPResponse(request, content_type=MIMEType.TYPE_HTML) as response: 79 response.send(f"{webpage()}") 80 81 # if a button is pressed on the site 82 @server.route("/", method=HTTPMethod.POST) 83 def buttonpress(request: HTTPRequest): 84 # get the raw text 85 raw_text = request.raw_request.decode("utf8") 86 print(raw_text) 87 # if the led on button was pressed 88 if "LED_ON" in raw_text: 89 # turn on the onboard LED 90 led.value = True 91 # if the led off button was pressed 92 if "LED_OFF" in raw_text: 93 # turn the onboard LED off 94 led.value = False 95 # if the pixel 1 button was pressed 96 if "PIXEL_1" in raw_text: 97 # turn on the Neopixeleffekt 1 98 effekte.effekt_1() 99 # if the pixel 2 button was pressed 100 if "PIXEL_2" in raw_text: 101 # turn on the Neopixeleffekt 2 102 effekte.effekt_2() 103 # reload site 104 with HTTPResponse(request, content_type=MIMEType.TYPE_HTML) as response: 105 response.send(f"{webpage()}") 106
* 'led.value = True' bzw. 'led.value = False' : schaltet die interne LED an bzw. aus.
* 'effekte.effekt_1()' und 'effekte.effekt_2()' : schaltet den Neopixelring mit dem jeweiligen Effekt.
Wie bereits erwähnt, wird in Zeile 12 die Datei 'effekte.py' importiert, welche durch die Zuweisung der Variable 'main' nicht selbständig ausgeführt wird. Erst wenn die Funktionen 'effekt_1()' bzw. 'effekt_2()' vom Hauptprogramm aufgerufen werden. Dieses Beispiel zeigt anschaulich, wie man Funktionen in andere Programme (Module) auslagern kann und so das Hauptprogramm übersichtlich hält. Es können dort auch jederzeit andere Effekte eingefügt werden.
Die Datei 'effekte.py' können Sie hier bei mir downloaden oder mit Hilfe der Ausführungen zum Experiment mit dem Neopixelring selbst erstellen.
Im verbleibenden Programmcode lauscht der AP auf eingehende Anforderungen auf dem Port 80. Außerdem wird alle 30 Sekunden der Variable 'temp' die Temperatur des internen Sensors zugewiesen. Kopieren Sie diesen Code noch in Ihr Projekt, bevor Sie den AP testen.
107 print("starting server..") 108 # startup the server 109 try: 110 server.start(str(wifi.radio.ipv4_address_ap)) 111 print("Listening on http://%s:80" % wifi.radio.ipv4_address_ap) 112 # if the server fails to begin, restart the pico w 113 except OSError: 114 time.sleep(5) 115 print("restarting..") 116 microcontroller.reset() 117 ping_address = ipaddress.ip_address("8.8.4.4") 118 119 clock = time.monotonic() 120 121 while True: 122 try: 123 # every 30 seconds update temp reading 124 if (clock + 30) < time.monotonic(): 125 clock = time.monotonic() 126 temp = str(int((microcontroller.cpu.temperature + 0.5) * 10) / 10) 127 128 # poll the server for incoming/outgoing requests 129 server.poll() 130 # pylint: disable=broad-except 131 except Exception as e: 132 print(e) 133 continue
Unter dem Strich bleibt allerdings die Frage: Was kann man sinnvoll damit anfangen? Eine interne LED an- und ausschalten verändert nicht gerade die Welt. Deshalb hab ich mich einmal umgeschaut und bei dem englischen Hersteller 'sb-components' folgendes entdeckt:
Es handelt sich um speziell für den Pico entwickelte Relaisboards (klick auf das Bild), die Spannungen bis 230V bei max. 7A schalten können. Dabei ist der Pico über Optokoppler getrennt, so dass durch die 230V keine Gefahr für den Microkontroller besteht. Das Relaisboard mit einem Relais wird mit dem GPIO 6 geschaltet. Ein einfaches Schaltungsbeispiel zum Test wäre das folgende:
1 import time
2 import board
3 from digitalio import DigitalInOut, Direction
4
5 # Relaissetup as GP6 for output
6 relais1 = DigitalInOut(board.GP6)
7 relais1.direction = Direction.OUTPUT
8 relais1.value = False
9
10 while True:
11 # relaistest
12 relais1.value = True # Turn on Relay
13 time.sleep(1)
14 relais1.value = False # Turn off Relay
15 time.sleep(1)
Jetzt kommen mir sofort einige Ideen, wie man z.B. Lampen, Lüfter oder andere Geräte im Garten, der Garage u.s.w. vom
Smartphone damit schalten kann.
Weitere verwandte Projekte:
1 import time 2 import board 3 from digitalio import DigitalInOut, Direction 4 5 # Relaissetup as GP6 for output 6 relais1 = DigitalInOut(board.GP6) 7 relais1.direction = Direction.OUTPUT 8 relais1.value = False 9 10 while True: 11 # relaistest 12 relais1.value = True # Turn on Relay 13 time.sleep(1) 14 relais1.value = False # Turn off Relay 15 time.sleep(1)
Weitere verwandte Projekte:
Viel Spass und Erfolg beim Ausprobieren. Wenn Ihnen diese Anleitung gefallen hat, tragen Sie hier bitte einen Kommentar ein.
Zurück