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

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.





  

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:

  • Pico W RTC Uhr mit Pico-LCD-1.14 Display
  • Pico Diashow mit LCD-1.14 Display
  • USB-Mouse-Jiggler mit Pico-LCD-1.14 Display
  • Pico W als Uhr mit Neopixelring


  • Viel Spass und Erfolg beim Ausprobieren. Wenn Ihnen diese Anleitung gefallen hat, tragen Sie hier bitte einen Kommentar ein.



    Zurück