Pico 2 W Projekte
getestet in CircuitPython 9.2.5
Webserver zur Smart Home Steuerung mit Relais
Bildbox 1 (klick hier)
Software
- CircuitPython 9.2.5
- Bibliotheken im 'lib'-Ordner
- Ordner: adafruit_bme280
- Ordner: adafruit_httpserver
- adafruit_connection_manager.mpy
- adafruit_requests.mpy
- Datei 'settings.toml' mit den Zugangsdaten zum WLAN-Netz
Auf dem oberen Bild ist noch einmal das Relaisboard von SB-Components zu sehen. In der Steuerung sollen die folgenden Funktionen realisiert werden:
Relais 1:
Der Temperatursensor erfasst kontinuierlich die aktuelle Temperatur und schaltet bei einem vorgegebenen Sollwert einen Lüfter ein bzw. aus.
Relais 2:
Es wird über den Helligkeitssensor als Dämmerungsschalter genutzt, welcher eine Beleuchtung steuert.
Relais 3:
Steuert ebenfalls eine Lampe, aber ohne einen angeschlossenen Sensor. Mit Hilfe einer Internetverbindung werden die jeweils aktuellen Sonnenauf- bzw.
Sonnenuntergangszeiten (Sunrise/ Sunset) abgerufen und danach eine Beleuchtung gesteuert.
Relais 4:
Mit Hilfe des Infrarotsensors (Bewegungsmelder) wird eine Bewegung in der Umgebung registriert und eine Lampe eingeschaltet.
Alle vier Funktionen laufen automatisch. Bei Bedarf lassen sich die Verbraucher aber unabhängig voneinander manuell steuern. Dazu wird mit
dem Pico 2W ein Webserver im WLAN bereitgestellt. Über eine Website mit entsprechenden Button erfolgt dann die Steuerung.

Auf der unteren Abbildung zeige ich den Anschluss des Temperatur-, des Licht- und des Bewegungssensors an den Pico 2 W. Der Aufbau ist identisch
mit dem vorherigen Versuch
(siehe hier).

Nachfolgend zeige und beschreibe ich schrittweise den Programmcode. In den Zeilen 1 bis 13 werden die notwendigen Bibliotheken importiert.
In den Zeilen 15 bis 22 werden die Schwellwerte zum Schalten des Lüfters und des Dämmerungsschaltes festgelegt. Experimentieren Sie
ruhig damit. Wenn Sie Änderungen vornehmen, wirken sich diese im gesamten Programm aus. Dann folgen ab Zeile 24 die Definitionen für die Onboard-LED, den
Temperatursensor, den Lichtsensor und den Bewegungssensor.
1 import time
2 import board
3 import busio
4 import ssl
5 import wifi
6 import adafruit_requests
7 import socketpool
8 import digitalio
9 from digitalio import DigitalInOut, Direction
10 from analogio import AnalogIn
11 from adafruit_connection_manager import get_radio_socketpool
12 from adafruit_httpserver import Server, Request, Response, POST
13 from adafruit_bme280 import basic as adafruit_bme280
14
15 ###
16 # Schwellwerte festlegen
17 ###
18 # Temperaturwerte ein/aus
19 tempon = 25
20 tempoff = 24
21 # Schaltschwelle des Lichtsensors
22 soll_wert = 11000
23
24 # onboard LED setup
25 led = DigitalInOut(board.LED)
26 led.direction = Direction.OUTPUT
27 led.value = False
28
29 #I2C Pin of the PicoBoy - Color
30 SDA = board.GP0
31 SCL = board.GP1
32 # Create sensor object, using the board's default I2C bus.
33 i2c = busio.I2C(SCL, SDA)
34 bme280 = adafruit_bme280.Adafruit_BME280_I2C(i2c, address=0x77)
35
36 #initialisieren des Analogen Pin 33 | GP28
37 ADC_2 = AnalogIn(board.GP28)
38
39 # Setup digital inputs for PIR sensor:
40 pir = digitalio.DigitalInOut(board.GP22)
41 pir.direction = digitalio.Direction.INPUT
42 pir.pull = digitalio.Pull.UP
43
Es folgen die Zeiten 'sunrise' und 'sunset'. Dazu wird eine Anfrage an die Seite https://api.sunrise-sunset.org gerichtet. Die Syntax
enthält die Koordinaten des gewünschten Ortes. Geben Sie z.B. in Ihrem Browser folgendes ein:
https://api.sunrise-sunset.org/json?lat=49.7222222&lng=12.1608333&date=today ,
dann erhalten Sie diese Rückmeldung:

Enthalten sind die Sonnenauf- und Sonnenuntergangszeit im UTC-Format. Die werden jetzt in den Zeilen 48 bis 60 bearbeitet und als Variable
'hourrise' und 'hourset' in ganzen Stunden bereitgestellt. Im oben gezeigten Fall würde die Beleuchtung um 4 Uhr aus und um 19 Uhr
eingeschaltet.
44 JSON_URL = "https://api.sunrise-sunset.org/json?lat=49.7222222&lng=12.1608333&date=today"
45 pool = socketpool.SocketPool(wifi.radio)
46 requests = adafruit_requests.Session(pool, ssl.create_default_context())
47 #print("Json abrufen und analysieren von", JSON_URL)
48 response = requests.get(JSON_URL)
49 sunrise = response.json()['results']['sunrise']
50 sunset = response.json()['results']['sunset']
51 if len(sunrise) == 10:
52 sunrise = sunrise[0:1]
53 else:
54 sunrise = sunrise[0:2]
55 hourrise = int(sunrise) + 1
56 if len(sunset) == 10:
57 sunset = sunset[0:1]
58 else:
59 sunset = sunset[0:2]
60 hourset = int(sunset) + 13
61
Die Zeilen 62 bis 104 definieren die Relais 1 bis 4, Umschalter für automatischen bzw. manuellen Betrieb und eine Reihe von Variablen
sowie den http-Server (103, 104). Für die Umschalter 'auto1' bis 'auto4' wurden die GPIO's 2 bis 5 verwendet, um später den Zustand
durch (jetzt noch nicht vorhandene) LED's anzuzeigen.
62 # Relais setup
63 relais1 = DigitalInOut(board.GP18)
64 relais1.direction = Direction.OUTPUT
65 relais1.value = False
66 relais2 = DigitalInOut(board.GP19)
67 relais2.direction = Direction.OUTPUT
68 relais2.value = False
69 relais3 = DigitalInOut(board.GP20)
70 relais3.direction = Direction.OUTPUT
71 relais3.value = False
72 relais4 = DigitalInOut(board.GP21)
73 relais4.direction = Direction.OUTPUT
74 relais4.value = False
75
76 # Umschalter automatisch / manuell
77 auto1 = DigitalInOut(board.GP2)
78 auto1.direction = Direction.OUTPUT
79 auto1.value = True
80 auto2 = DigitalInOut(board.GP3)
81 auto2.direction = Direction.OUTPUT
82 auto2.value = True
83 auto3 = DigitalInOut(board.GP4)
84 auto3.direction = Direction.OUTPUT
85 auto3.value = True
86 auto4 = DigitalInOut(board.GP5)
87 auto4.direction = Direction.OUTPUT
88 auto4.value = True
89
90 r1_color = "#33ff33"
91 r1_show = "anschalten"
92 relais1_state = "aus"
93 r2_color = "#33ff33"
94 r2_show = "anschalten\nwenn dunkel"
95 relais2_state = "aus"
96 r3_color = "#33ff33"
97 r3_show = "anschalten"
98 relais3_state = "aus"
99 r4_color = "#33ff33"
100 r4_show = "keine\nBewegung"
101 relais4_state = "aus"
102
103 pool = get_radio_socketpool(wifi.radio)
104 server = Server(pool, "/static", debug=True)
105
Es folgt ab Zeile 106 die Funktion, welche die Webseite im Browser darstellt. Dazu werden 12 Variable übergeben, die zur
Beschriftung der Button und Zustandsanzeige dienen. Markieren Sie den kompletten Inhalt der unteren Textbox und kopieren ihn
ab Zeile 106 in Ihre Thonny IDE. Damit umfasst das bisherige Programm die Zeilen 1 bis 144. Ggf. fügen Sie als Zeile 145 noch
eine Leerzeile ein.
Als nächstes wird der Webserver aufgerufen. In dieser Funktion werden zunächst die Zeit bestimmt und die Sensoren gelesen (Zeilen
148-155). Danach folgen die Bereiche für den Lüfter (Zeilen 159-183), den Dämmerungsschalter (Zeilen 184-208), die Schaltung nach
Sonnenauf- und Sonnenuntergang (Zeilen 209-231) und der Bereich für den Bewegungsmelder (Zeilen 232-256). In Zeile 260 wird die Antwort auf
die Anfrage zurückgegeben. Machen Sie sich keine Sorgen. Im unteren Kasten ist aus Platzgründen nur ein Teil angezeigt.
Beim Übertragen in die Thonny-IDE in diesem und im nächsten Kasten wird aber selbstverständlich alles kopiert.
146 @server.route("/")
147 def base(request: Request):
148 current_time = time.localtime()
149 hour = current_time.tm_hour
150 # Temperatur : auslesen
151 temp = bme280.temperature
152 # Lichtsensor: auslesen des ADC
153 value = ADC_2.value
154 # pir-Sensor: auslesen
155 pir_value = pir.value
...
...
...
257 ###
258 # Serve the web page
259 ###
260 return Response(request, f"{webpage(r1_color, r1_show, relais1_state, r2_color, r2_show, relais2_state, r3_color, r3_show, relais3_state, r4_color, r4_show, relais4_state)}", content_type='text/html')
261
Wenn Sie zur Probe eine Zeile 262 mit folgenden Aufruf eingeben:
server.serve_forever(str(wifi.radio.ipv4_address)), können Sie testen, ob der Server funktioniert.

Der Browser sollte ihn dann wie im Bild anzeigen. Bisher reagieren aber die Button noch nicht! Wichtig ist, dass keine Fehlermeldung erscheint,
denn dann sind Sie dem Ziel schon ganz nah. Es fehlt jetzt nur noch eine Funktion, welche die Webseite nach der Betätigung eines Button
neu lädt und die geänderten Funktionen auf den Button anzeigt. Dazu löschen Sie die Zeile 262 vom gerade
durchgeführten Test wieder.
Kopieren Sie nun den Quellcode aus dem unteren Kasten und setzen ihn in die Thonny-IDE ab Zeile 262 ein.
262 # if a button is pressed on the site
263 @server.route("/", POST)
264 def buttonpress(request: Request):
265 # get the raw text
...
...
...
363 if relais4.value == True:
364 r4_color = "#ff3333"
365 r4_show = "manuell\nausschalten"
366 relais4_state = "an"
367
368 return Response(request, f"{webpage(r1_color, r1_show, relais1_state, r2_color, r2_show, relais2_state, r3_color, r3_show, relais3_state, r4_color, r4_show, relais4_state)}", content_type='text/html')
369
370 server.serve_forever(str(wifi.radio.ipv4_address))
Geschafft. Sie können jetzt den Webserver starten, indem Sie im Thonny auf 'Ausführen' klicken. In der Kommandozeile erscheint
dann z.B.:
Started development server on http://192.169.181.77:5000
Die angezeigte IP-Adresse aus Ihrem Netzwerk wurde dem Server
per DHCP von Ihrem Router zugewiesen. Klicken Sie darauf und es öffnet sich der Browser mit dem Server. Wenn Sie den Server vom Smartphone
aus steuern wollen, welches sich natürlich im WLAN-Netz befinden muss, brauchen Sie dort ebenfalls nur die IP-Adresse eingeben.
Viel Spass und Erfolg beim Ausprobieren.
Pico 2 W Projekte
getestet in CircuitPython 9.2.5

Bildbox 1 (klick hier)
- CircuitPython 9.2.5
- Bibliotheken im 'lib'-Ordner
- Ordner: adafruit_bme280
- Ordner: adafruit_httpserver
- adafruit_connection_manager.mpy
- adafruit_requests.mpy
- Datei 'settings.toml' mit den Zugangsdaten zum WLAN-Netz
Auf dem oberen Bild ist noch einmal das Relaisboard von SB-Components zu sehen. In der Steuerung sollen die folgenden Funktionen realisiert werden:
Relais 1:
Der Temperatursensor erfasst kontinuierlich die aktuelle Temperatur und schaltet bei einem vorgegebenen Sollwert einen Lüfter ein bzw. aus.
Relais 2:
Es wird über den Helligkeitssensor als Dämmerungsschalter genutzt, welcher eine Beleuchtung steuert.
Relais 3:
Steuert ebenfalls eine Lampe, aber ohne einen angeschlossenen Sensor. Mit Hilfe einer Internetverbindung werden die jeweils aktuellen Sonnenauf- bzw. Sonnenuntergangszeiten (Sunrise/ Sunset) abgerufen und danach eine Beleuchtung gesteuert.
Relais 4:
Mit Hilfe des Infrarotsensors (Bewegungsmelder) wird eine Bewegung in der Umgebung registriert und eine Lampe eingeschaltet.
Alle vier Funktionen laufen automatisch. Bei Bedarf lassen sich die Verbraucher aber unabhängig voneinander manuell steuern. Dazu wird mit dem Pico 2W ein Webserver im WLAN bereitgestellt. Über eine Website mit entsprechenden Button erfolgt dann die Steuerung.

Auf der unteren Abbildung zeige ich den Anschluss des Temperatur-, des Licht- und des Bewegungssensors an den Pico 2 W. Der Aufbau ist identisch mit dem vorherigen Versuch (siehe hier).

Nachfolgend zeige und beschreibe ich schrittweise den Programmcode. In den Zeilen 1 bis 13 werden die notwendigen Bibliotheken importiert. In den Zeilen 15 bis 22 werden die Schwellwerte zum Schalten des Lüfters und des Dämmerungsschaltes festgelegt. Experimentieren Sie ruhig damit. Wenn Sie Änderungen vornehmen, wirken sich diese im gesamten Programm aus. Dann folgen ab Zeile 24 die Definitionen für die Onboard-LED, den Temperatursensor, den Lichtsensor und den Bewegungssensor.
1 import time 2 import board 3 import busio 4 import ssl 5 import wifi 6 import adafruit_requests 7 import socketpool 8 import digitalio 9 from digitalio import DigitalInOut, Direction 10 from analogio import AnalogIn 11 from adafruit_connection_manager import get_radio_socketpool 12 from adafruit_httpserver import Server, Request, Response, POST 13 from adafruit_bme280 import basic as adafruit_bme280 14 15 ### 16 # Schwellwerte festlegen 17 ### 18 # Temperaturwerte ein/aus 19 tempon = 25 20 tempoff = 24 21 # Schaltschwelle des Lichtsensors 22 soll_wert = 11000 23 24 # onboard LED setup 25 led = DigitalInOut(board.LED) 26 led.direction = Direction.OUTPUT 27 led.value = False 28 29 #I2C Pin of the PicoBoy - Color 30 SDA = board.GP0 31 SCL = board.GP1 32 # Create sensor object, using the board's default I2C bus. 33 i2c = busio.I2C(SCL, SDA) 34 bme280 = adafruit_bme280.Adafruit_BME280_I2C(i2c, address=0x77) 35 36 #initialisieren des Analogen Pin 33 | GP28 37 ADC_2 = AnalogIn(board.GP28) 38 39 # Setup digital inputs for PIR sensor: 40 pir = digitalio.DigitalInOut(board.GP22) 41 pir.direction = digitalio.Direction.INPUT 42 pir.pull = digitalio.Pull.UP 43
https://api.sunrise-sunset.org/json?lat=49.7222222&lng=12.1608333&date=today ,
dann erhalten Sie diese Rückmeldung:

Enthalten sind die Sonnenauf- und Sonnenuntergangszeit im UTC-Format. Die werden jetzt in den Zeilen 48 bis 60 bearbeitet und als Variable 'hourrise' und 'hourset' in ganzen Stunden bereitgestellt. Im oben gezeigten Fall würde die Beleuchtung um 4 Uhr aus und um 19 Uhr eingeschaltet.
44 JSON_URL = "https://api.sunrise-sunset.org/json?lat=49.7222222&lng=12.1608333&date=today" 45 pool = socketpool.SocketPool(wifi.radio) 46 requests = adafruit_requests.Session(pool, ssl.create_default_context()) 47 #print("Json abrufen und analysieren von", JSON_URL) 48 response = requests.get(JSON_URL) 49 sunrise = response.json()['results']['sunrise'] 50 sunset = response.json()['results']['sunset'] 51 if len(sunrise) == 10: 52 sunrise = sunrise[0:1] 53 else: 54 sunrise = sunrise[0:2] 55 hourrise = int(sunrise) + 1 56 if len(sunset) == 10: 57 sunset = sunset[0:1] 58 else: 59 sunset = sunset[0:2] 60 hourset = int(sunset) + 13 61
62 # Relais setup 63 relais1 = DigitalInOut(board.GP18) 64 relais1.direction = Direction.OUTPUT 65 relais1.value = False 66 relais2 = DigitalInOut(board.GP19) 67 relais2.direction = Direction.OUTPUT 68 relais2.value = False 69 relais3 = DigitalInOut(board.GP20) 70 relais3.direction = Direction.OUTPUT 71 relais3.value = False 72 relais4 = DigitalInOut(board.GP21) 73 relais4.direction = Direction.OUTPUT 74 relais4.value = False 75 76 # Umschalter automatisch / manuell 77 auto1 = DigitalInOut(board.GP2) 78 auto1.direction = Direction.OUTPUT 79 auto1.value = True 80 auto2 = DigitalInOut(board.GP3) 81 auto2.direction = Direction.OUTPUT 82 auto2.value = True 83 auto3 = DigitalInOut(board.GP4) 84 auto3.direction = Direction.OUTPUT 85 auto3.value = True 86 auto4 = DigitalInOut(board.GP5) 87 auto4.direction = Direction.OUTPUT 88 auto4.value = True 89 90 r1_color = "#33ff33" 91 r1_show = "anschalten" 92 relais1_state = "aus" 93 r2_color = "#33ff33" 94 r2_show = "anschalten\nwenn dunkel" 95 relais2_state = "aus" 96 r3_color = "#33ff33" 97 r3_show = "anschalten" 98 relais3_state = "aus" 99 r4_color = "#33ff33" 100 r4_show = "keine\nBewegung" 101 relais4_state = "aus" 102 103 pool = get_radio_socketpool(wifi.radio) 104 server = Server(pool, "/static", debug=True) 105
Als nächstes wird der Webserver aufgerufen. In dieser Funktion werden zunächst die Zeit bestimmt und die Sensoren gelesen (Zeilen 148-155). Danach folgen die Bereiche für den Lüfter (Zeilen 159-183), den Dämmerungsschalter (Zeilen 184-208), die Schaltung nach Sonnenauf- und Sonnenuntergang (Zeilen 209-231) und der Bereich für den Bewegungsmelder (Zeilen 232-256). In Zeile 260 wird die Antwort auf die Anfrage zurückgegeben. Machen Sie sich keine Sorgen. Im unteren Kasten ist aus Platzgründen nur ein Teil angezeigt. Beim Übertragen in die Thonny-IDE in diesem und im nächsten Kasten wird aber selbstverständlich alles kopiert.
146 @server.route("/") 147 def base(request: Request): 148 current_time = time.localtime() 149 hour = current_time.tm_hour 150 # Temperatur : auslesen 151 temp = bme280.temperature 152 # Lichtsensor: auslesen des ADC 153 value = ADC_2.value 154 # pir-Sensor: auslesen 155 pir_value = pir.value ... ... ... 257 ### 258 # Serve the web page 259 ### 260 return Response(request, f"{webpage(r1_color, r1_show, relais1_state, r2_color, r2_show, relais2_state, r3_color, r3_show, relais3_state, r4_color, r4_show, relais4_state)}", content_type='text/html') 261
server.serve_forever(str(wifi.radio.ipv4_address)), können Sie testen, ob der Server funktioniert.

Der Browser sollte ihn dann wie im Bild anzeigen. Bisher reagieren aber die Button noch nicht! Wichtig ist, dass keine Fehlermeldung erscheint, denn dann sind Sie dem Ziel schon ganz nah. Es fehlt jetzt nur noch eine Funktion, welche die Webseite nach der Betätigung eines Button neu lädt und die geänderten Funktionen auf den Button anzeigt. Dazu löschen Sie die Zeile 262 vom gerade durchgeführten Test wieder. Kopieren Sie nun den Quellcode aus dem unteren Kasten und setzen ihn in die Thonny-IDE ab Zeile 262 ein.
262 # if a button is pressed on the site 263 @server.route("/", POST) 264 def buttonpress(request: Request): 265 # get the raw text ... ... ... 363 if relais4.value == True: 364 r4_color = "#ff3333" 365 r4_show = "manuell\nausschalten" 366 relais4_state = "an" 367 368 return Response(request, f"{webpage(r1_color, r1_show, relais1_state, r2_color, r2_show, relais2_state, r3_color, r3_show, relais3_state, r4_color, r4_show, relais4_state)}", content_type='text/html') 369 370 server.serve_forever(str(wifi.radio.ipv4_address))
Started development server on http://192.169.181.77:5000
Die angezeigte IP-Adresse aus Ihrem Netzwerk wurde dem Server per DHCP von Ihrem Router zugewiesen. Klicken Sie darauf und es öffnet sich der Browser mit dem Server. Wenn Sie den Server vom Smartphone aus steuern wollen, welches sich natürlich im WLAN-Netz befinden muss, brauchen Sie dort ebenfalls nur die IP-Adresse eingeben.