Raspberry Pi Pico W Einsteiger-Tutorial für Komponenten
In diesem Raspberry Pi Pico W Einsteiger-Tutorial lernen Sie, wie Sie mit dem Mikrocontroller interagieren, um einfache Komponenten wie LEDs, Ultraschallsensoren und viele andere Dinge, die in einem Einsteigerbausatz zu finden sind, zu steuern.
Wenn Sie ein absoluter Anfänger sind, wird dieses Tutorial Ihnen helfen, MicroPython zu verstehen, damit Sie Code lesen, schreiben und ändern können. Mit diesem Wissen können Sie Code und Komponenten kombinieren, um etwas zu erstellen, das einen realen Anwendungsfall hat.
Wenn Sie von einem Pico kommen, lernen Sie in diesem Tutorial, wie Sie den Pico W drahtlos steuern können. Bisher konnten Sie mit dem Pico nur über einen Schalter, eine Taste oder ein anderes physisches Interaktionsgerät interagieren. Das ist jetzt vorbei! Sie können die Komponenten jetzt mit Ihrem Telefon oder Desktop steuern.
Tutorial-Fluss
Einführung
Das Hello World-Tutorial für den Pico W
Eine Stufe höher
Grundlegende Möglichkeiten zur Übertragung von Sensordaten
- Pico W und HC-SR04 Ultraschallsensor
- Übertragen einer Webseite mit Sensordaten
- Verringerung der Nutzlast mit AJAX
- Pimoroni Phew zur Rationalisierung der Endpunktkodierung
Verbinden mit Web-Dienstprogrammen
- Protokollierung der Klimadaten des DHT22-Sensors in Google Sheets mit IFTTT
- Bau einer Spotify-Fernbedienung mit Play/Pause/Skip-Funktionen
Codefreie GPIO-Steuerung mit PiCockpit
- Super einfache PiCockpit Installation auf Pico W
- Einfache LED-Ansteuerung mit PiCockpit und Pico W
- Pico W, 5V Lüfter und ein Transistor, gesteuert von PiCockpit
MQTT
Inhaltsübersicht
Ziele des Tutorials im Überblick
- Lernen, wie man mit grundlegenden Komponenten interagiert, aus denen größere Projekte bestehen
- All diese Geräte lassen sich drahtlos steuern - ohne Schalter, Knöpfe oder andere Interaktionsgeräte.
- Ein besseres Verständnis der Stärken des Pico W gewinnen
Wichtige Links
Github-Depot für den Code des Tutorials (außer secrets.py)
Fehler, Anregungen, Kommentare? Hinterlassen Sie einen Kommentar in der Kommentarbox unten, E-Mail oder Tweeten Sie mich.
OSError: [Errno 98] EADDRINUSE
Wenn Sie diese Fehlermeldung erhalten, ziehen Sie einfach Ihren Raspberry Pi Pico ab und schließen Sie ihn wieder an.
Sie können dies auch tun, indem Sie diese Befehle in Thonnys Shell eingeben:
import machine
machine.reset()
Ergebnis:
Löten von Kopfstiften
Wenn Sie einen Raspberry Pi Pico W kaufen, wird er möglicherweise nicht mit Headern geliefert, die es Ihnen ermöglichen, Komponenten an Ihren Pico anzuschließen.
Zum Zeitpunkt der Erstellung dieses Artikels ist der Pico WH (H für Header) noch nicht freigegeben worden. Unser Mega-Artikel über den Pico W verfolgt seine Veröffentlichung.
Wenn Sie jedoch einen Pico W mit vorgelöteten Headern finden können, würde ich Ihnen raten, diesen zu kaufen.
Für den Rest von uns ist das Anlöten von Stiftleisten an den Pico W jedoch eine einfache Sache. Sie benötigen:
- Brettchen
- Lötkolben und Lötzinn
- Kopfzeilen
Wenn Sie Ihre Header kaufen, stellen Sie sicher, dass Sie einen kaufen, der für den Pico W bestimmt ist. Im Gegensatz zu den Headern für die Raspberry Pi Zero-Serie sind die Header auf dem Pico W nicht nebeneinander angeordnet. Sie befinden sich an den gegenüberliegenden Enden der Platine.
Die Pins haben eine lange Seite und eine kurze Seite. Die längeren Pins sollten sich auf der Seite befinden, auf der die GPIO-Beschriftungen zu sehen sind (GP0, GP1, GND, VBUS, VSYS, usw.)
Setzen Sie daher die längeren Stifte in die Lochrasterplatine ein. Sie benötigen vier Löcher und einen Abstand von einer Dachrinne dazwischen. Wenn Sie unsicher sind, testen Sie mit Ihrem Pico W.
Löten ist einfach. Vergewissern Sie sich, dass Ihr Lötkolben heiß ist, und achten Sie darauf, die Spitze des Lötkolbens zu verwenden.
Am effektivsten war es, die Spitze des Lötkolbens nahe an den Stift zu bringen, das Lötzinn mit der Spitze in Berührung zu bringen und zu sehen, wie es am Stift herunterfließt und eine Verbindung herstellt.
Überprüfen Sie nach dem Löten, dass kein überschüssiges Lötzinn mehr vorhanden ist, das zwei GPIO-Pins miteinander verbinden könnte, oder dass keine Lötzinnreste mehr auf der Platine vorhanden sind.
Verwenden Sie Thonny als Code-Editor
Thonny ist und bleibt der einfachste Weg, Ihren Raspberry Pi Pico W zu programmieren.
Wenn Sie das Betriebssystem des Raspberry Pi verwenden, haben Sie es bereits installiert.
Wenn Sie jedoch Windows oder Mac verwenden, müssen Sie es herunterladen und konfigurieren.
Hier finden Sie eine Anleitung, die Sie durch die einzelnen Schritte führt.
Achten Sie auch darauf, dass Lesen Sie die Anleitung zum Hochladen von Dateien auf Ihren Pico W.
Aktualisieren Sie Ihre Firmware durch Hochladen der neuesten UF2
Wenn Sie Ihren Pico W kaufen, haben Sie möglicherweise bereits die veraltete Firmware.
Für den Pico W stehen viele Änderungen an, daher ist es ideal, die Firmware jetzt zu aktualisieren.
Einige Änderungen, die ich seit dem Tag der Veröffentlichung gesehen habe, sind Verbesserungen der WLAN-Access-Point-Funktion, und zukünftige Updates könnten die Bluetooth-Funktion auf dem Board freischalten.
Jetzt aktualisieren! Hier ist ein Leitfaden in unserem Mega-Artikel.
1. Eine Webseite mit dem Text "Hello World" auf dem Pico anzeigen
Eines der grundlegendsten Projekte in allen Programmier-Tutorials ist das "Hello World"-Projekt.
Das "Hello World" eines Mikrocontrollers besteht normalerweise aus dem Blinken einer LED. Es ist ganz einfach. So geht's.
Da der Pico W jedoch eine Webseite anzeigen kann, wollen wir zunächst lernen, wie man eine Webseite mit einer "Hello World"-Nachricht anzeigt.
Der hier verwendete Aufbau bildet den grundlegenden Baustein für den Rest der Tutorials.
Sie können den Pico W auf zwei Arten mit einem WiFi-Netzwerk verbinden einen SoftAP-Hotspot ausstrahlen, ähnlich wie bei Ihrem Smartphone. Wenn Sie Letzteres versuchen wollen, Folgen Sie diesem Link. Aus Gründen der Einheitlichkeit werden wir in dieser Anleitung jedoch immer eine Verbindung zu einem WiFi-Netzwerk herstellen, anstatt eines vom Pico W zu übertragen.
Die Schritte zur Bereitstellung einer Webseite umfassen also im Wesentlichen Folgendes:
- Verbinden mit WiFi
- Schreiben von Code, um index.html an jeden zu senden, der sich mit der IP-Adresse des Pico W verbindet
Lassen Sie uns ein paar Dateien einrichten. Speichern Sie diese und laden Sie sie auf Ihren Raspberry Pi Pico W hoch. Hier erfahren Sie, wie Sie Dateien hochladen können, falls Sie es verpasst haben.
wifi.py
wifi.py ist eine Boilerplate, die Ihnen helfen soll, sich mit Ihrem WiFi-Netzwerk zu verbinden. Erstellen Sie eine separate Datei und importieren Sie sie in main.py Datei wird später dazu beitragen, unübersichtlichen Code zu vermeiden.
Beachten Sie, dass Sie den Code Ihres Landes in der folgenden Zeile ändern sollten rp2.country('DE') wenn Ihr Land nicht Deutschland ist.
import rp2
import network
import ubinascii
import machine
import urequests as requests
import time
from secrets import secrets
def init_wifi():
# Set country to avoid possible errors
rp2.country('DE')
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
# Load login data from different file for safety reasons
ssid = secrets['ssid']
pw = secrets['pw']
wlan.connect(ssid, pw)
# Wait for connection with 10 second timeout
timeout = 10
while timeout > 0:
if wlan.status() < 0 or wlan.status() >= 3:
break
timeout -= 1
print('Waiting for connection...')
time.sleep(1)
# Define blinking function for onboard LED to indicate error codes
def blink_onboard_led(num_blinks):
led = machine.Pin('LED', machine.Pin.OUT)
for i in range(num_blinks):
led.on()
time.sleep(.2)
led.off()
time.sleep(.2)
wlan_status = wlan.status()
blink_onboard_led(wlan_status)
if wlan_status != 3:
raise RuntimeError('Wi-Fi connection failed')
else:
print('Connected')
status = wlan.ifconfig()
print('ip = ' + status[0])
geheimnisse.py
wifi.py Einfuhren geheimnisse.py, wo Sie die Daten Ihres WiFi-Netzwerks speichern.
geheimnisse.py ist eine einfache JSON-Datei, die Ihre WiFi SSID und Ihr Passwort enthält.
secrets = {
'ssid': 'SM-A520W9371',
'pw': 'starting',
}
serve_webpage.py
Wie der Name schon sagt, bietet diese Seite Websites für Benutzer an, die eine Verbindung mit dem Pico W herstellen.
Beim Empfang einer Verbindung findet der Pico W eine Datei namens index.html und sendet es an den verbundenen Client, wie in der Zeile Antwort = get_html('index.html').
import socket
def serve_webpage():
#Function to load in html page
def get_html(html_name):
# open html_name (index.html), 'r' = read-only as variable 'file'
with open(html_name, 'r') as file:
html = file.read()
return html
# HTTP server with socket
addr = socket.getaddrinfo('0.0.0.0', 80)[0][-1]
s = socket.socket()
s.bind(addr)
s.listen(1)
print('Listening on', addr)
# Listen for connections
while True:
try:
cl, addr = s.accept()
print('Client connected from', addr)
response = get_html('index.html')
cl.send('HTTP/1.0 200 OK\r\nContent-type: text/html\r\n\r\n')
cl.send(response)
cl.close()
except OSError as e:
cl.close()
print('Connection closed')
Schließlich müssen wir die index.html Datei, die an einen verbundenen Client gesendet wird.
<!DOCTYPE html>
<html>
<head>
<title>Pico W</title>
</head>
<body>
<h1>Hello World</h1>
</body>
</html>
Dies ist ein einfaches HTML-Boilerplate mit zwei Änderungen: eine an der <title>Tag, der "Pico W" als Titel ausgibt, und den <h1>-Tag, der "Hello World" sagt.
main.py
Da wir den gesamten Code an anderer Stelle platziert haben, ist unser main.py Datei muss nur diese Funktionen importieren und aufrufen, um die Hello World-Webseite zu bedienen.
Wie Sie sehen können, wird WiFi zuerst initialisiert, bevor die Webseite bereitgestellt wird.
from wifi import init_wifi
from serve_webpage import serve_webpage
init_wifi()
serve_webpage()
Sie sind fast am Ziel!
Vergewissern Sie sich anhand der nachstehenden Abbildung:
- Sie haben fünf Dateien auf Ihren Raspberry Pi Pico W hochgeladen (siehe roter Kasten unten links)
- Vergewissern Sie sich, dass Ihr Interpreter eingestellt ist auf MicroPython (Raspberry Pi Pico) (siehe Kasten unten rechts)
- Markieren Sie dann die main.py in Ihrem Code-Editor, und klicken Sie auf die grüne Schaltfläche "Ausführen" (rotes Feld oben links)
- Sobald Sie dies ausführen, sehen Sie Ihre IP-Adresse in der Shell. Geben Sie diese Adresse in Ihren Browser ein und Sie sehen die Hello World-Webseite.
- Wenn Ihre Shell nicht geöffnet ist, gehen Sie zu Ansicht -> Shell.
Wenn alles erfolgreich war, sehen Sie die folgende Seite.
2. Drahtlose Steuerung einer LED
Nachdem Sie nun die Grundlagen geschaffen haben, gehen wir einen Schritt weiter.
Eines der grundlegendsten Raspberry Pi-Projekte beinhaltet das Blinken einer LED.
Wir wollen die LED drahtlos steuern und damit einen Schritt weiter gehen. Wir wollen in der Lage sein, die LED zu blinken, ein- und auszuschalten.
Dazu müssen Sie einen Schaltkreis und einen Webserver mit drei Tasten - ON, OFF, BLINK - einrichten.
Für dieses Projekt benötigen Sie eine LED, einen 330-Ohm-Widerstand, einen Überbrückungsdraht und ein Steckbrett.
Wir werden eine rote LED verwenden, weil die meisten Bausätze sie haben. Beachten Sie, dass Sie den Widerstand anpassen müssen, wenn Sie eine LED mit einer anderen Farbe verwenden.
So schließen Sie die Komponenten an
- GPIO 2 -> Langes Bein der LED (Anode/Positiv)
- GND -> 330-Ohm-Widerstand -> kurzes Bein der LED (Kathode/Negativ)
Code zur Steuerung der LED am Pico W
Lassen Sie uns auf dem aufbauen, was wir im vorherigen Tutorial gemacht haben. Die einzigen beiden Dateien, die wir ändern müssen, sind index.html zum Hinzufügen von Schaltflächen und main.py mit der LED zu interagieren, basierend auf den Eingaben von index.html.
Die fett gedruckten Teile zeigen die neuen Zeilen an, die hinzugefügt wurden index.html. Sie fügen drei Schaltflächen und einen Absatz mit der Aufschrift "Control the LED" hinzu.
<!DOCTYPE html>
<html>
<head>
<title>Pico W</title>
</head>
<body>
<h1>Pico W</h1>
<p>Control the LED</p>
<a href=\"?led=on\"><button>ON</button></a>
<a href=\"?led=off\"><button>OFF</button></a>
<a href=\"?led=blink\"><button>BLINK</button></a>
</body>
</html>
Wenn Sie die Tasten drücken, wird ein Parameter zur IP-Adresse Ihres Pico W hinzugefügt (z. B. http://192.168.43.134/%22?led=blink\). Diese Parameter werden vom Backend des Pico W erfasst und steuern die LED.
Wir werden umziehen serve_webpage.pyin den Code der main.py Datei.
Hier ist main.py:
from wifi import init_wifi
import socket
import machine
import time
init_wifi()
#LED controls
led = machine.Pin(2, machine.Pin.OUT)
def blink_led():
led.on()
time.sleep(0.2)
led.off()
time.sleep(0.2)
#Function to load in html page
def get_html(html_name):
# open html_name (index.html), 'r' = read-only as variable 'file'
with open(html_name, 'r') as file:
html = file.read()
return html
# HTTP server with socket
addr = socket.getaddrinfo('0.0.0.0', 80)[0][-1]
s = socket.socket()
s.bind(addr)
s.listen(1)
print('Listening on', addr)
# Listen for connections
while True:
try:
cl, addr = s.accept()
print('Client connected from', addr)
request = cl.recv(1024)
print(request)
request = str(request)
led_on = request.find('?led=on')
led_off = request.find('?led=off')
led_blink = request.find('?led=blink')
print('led_on = ', led_on)
print('led_off = ', led_off)
print('led_blink = ', led_blink)
if led_on > -1:
print('LED ON')
led.on()
if led_off > -1:
print('LED OFF')
led.off()
if led_blink > -1:
print('LED BLINK')
blink_led()
response = get_html('index.html')
cl.send('HTTP/1.0 200 OK\r\nContent-type: text/html\r\n\r\n')
cl.send(response)
cl.close()
except OSError as e:
cl.close()
print('Connection closed')
Das erste und wichtigste Segment finden Sie unten:
request = cl.recv(1024)
print(request)
request = str(request)
led_on = request.find('?led=on')
led_off = request.find('?led=off')
led_blink = request.find('?led=blink')
print('led_on = ', led_on)
print('led_off = ', led_off)
print('led_blink = ', led_blink)
if led_on > -1:
print('LED ON')
led.on()
if led_off > -1:
print('LED OFF')
led.off()
if led_blink > -1:
print('LED BLINK')
blink_led()
Die Variable "request" gibt, wenn sie gedruckt wird, den ersten Textblock unten aus. Die letzten drei Zeilen sind die Druckanweisungen, die prüfen, ob die LED an, aus oder blinkt:
b'GET /%22?led=blink\\%22 HTTP/1.1\r\nHost: 192.168.43.134\r\nConnection: keep-alive\r\nCache-Control: max-age=0\r\nUpgrade-Insecure-Requests: 1\r\nUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36\r\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9\r\nReferer: http://192.168.43.134/%22?led=on\\%22\r\nAccept-Encoding: gzip, deflate\r\nAccept-Language: en-US,en;q=0.9,es;q=0.8,zh-TW;q=0.7,zh-CN;q=0.6,zh;q=0.5\r\n\r\n'
led_on = 456
led_off = -1
led_blink = 10
Der obige Code wird versuchen, bestimmte Zeichenfolgen wie "led=on". Wenn er existiert, ist der Wert größer als -1 und löst damit die entsprechende wenn Erklärung.
Wenn z. B. led=on in den Parametern vorhanden ist, dann wird die Variable led_on größer als -1 sein, so dass die wenn led_on > -1 Anweisung auslöst und ausführt led.on();
Der einzige komplizierte Teil ist die led_blink die die Funktion auslösen wird:
def blink_led():
led.on()
time.sleep(0.2)
led.off()
time.sleep(0.2)
Schließlich wird GPIO 2 für den Betrieb der LED initialisiert:
import machine
import time
#LED controls
led = machine.Pin(2, machine.Pin.OUT)
Wir importieren Maschine, um mit dem GPIO-Pin zu interagieren. Wie Sie in der Variable sehen können geführtwollen wir, dass der Pico W GPIO 2 versorgt.
Wir importieren Zeit so dass wir eine Pause von 0,2 Sekunden in blink_led().
3. RGB-LED am Pico W
Um Ihre RGB-LED zum Leuchten zu bringen, benötigen Sie:
- Drei 330-Ohm-Widerstände
- Eine RGB-LED
- Ein Schaltdraht
An der RGB-LED finden Sie vier Beine. Ein Bein ist das längste. Das ist entweder eine Kathode (negativ) oder eine Anode (positiv). Meine RGB-LED hatte eine gemeinsame Kathode, also ist hier der Anschluss:
- GPIO 15 -> 330-Ohm-Widerstand -> rote LED
- GPIO 17 -> Widerstand -> grüne LED
- GPIO 16 -> Widerstand -> blaue LED
Hier ist ein Code, um zu sehen, ob Sie richtig verdrahtet haben:
import machine
red_led = machine.PWM(machine.Pin(15))
green_led = machine.PWM(machine.Pin(17))
blue_led = machine.PWM(machine.Pin(16))
red_led.duty_u16(65534)
green_led.duty_u16(65534)
blue_led.duty_u16(65534)
In diesem Beispiel verwenden wir PWM, mit dem Sie die Helligkeit der LEDs R, G und B variieren können.
Sie können die an [color].duty_u16 übergebenen Werte in einen Wert zwischen 0 und 65534 ändern. Theoretisch sollten Sie 65535 übergeben können, aber irgendwie scheint das bei mir nicht zu funktionieren.
Die Angabe "0" bedeutet, dass Sie null Prozent Helligkeit wünschen. Wenn Sie 65534 eingeben, wollen Sie 100 Prozent Helligkeit.
Wenn Sie 65534 für eine Farbe und Null für die anderen Farben eingeben, können Sie feststellen, ob Sie die richtigen GPIO-Pins mit der richtigen LED-Farbe verbunden haben.
Warum verwenden wir also PWM? Weil man damit mehr Farben erzielen kann. Wenn du nur eine "Ein-und-Aus"-Methode verwendest, kannst du rotes, grünes, blaues, weißliches oder gar kein Licht erzeugen. Mit PWM können Sie die Intensität der R-, G- und B-LED variieren und so viele Farben erzeugen, wie Sie sich vorstellen können.
Jetzt wollen wir etwas schaffen, das Sie drahtlos steuern können!
index.html
Die wichtigste Änderung besteht darin, dass es eine <form> der drei Schieberegler hat. Diese Schieberegler haben einen Wert zwischen Null und 100.
Die Verwendung von Werten zwischen null und 100 hilft Ihnen, die Helligkeit als Prozentsatz zu visualisieren. Es reduziert auch die Menge an Code, die benötigt wird, um den Wert aus den Parametern auszulesen (siehe später in main.py)
Wenn Sie die Werte für die R-, G- und B-LEDs eingestellt haben, drücken Sie auf "Submit", und diese Daten werden vom Pico W erfasst.
<!DOCTYPE html>
<html>
<head>
<title>Pico W</title>
</head>
<body>
<h1>Pico W RGB LED</h1>
<form id="form">
<input type="range" min="0" max="100" value="slider_value" name="red" id="red">
<label for="red">R</p>
<input type="range" min="0" max="100" value="slider_value" name="green" id="green">
<label for="green">G</p>
<input type="range" min="0" max="100" value="slider_value" name="blue" id="blue">
<label for="blue">B</p>
<input type="submit" id="submit">
</form>
<script>
submit.addEventListener('click', function () {
form.submit();
}, false);
</script>
</html>
main.py
from wifi import init_wifi
import socket
import machine
import time
init_wifi()
#LED controls
red_led = machine.PWM(machine.Pin(15))
green_led = machine.PWM(machine.Pin(17))
blue_led = machine.PWM(machine.Pin(16))
#Function to load in html page
def get_html(html_name):
# open html_name (index.html), 'r' = read-only as variable 'file'
with open(html_name, 'r') as file:
html = file.read()
return html
def find_intensity(color, request_str):
index = request_str.find(color) + len(color)
offset = 0
if request_str[index].isdigit():
offset = 1
if request_str[index+1].isdigit():
offset = 2
if request_str[index+2].isdigit():
offset = 3
intensity = int(request_str[index:index+offset])
return intensity
# HTTP server with socket
addr = socket.getaddrinfo('0.0.0.0', 80)[0][-1]
s = socket.socket()
s.bind(addr)
s.listen(1)
print('Listening on', addr)
# Listen for connections
while True:
try:
cl, addr = s.accept()
print('Client connected from', addr)
request = cl.recv(1024)
request_str = str(request)
#find intensity ONLY if the params exist in request
if request_str.find('red') > -1 :
#int = get rid of decimal
#/100*65534 = find_intensity returns something 0 to 100,
# so x/100 = proportion of 65534 that you want to send to LED
# 65534 = max number you can use for PWM
red_intensity = int(find_intensity('red=', request_str) /100 * 65534)
green_intensity = int(find_intensity('green=', request_str) /100 * 65534)
blue_intensity = int(find_intensity('blue=', request_str) /100 * 65534)
#print('r=' + str(red_intensity))
#print('g=' + str(green_intensity))
#print('b=' + str(blue_intensity))
red_led.duty_u16(red_intensity)
green_led.duty_u16(green_intensity)
blue_led.duty_u16(blue_intensity)
response = get_html('index.html')
cl.send('HTTP/1.0 200 OK\r\nContent-type: text/html\r\n\r\n')
cl.send(response)
cl.close()
except OSError as e:
cl.close()
print('Connection closed')
Wenn Sie auf "Senden" in der index.html Webseite, übernimmt der Pico W die Parameter und verarbeitet sie.
Schauen wir uns einige wichtige Punkte im Code an, die im obigen Codeblock fett gedruckt sind.
find_intensity-Funktion
Diese Funktion benötigt zwei Parameter: Farbe und anfrage_str. Farbe gibt "rot", "grün" oder "blau" ein und findet den Wert nach dem Gleichheitszeichen (=).
Zum Beispiel lautet Ihre URL nach dem Absenden des Formulars "http://192.168.1.142/?red=89&green=50&blue=50".
Wenn Sie "rot" an find_intensity übergeben, wird 89 zurückgegeben.
Intensitätsparser
Der zweite fettgedruckte Codeblock stellt den Code dar, der dem GPIO des Pico W mitteilt, wie viel Helligkeit von jeder LED gewünscht wird.
Zunächst müssen wir sicherstellen, dass die Parameter in der URL vorhanden sind. Dies geschieht durch die wenn Anweisung request_str.find('rot') > -1. Ich habe gerade 'rot' weil die Parameter 100% die Zeichenfolge "rot" enthalten, wenn Sie das Formular verwenden.
Wenn Sie die IP-Adresse Ihres Pico W (z.B. http://192.168.1.142/) zum ersten Mal besuchen, haben Sie die Parameter nicht, so dass das Programm abstürzen wird, wenn Sie find_intensity.
Wenn Parameter vorhanden sind, wird die Intensität für jede LED entsprechend den angegebenen Werten ermittelt. Werfen wir einen Blick auf red_intensity.
red_intensity = int(find_intensity('red=', request_str) /100 * 65534)
...
red_led.duty_u16(red_intensity)
find_intensity gibt eine ganze Zahl zwischen Null und 100 zurück. Dieser Wert wird durch 100 geteilt, um einen Prozentsatz zu erhalten. Dieser Prozentsatz teilt den maximalen Wert, den die Pflicht_u16 Methode einnehmen kann.
Wir brauchen jedoch eine int Funktion zu verpacken, weil Sie manchmal einen Float erhalten und Pflicht_u16 braucht eine int. Beispiel: Sie wollen 41% Helligkeit - 41% von 65534 ist 26.868,94. Sie können diesen Float nicht übergeben, da das Programm sonst abstürzt.
4. Betrieb des Summers auf dem Pico W
Ein Summer ist eine ziemlich wichtige Komponente für grundlegende Benachrichtigungen, so wie eine LED über den Zustand einer Sache informieren kann, gibt ein Summer eine akustische Benachrichtigung.
Anstatt meinen eigenen Code zu implementieren, habe ich mich für die Verwendung von Giuseppe Cassibba's Umsetzung. Wenn Sie seinen Code auf dem Pico W ausgeführt haben, hören Sie Pieptöne auf Ihrem Buzzer.
Da dieser Code aber für den Pico gedacht ist, wird er keine drahtlosen Interaktionsfunktionen haben.
Also, raus mit der Gabel!
Ändern wir zunächst die index.html um die Schaltflächen zu implementieren. Wir haben eine Schaltfläche für "EIN", "AUS", "SKALIEREN", "MUSIK".
Die ersten beiden Tasten sind selbsterklärend. Die dritte Taste spielt eine C-Skala und die letzte Taste spielt ein Musikstück.
<!DOCTYPE html>
<html>
<head>
<title>Pico W</title>
</head>
<body>
<h1>Pico W Buzzer</h1>
<p>Control the buzzer</p>
<a href=\"?buzzer=on\"><button>ON</button></a>
<a href=\"?buzzer=off\"><button>OFF</button></a>
<a href=\"?buzzer=scale\"><button>SCALE</button></a>
<a href=\"?buzzer=music\"><button>MUSIC</button></a>
</body>
</html>
Genau wie zuvor erstellen wir ein paar <button> Tags mit <a> Tags um sie herum. Wenn Sie auf die Schaltflächen klicken, enthält die URL einen Parameter wie /buzzer=on. Der Pico W liest dies und schaltet den Summer ein.
Schauen wir uns nun den Code von Giuseppe für den Pico an:
from machine import Pin, PWM
from time import sleep
buzzerPIN=16
BuzzerObj=PWM(Pin(buzzerPIN))
def buzzer(buzzerPinObject,frequency,sound_duration,silence_duration):
# Set duty cycle to a positive value to emit sound from buzzer
buzzerPinObject.duty_u16(int(65536*0.2))
# Set frequency
buzzerPinObject.freq(frequency)
# wait for sound duration
sleep(sound_duration)
# Set duty cycle to zero to stop sound
buzzerPinObject.duty_u16(int(65536*0))
# Wait for sound interrumption, if needed
sleep(silence_duration)
# Play following notes by changing frequency:
#C (DO)
buzzer(BuzzerObj,523,0.5,0.1)
#D (RE)
buzzer(BuzzerObj,587,0.5,0.1)
#E (MI)
buzzer(BuzzerObj,659,0.5,0.1)
#F (FA)
buzzer(BuzzerObj,698,0.5,0.1)
#G (SOL)
buzzer(BuzzerObj,784,0.5,0.1)
#A (LA)
buzzer(BuzzerObj,880,0.5,0.1)
#B (SI)
buzzer(BuzzerObj,987,0.5,0.1)
#Deactivates the buzzer
BuzzerObj.deinit()
Sein Code spielt eine C-Skala, wenn er mit der Funktion Buzzer()die vier Parameter aufnimmt: Buzzer-Objekt, Frequenz in Hertz, Tondauer und Pausendauer vor dem nächsten Ton.
Ändern wir den Code so, dass wir die ON, OFF, SCALE und MUSIK.
So integrieren wir den Code von Giuseppe in unsere main.py:
from wifi import init_wifi
import socket
import machine
import time
init_wifi()
# Buzzer
buzzerPIN = 16
BuzzerObj = machine.PWM(machine.Pin(buzzerPIN))
def buzzer(buzzerPinObject, frequency, sound_duration, silence_duration):
# Set duty cycle to a positive value to emit sound from buzzer
buzzerPinObject.duty_u16(int(65536*0.2))
# Set frequency
buzzerPinObject.freq(frequency)
# wait for sound duration
time.sleep(sound_duration)
# Set duty cycle to zero to stop sound
buzzerPinObject.duty_u16(int(65536*0))
# Wait for sound interrumption, if needed
time.sleep(silence_duration)
# Function to load in html page
def get_html(html_name):
# open html_name (index.html), 'r' = read-only as variable 'file'
with open(html_name, 'r') as file:
html = file.read()
return html
# HTTP server with socket
addr = socket.getaddrinfo('0.0.0.0', 80)[0][-1]
s = socket.socket()
s.bind(addr)
s.listen(1)
print('Listening on', addr)
# Listen for connections
while True:
try:
cl, addr = s.accept()
print('Client connected from', addr)
request = cl.recv(1024)
request = str(request)
buzzer_on = request.find('?buzzer=on')
buzzer_off = request.find('?buzzer=off')
buzzer_scale = request.find('?buzzer=scale')
buzzer_music = request.find('?buzzer=music')
if buzzer_on > -1:
BuzzerObj.duty_u16(int(65536*0.2))
BuzzerObj.freq(440)
if buzzer_off > -1:
BuzzerObj.duty_u16(0)
if buzzer_scale > -1:
#C (DO)
buzzer(BuzzerObj, 523, 0.5, 0.1)
#D (RE)
buzzer(BuzzerObj, 587, 0.5, 0.1)
#E (MI)
buzzer(BuzzerObj, 659, 0.5, 0.1)
#F (FA)
buzzer(BuzzerObj, 698, 0.5, 0.1)
#G (SOL)
buzzer(BuzzerObj, 784, 0.5, 0.1)
#A (LA)
buzzer(BuzzerObj, 880, 0.5, 0.1)
#B (SI)
buzzer(BuzzerObj, 987, 0.5, 0.1)
BuzzerObj.deinit()
if buzzer_music > -1:
pass
response = get_html('index.html')
cl.send('HTTP/1.0 200 OK\r\nContent-type: text/html\r\n\r\n')
cl.send(response)
cl.close()
except OSError as e:
cl.close()
print('Connection closed')
In der obigen Implementierung haben wir nicht den Code für MUSIK.
Der Code ist dem obigen Tutorial für die rote LED sehr ähnlich, wobei der Pico W die Parameter nach der IP-Adresse des Pico W erfasst. Wenn die Param buzzer=ON, wird ein 440Hz-Ton abgespielt. Wenn buzzer=scalewird die Tonleiter aus Giuseppes Code abgespielt.
Was ist mit der Implementierung von Musik? Die Implementierung von Musik ist etwas komplizierter, daher sollten wir eine neue Datei namens konstanten.py und fügen Sie ein paar Zeilen in unser main.py.
Dieser Code ist ein Fork von Arduino-Code von Rowan Packard.
konstanten.py
A3F = 208 # 208 Hz
B3F = 233 # 233 Hz
B3 = 247 # 247 Hz
C4 = 261 # 261 Hz MIDDLE C
C4S = 277 # 277 Hz
E4F = 311 # 311 Hz
F4 = 349 # 349 Hz
A4F = 415 # 415 Hz
B4F = 466 # 466 Hz
B4 = 493 # 493 Hz
C5 = 523 # 523 Hz
C5S = 554 # 554 Hz
E5F = 622 # 622 Hz
F5 = 698 # 698 Hz
F5S = 740 # 740 Hz
A5F = 831 # 831 Hz
main.py (Ergänzungen fett gedruckt)
from wifi import init_wifi
import socket
import machine
import time
from constants import *
init_wifi()
# Buzzer
buzzerPIN = 16
BuzzerObj = machine.PWM(machine.Pin(buzzerPIN))
def buzzer(buzzerPinObject, frequency, sound_duration, silence_duration):
# Set duty cycle to a positive value to emit sound from buzzer
buzzerPinObject.duty_u16(int(65536*0.2))
# Set frequency
buzzerPinObject.freq(frequency)
# wait for sound duration
time.sleep(sound_duration)
# Set duty cycle to zero to stop sound
buzzerPinObject.duty_u16(int(65536*0))
# Wait for sound interrumption, if needed
time.sleep(silence_duration)
# Function to load in html page
def get_html(html_name):
# open html_name (index.html), 'r' = read-only as variable 'file'
with open(html_name, 'r') as file:
html = file.read()
return html
# HTTP server with socket
addr = socket.getaddrinfo('0.0.0.0', 80)[0][-1]
s = socket.socket()
s.bind(addr)
s.listen(1)
print('Listening on', addr)
# Listen for connections
while True:
try:
cl, addr = s.accept()
print('Client connected from', addr)
request = cl.recv(1024)
request = str(request)
buzzer_on = request.find('?buzzer=on')
buzzer_off = request.find('?buzzer=off')
buzzer_scale = request.find('?buzzer=scale')
buzzer_music = request.find('?buzzer=music')
if buzzer_on > -1:
BuzzerObj.duty_u16(int(65536*0.2))
BuzzerObj.freq(440)
if buzzer_off > -1:
BuzzerObj.duty_u16(0)
if buzzer_scale > -1:
#C (DO)
buzzer(BuzzerObj, 523, 0.5, 0.1)
#D (RE)
buzzer(BuzzerObj, 587, 0.5, 0.1)
#E (MI)
buzzer(BuzzerObj, 659, 0.5, 0.1)
#F (FA)
buzzer(BuzzerObj, 698, 0.5, 0.1)
#G (SOL)
buzzer(BuzzerObj, 784, 0.5, 0.1)
#A (LA)
buzzer(BuzzerObj, 880, 0.5, 0.1)
#B (SI)
buzzer(BuzzerObj, 987, 0.5, 0.1)
BuzzerObj.deinit()
if buzzer_music > -1:
pause = 0.05
# pauses between notes
t = 0.125
# time that music note plays
music_notes = [B4F, B4F, A4F, A4F,
F5, F5, E5F, B4F, B4F, A4F, A4F, E5F, E5F, C5S, C5, B4F,
C5S, C5S, C5S, C5S,
C5S, E5F, C5, B4F, A4F, A4F, A4F, E5F, C5S,
B4F, B4F, A4F, A4F,
F5, F5, E5F, B4F, B4F, A4F, A4F, A5F, C5, C5S, C5, B4F,
C5S, C5S, C5S, C5S,
C5S, E5F, C5, B4F, A4F, A4F, A4F, E5F, C5S, C5S]
rhythm = [1, 1, 1, 1,
3, 3, 6, 1, 1, 1, 1, 3, 3, 3, 1, 2,
1, 1, 1, 1,
3, 3, 3, 1, 2, 2, 2, 4, 8,
1, 1, 1, 1,
3, 3, 6, 1, 1, 1, 1, 3, 3, 3, 1, 2,
1, 1, 1, 1,
3, 3, 3, 1, 2, 2, 2, 4, 8, 4]
for i in range(len(music_notes)):
buzzer(BuzzerObj, music_notes[i], rhythm[i]*t, pause)
response = get_html('index.html')
cl.send('HTTP/1.0 200 OK\r\nContent-type: text/html\r\n\r\n')
cl.send(response)
cl.close()
except OSError as e:
cl.close()
print('Connection closed')
Wie Sie sehen können, gibt es zwei Arrays, musik_noten und Rhythmus. Sie würden dann eine for-Schleife laufen lassen, um diese Werte in die Buzzer() Funktion. Außerdem importieren wir am Anfang des Codes alle Variablen aus konstanten.py.
Die Buzzer() Funktion verwendet auch zwei neue Variablen - t und Pause. Mit diesen beiden Variablen können Sie das Tempo der Musik abstimmen. t definiert, wie lange jede Note gespielt werden soll und Pause legt fest, wie lange eine Pause zwischen den Noten sein soll.
5. Pico W und HC-SR04 Ultraschallsensor
In den vorherigen Tutorials haben wir den Pico W verwendet, um Befehle an die LEDs und Buzzer zu senden.
Was aber, wenn wir den Pico W zum Empfangen von Informationen verwenden?
In diesem Fall handelt es sich um den HC-SR04 Ultraschall-Abstandssensor.
Wenn Sie Ihren Ultraschallsensor anschließen, stellen Sie sicher, dass Sie wissen, ob es sich um eine 5V- oder 3,3V-Komponente handelt. Ich schloss meine 5V-Version an den 3,3V-Pin an und erhielt keine Antwort vom Programm, was ich weiter unten mitteilen werde. Sobald ich die Stromquelle an den 5V-Pin anschloss, erhielt ich sofort eine Antwort.
Offenbar können einige neuere Versionen des HC-SR04 sowohl 3,3 V als auch 5 V verarbeiten. Vielleicht ist es am besten, zuerst nur den 3,3V-Pin auszuprobieren und zu sehen, ob Sie ein Ergebnis erhalten. Wenn nicht, versuchen Sie die 5V.
Hier ist der Schaltplan und das Programm, das Sie in Thonny ausführen können. Wenn Sie eine Antwort erhalten, bedeutet das, dass Sie alles richtig angeschlossen haben, auch die Spannung.
Verkabelung
Die Verdrahtung der beschrifteten Stifte der HC-SR04-Sensoren ist wie folgt:
- VCC an 3,3V oder 5V Pin (im Zweifelsfall zuerst 3,3 V ausprobieren)
- TRIG an GPIO 16
- ECHO an GPIO 15
- GND an GND
Testprogramm für HC-SR04
Um zu testen, ob Ihre Verdrahtung korrekt ist, versuchen Sie diesen Code, der die Entfernung auf der Thonny Shell ausgibt.
from machine import Pin
import time
trigger = Pin(16, Pin.OUT)
echo = Pin(15, Pin.IN)
def ultrasonic():
trigger.low()
time.sleep_us(1)
trigger.high()
time.sleep_us(10)
trigger.low()
while echo.value() == 0:
signaloff = time.ticks_us()
while echo.value() == 1:
signalon = time.ticks_us()
timepassed = signalon - signaloff
distance = (timepassed * 0.0340) / 2
print("Distance = ",distance,"cm")
while True:
ultrasonic()
time.sleep(1)
Ihre Ausgabe sollte lauten:
Distance = 9.707001 cm
Distance = 9.707001 cm
Distance = 8.619 cm
Distance = 8.415001 cm
Distance = 8.551001 cm
Distance = 8.551001 cm
Distance = 8.619 cm
Wenn das Programm läuft und ohne Ausgabe beendet wird, haben Sie wahrscheinlich etwas falsch verdrahtet. Als ich den Sensor an einen 3,3V-Pin statt an einen 5V-Pin anschloss, beendete das Programm ohne Reaktion.
Abrufen von Daten, die an Ihren Browser gesendet werden
Lassen Sie uns die Dateien, die wir für die Bereitstellung einer Webseite verwendet haben, so ändern, dass wir die Abstandswerte sehen können.
Hier ist der endgültige Code:
main.py
from wifi import init_wifi
import socket
from machine import Pin
import time
init_wifi()
# ultrasonic sensor pins and functions
trigger = Pin(16, Pin.OUT)
echo = Pin(15, Pin.IN)
def ultrasonic():
trigger.low()
time.sleep_us(1)
trigger.high()
time.sleep_us(10)
trigger.low()
while echo.value() == 0:
signaloff = time.ticks_us()
while echo.value() == 1:
signalon = time.ticks_us()
timepassed = signalon - signaloff
distance = (timepassed * 0.0340) / 2
return distance
# Function to load in html page
def get_html(html_name, distance):
# open html_name (index.html), 'r' = read-only as variable 'file'
with open(html_name, 'r') as file:
html = file.read()
content = html.replace(
"<h2 id=\"ultrasonic\"></h2>", f"<h2 id=\"ultrasonic\">{distance}cm</h2>")
return content
# HTTP server with socket
addr = socket.getaddrinfo('0.0.0.0', 80)[0][-1]
s = socket.socket()
s.bind(addr)
s.listen(1)
print('Listening on', addr)
# Listen for connections
while True:
try:
cl, addr = s.accept()
print('Client connected from', addr)
request = cl.recv(1024)
print(ultrasonic())
response = get_html('index.html', ultrasonic())
cl.send('HTTP/1.0 200 OK\r\nContent-type: text/html\r\n\r\n')
cl.send(response)
cl.close()
except OSError as e:
cl.close()
print('Connection closed')
index.html
<!DOCTYPE html>
<html>
<head>
<title>Pico W</title>
</head>
<body>
<h1>Pico W Ultrasonic Distance</h1>
<h2 id="ultrasonic"></h2>
<script>
setInterval(() => location.reload(), 500)
</script>
</html>
Schauen wir uns einige Codeschnipsel an, um zu verstehen, was hier passiert.
Code zur Ermittlung der Ultraschallentfernung
def ultrasonic():
trigger.low()
time.sleep_us(1)
trigger.high()
time.sleep_us(10)
trigger.low()
while echo.value() == 0:
signaloff = time.ticks_us()
while echo.value() == 1:
signalon = time.ticks_us()
timepassed = signalon - signaloff
distance = (timepassed * 0.0340) / 2
return distance
Der obige Codeblock löst die Aussendung einer Ultraschallwelle aus. Die time.sleep zwischen den Tiefst- und Höchstwerten sind für das Funktionieren des Ultraschallsensors erforderlich.
Um zu messen, wie viel Zeit zwischen der Aussendung der Ultraschallwelle und der Rückkehr der Schallwelle vergeht, verwenden wir time.ticks_us um den Zeitpunkt der Aussendung und die Zeit bis zur Erkennung des Echos zu messen.
time.ticks_us ist eine willkürliche Zahl, also müssen wir subtrahieren auf von Signal aus um die Zeit verstreichen zu lassen.
Um die Entfernung zu ermitteln, verwenden wir die Formel Entfernung = (verstrichene Zeit * Geschwindigkeit des Schalls) / 2. Die Schallgeschwindigkeit beträgt 340m/s, also 0,0340.
Der Grund, warum wir sie durch zwei teilen müssen, ist, dass die Schallwelle zum Objekt wandert und wieder zurückkehrt.
Code zur Bereitstellung einer Webseite mit Entfernungsangaben
def get_html(html_name, distance):
# open html_name (index.html), 'r' = read-only as variable 'file'
with open(html_name, 'r') as file:
html = file.read()
content = html.replace(
"<h2 id=\"ultrasonic\"></h2>", f"<h2 id=\"ultrasonic\">{distance}cm</h2>")
return content
...
response = get_html('index.html', ultrasonic())
Diese Funktion wurde im Vergleich zu den vorangegangenen Tutorials ein wenig verändert, indem ein zusätzlicher Parameter aufgenommen wurde Entfernungder läuft ultrasonic().
Die Funktion öffnet die index.html file normally but uses the ersetzen. Methode zum Auffinden der <h2> und fügt die Entfernung variabel.
index.html pingt den Server alle 500ms an, um einen neuen Wert zu erhalten
Die Hauptwebseite erhält eine Funktion, die die Webseite alle 500ms neu lädt. Bei jedem Neuladen wird der Pico W angefunkt, um den neuen Ultraschallentfernungswert zu erhalten.
<script>
setInterval(() => location.reload(), 500)
</script>
6. Ultraschalldaten, aber wir sollten AJAX verwenden, um die Nutzlast zu reduzieren
Das vorherige Tutorial funktioniert so, dass der Raspberry Pi Pico W eine ganz neue index.html Datei jedes Mal, wenn eine Verbindung hergestellt wird.
Das funktioniert, ist aber unglaublich ineffizient, weil die gesamte index.html wird erneut gesendet, wenn Sie nur die Ultraschall-Entfernungsdaten aktualisieren müssen.
Wir wollen die gleichen Ergebnisse wie im vorigen Tutorial, aber ohne die hohe Nutzlast der vorherigen Methode.
Wir müssen also dafür sorgen, dass der Client (Ihr Telefon oder PC) einen Endpunkt anpingt, der nur mit den Ultraschalldaten antwortet.
Die neue Methode sieht folgendermaßen aus: Wenn Besucher die Stamm-URL, z. B. 192.168.1.119, aufrufen, werden sie mit der index.html.
index.html wird JavaScript enthalten, das die /Daten Endpunkt, der den Pico W veranlasst, Ultraschall-Entfernungsdaten abzurufen und mit diesen zu antworten.
Dann, index.html erhält diese Daten und aktualisiert die Webseite.
Spleißen der Anfrage vom Client
Denken Sie daran, dass in der main.pygibt es immer eine Zeile, die besagt Anfragen = cl.recv(1024). Das Request-Objekt sieht in etwa so aus:
b'GET /data HTTP/1.1
Host: 192.168.1.119
Connection: keep-alive
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Referer: http://192.168.1.119/data
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9,es;q=0.8,zh-TW;q=0.7,zh-CN;q=0.6,zh;q=0.5
Zunächst einmal müssen wir diese Textwand herausfiltern.
Wir verwenden die finden() Methode, um herauszufinden, ob die Anfrage Variable "/data" enthält. Wenn ja, antworten Sie mit den Daten der Ultraschallentfernung. Wenn keine "/data" vorhanden ist, antworten Sie mit index.html.
Vor
request = cl.recv(1024)
print(ultrasonic())
response = get_html('index.html', ultrasonic())
Nach
request = cl.recv(1024)
request = str(request)
print (request.find('/data'))
if (request.find('/data') > -1):
#if string is found, respond with data.
response = str(ultrasonic())
else:
response = get_html('index.html', ultrasonic())
Wenn Sie /data in Ihrem Browser aufrufen, sehen Sie den Entfernungswert wie unten dargestellt.
Zuvor wurde fast alles vom Backend erledigt. Die Ultraschallentfernung wurde geändert, bevor sie als index.html bereitgestellt wurde.
Jetzt, index.html die Sensordaten vom Pico W abruft, müssen wir also einige Änderungen am JavaScript in der HTML-Datei vornehmen. Die Änderungen sind fett hervorgehoben.
<!DOCTYPE html>
<html>
<head>
<title>Pico W</title>
</head>
<body>
<h1>Pico W Ultrasonic Distance</h1>
<h2 id="ultrasonic"></h2>
<script>
//instead of hardcoding, use address which browser accessed Pico W.
const PicoAddress = window.location.href
const getData = async () => {
//there is a slash at the end of PicoAddress, so don't use "/data". use "data"
const data = await fetch(`${PicoAddress}data`);
//response is just a string, so use data.text() to decode the Response's body
const distance = await data.text();
//target ultrasonic id and change its inner HTML
ultrasonic.innerHTML = `${distance} cm`;
//run getData() again.
setInterval(getData,100)
//you can run getData() but it seems more optimized if you give it some time to breathe
};
getData();
</script>
</html>
Im Mittelpunkt des Codes steht hier die API abrufen und die neuesten async/await Syntax hier.
Die Funktion getData() pingt den /data-Endpunkt des Pico W an, und der Pico W antwortet. Wir stellen sicher, dass das Programm nicht weiterspringt, bevor wir eine vollständige Antwort erhalten, in der es aufgefordert wird warten Sie.
Fetch wird zu einem Response-Objekt, das Sie mit der Methode Response.text() aufrufen müssen, um den Text der Antwort zu erhalten. Daher die Zeilen const distance = await data.text();
Sobald wir die Ultraschalldaten haben, ändern wir die <h2 id="”ultrasonic”"> Elementes, das zunächst leer ist, mit den Entfernungsdaten. Sie können ein Element mit einer id direkt, ohne Verwendung der getElementById() oder querySelector() Methoden.
Sobald der gesamte Code fertig ist, wollen wir erneut getData() ausführen. Warum habe ich eine setIntervall um ein 100ms-Intervall einzustellen?
Ich habe festgestellt, dass Sie mehr Pausen zwischen den Ausgaben erhalten, wenn Sie getData() ohne Intervall aufrufen. Sie erhalten eine Folge von schnellen Updates, dann eine Pause. Mit den 100ms Atempause, läuft die Pico W ein bisschen besser und Updates scheinen mehr oder weniger Echtzeit noch.
Wenn Sie verstehen wollen, was unter der Haube passiert, lesen Sie die API-Dokumentation abrufen und die async/await Dokumentation.
7. Pimoroni Puh für sauberen Code
Im letzten Abschnitt haben wir die AJAX-Methode zur Aktualisierung der Ultraschallsensordaten behandelt.
Aber gibt es eine noch bessere Möglichkeit, dies zu tun?
Pimoroni's Phew ist eine Bibliothek, die Ihnen hilft, eine Menge von Netzwerken leicht zu tun, weil Sie eine Menge von drugery vermeiden können.
Die Ziele sind die gleichen:
- Abrufen von Ultraschalldaten und deren Anzeige auf index.html
- Halten Sie die Nutzlast so gering wie möglich.
So geht's main.py sieht so aus.
from wifi import init_wifi
from phew import server
from phew.template import render_template
from machine import Pin
import time
init_wifi()
# ultrasonic sensor pins and functions
trigger = Pin(16, Pin.OUT)
echo = Pin(15, Pin.IN)
# Function to load in html page
@server.route("/data", methods=["GET"])
def ultrasonic(request):
trigger.low()
time.sleep_us(1)
trigger.high()
time.sleep_us(10)
trigger.low()
while echo.value() == 0:
signaloff = time.ticks_us()
while echo.value() == 1:
signalon = time.ticks_us()
timepassed = signalon - signaloff
distance = (timepassed * 0.0340) / 2
return str(distance), 200
@server.catchall()
def catchall(request):
return render_template("index.html")
server.run()
Wie Sie sehen können, ist der Code viel lesbarer, da Sie Endpunkte festlegen und mit Funktionen verknüpfen können, die bestimmte Daten zurückgeben.
Statt sich mit Code herumzuschlagen, um die Sockets auszuführen, rufen Sie einfach eine Funktion aus der Bibliothek von Phew auf.
Einige Dinge, die ich an Phew mag, sind:
- Keine Verwendung mehr von request.find() um einen Endpunkt zu erstellen
- Nicht mehr get_html() Funktion zum Öffnen der index.html Datei, verwenden Sie einfach Phews render_template()
- main.py ist viel einfacher zu lesen, mit minimalem zusätzlichem Aufwand!
- Phew fügt außerdem eine Protokollierungsfunktion hinzu, mit der Sie Ihren Code leichter debuggen können.
Der einzige Nachteil ist, dass Phew immer noch "ein sehr neues Projekt ist und bestenfalls als Alphastadium betrachtet werden sollte." Es kann also sein, dass Sie manchmal auf unerwartete Hindernisse stoßen.
In den vorangegangenen Anleitungen wurde beschrieben, wie Sie Ihr Pico W mit Ihrem PC/Mobiltelefon bedienen können.
Gehen wir einen Schritt weiter und bringen den Pico W dazu, mit einem Cloud-Dienst zu interagieren.
Dazu erstellen wir einen Temperatur- und Luftfeuchtigkeitslogger mit einem DHT22-Sensor, der Daten über IFTTT an Google Sheets sendet.
8. Anschluss des Temperatur- und Feuchtigkeitssensors DHT22 an den Pico W
Alle diese Schritte funktionieren für den DHT11 und den DHT22. Der Hauptunterschied zwischen den beiden ist die Genauigkeit der Messwerte. DHT11 hat eine blaue Farbe, während DHT22 weiß ist.
Wenn Sie einen DHT11 haben, beachten Sie, dass Verweise auf den DHT22 im Code in DHT11 geändert werden sollten. Zum Beispiel,
import dht
#dht22 = dht.DHT22(Pin(16))
#should be
dht11 = dht.DHT11(Pin(16))
Wenn Sie sich das Diagramm unten ansehen, würden Sie von oben nach unten des DHT22 3,3 V an den ersten Pin anschließen.
Der zweite Pin ist der Datenpin. Sie müssen ihn mit Strom versorgen. Schließen Sie also einen 10K-Ohm-Widerstand von der Stromschiene an ihn an, und verbinden Sie dann einen weiteren Jumper-Draht mit GPIO 16 auf dem Raspberry Pi Pico.
GND geht an GND.
Um den Sensor zu testen, führen Sie Folgendes aus:
from machine import Pin
import dht
# ultrasonic sensor pins and functions
dht22 = dht.DHT22(Pin(16))
print(dht22.measure())
print(dht22.temperature())
print(dht22.humidity())
Wenn Sie OSError: [Errno 110] ETIMEDOUT bedeutet, dass Sie das Skript zu früh ausführen. Der DHT22 benötigt eine Pause von zwei Sekunden, bevor er einen anderen Wert zurückgeben kann. DHT11 benötigt eine Sekunde.
IFTTT und Google Sheets miteinander verbinden
Der einfachste Weg, Daten vom Pico W zu Google Sheets zu übertragen, ist über IFTTT.
Erstens, IFTTT-Konto einrichten.
Klicken Sie dann auf die Schaltfläche "Erstellen", um das Applet zu erstellen.
Sie sehen dann diesen Bildschirm:
Klicken Sie auf "Wenn dies" und suchen Sie nach Webhooks. Klicken Sie auf "Webanforderung empfangen". Wählen Sie nicht die JSON-Anfrage. Geben Sie dem Ereignis den Namen "dht22". Der Ereignisname ist entscheidend, denn so weiß IFTTT, welches Applet ausgelöst werden soll.
Was Sie hier tun, ist einen Endpunkt zu erstellen, den Sie mit den Sensordaten des DHT22 anpingen können.
Klicken Sie dann auf "Dann das". Wählen Sie "Google Sheets". Wählen Sie dann "Zeile zum Arbeitsblatt hinzufügen". Sie müssen Ihr Google Sheets-Konto verknüpfen.
Ändern Sie den "Spreadsheet name" und den "Drive folder path" auf die von Ihnen gewünschten Werte. Das einzige, was hier wichtig ist, ist die "Formatierte Zeile", die wie folgt lauten soll
{{OccurredAt}} ||| {{Value1}} ||| {{Value2}}
Nun müssen Sie den Endpunkt ermitteln, an den der Pico W Sensordaten senden kann.
Kopf nach https://ifttt.com/maker_webhooks und klicken Sie auf "Dokumentation".
In der Dokumentation finden Sie Ihren Schlüssel, den Endpunkt, an den Sie Daten senden müssen, und die Struktur des JSON-Bodys.
Da Sie "dht22" als Ereignisnamen verwendet haben, lautet Ihr Endpunkt:
ttps://maker.ifttt.com/trigger/dht22/with/key/[your_key_here]
Außerdem sollten Sie Ihren JSON-Körper wie folgt strukturieren:
{'value1': *** temperature data *** , value2': *** humidity data *** }
Codierung des Pico W, um DHT22-Daten zu erhalten und an IFTTT zu senden
So geht's.
from machine import Pin
from wifi import init_wifi
import urequests
import ujson
import dht
import time
init_wifi()
dht22 = dht.DHT22(Pin(16))
def send_data():
#tell dht22 to take a reading
dht22.measure()
#find temp & humidity data and then jsonify data.
dht_data = {'value1': str(dht22.temperature()),
'value2': str(dht22.humidity())}
post_data = ujson.dumps(dht_data)
request_url = 'https://maker.ifttt.com/trigger/dht22/with/key/[your_key_here]'
res = urequests.post(request_url, headers={
'content-type': 'application/json'}, data=post_data)
#log response from IFTTT.
print(res.text)
#sleep for a minute before running send_data again
time.sleep(1*60)
send_data()
send_data()
Wenn Sie diesen Code kopieren wollen, ersetzen Sie bitte [your_key_here] in der anfrage_url variabel.
Sie sollten jede Minute einen neuen Messwert erhalten, der in Google Sheet protokolliert wird (siehe unten).
Beachten Sie, dass die Temperatur in Celcius angegeben wird. Wenn Sie sie in Fahrenheit angeben möchten, finden Sie hier die Formel:
fahrenheit = dht22.temperature() * 1.8000 + 32.00
Wenn Sie möchten, dass die Daten häufiger (oder weniger häufig) protokolliert werden, ändern Sie den Wert in time.sleep().
Verwenden Sie IFTTT, um Sie bei einem Fehler zu benachrichtigen
Natürlich ist dieser Code noch recht anfällig.
Nehmen wir an, etwas geht schief. Zum Beispiel hat Ihre Katze das 3,3-V-Jumper-Kabel gezogen, während Sie sich auf den Boden gelegt haben, um die Temperatur zu messen.
Das Programm wird beendet, aber Sie erhalten keine Benachrichtigung, bis Sie feststellen, dass Ihre Daten nicht protokolliert werden.
Wie lösen Sie das Problem?
Dann lassen Sie sich von IFTTT benachrichtigen, wenn das passiert!
Sie benötigen die IFTTT-App auf Ihrem Telefon. Also laden Sie sie herunter.
Dann würden Sie ein neues Applet erstellen.
Für die "Wenn dies" Teil, Wählen Sie Webhooks -> Empfangen einer Webanfrage. Nennen Sie Ihr Ereignis "Fehler".
Für die "Dann dies" Teil, wählen Sie "Benachrichtigungen" und "Eine Benachrichtigung von der IFTTT-App aus senden".
Ich habe die Nachricht einfach gehalten
Error: {{Value1}}
Bauen wir nun die try-error-Blöcke auf.
from machine import Pin
from wifi import init_wifi
import urequests
import ujson
import dht
import time
init_wifi()
dht22 = dht.DHT22(Pin(16))
def send_data():
# tell dht22 to take a reading
dht22.measure()
# find temp & humidity data and then jsonify data.
dht_data = {'value1': str(dht22.temperature()),
'value2': str(dht22.humidity())}
post_data = ujson.dumps(dht_data)
request_url = 'https://maker.ifttt.com/trigger/dht22/with/key/[your-key-here]'
res = urequests.post(request_url, headers={
'content-type': 'application/json'}, data=post_data)
# log response from IFTTT.
print(res.text)
# sleep for a minute before running send_data again
time.sleep(1*60)
send_data()
try:
send_data()
except Exception as e:
print(e)
request_url = 'https://maker.ifttt.com/trigger/error/with/key/[your-key-here]'
post_data = ujson.dumps({"value1": str(e)})
urequests.post(request_url, headers={
'content-type': 'application/json'}, data=post_data)
Probieren Sie es aus. Ziehen Sie das 3,3-V-Kabel von Ihrem DHT22 ab und Sie erhalten eine entsprechende Meldung:
9. Bau einer physischen Spotify-Fernbedienung mit dem Raspberry Pi Pico W
Aufbauend auf dem vorherigen Projekt werden wir IFTTT verwenden, um Spotify zu steuern.
Wir werden ein Gerät erstellen, das über eine Taste zum Abspielen, Anhalten und Überspringen von Titeln verfügt.
Der Hauptvorteil der Verwendung von IFTTT zur Steuerung von Spotify liegt in der Einfachheit der Anwendung.
Der Nachteil ist, dass Sie ein kostenpflichtiges Spotify-Konto benötigen und die Reaktionen langsam sind. Das heißt, wenn Sie die Skip-Taste drücken, müssen Sie eine Weile warten, bevor Sie das Ergebnis sehen.
Das Schöne an einer speziellen Spotify-Fernbedienung ist, dass Sie Ihre Musik ändern können, ohne Ihr Telefon mit sich herumtragen oder die Spotify-App öffnen zu müssen.
Wenn Sie schon einmal ein modernes Auto gefahren sind, werden Sie wissen, wie angenehm es ist, Bedienelemente am Lenkrad zu haben.
Verkabelung einer Spotify-Fernsteuerung
Sie brauchen...
- 7x Überbrückungsdrähte
- 3x Tasten
- Raspberry Pi Pico W
- Bezahltes Spotify-Konto
Auf dem Bild kreuzen sich viele Drähte, deshalb hier eine Erklärung in Textform.
Die Drucktasten sind wie Schalter. Sie müssen den 3V3-Pin mit jedem von ihnen verbinden, was bedeutet, die positive Spalte auf dem Breadboard zu verwenden. Daher:
3V3 -> Breadboard positive Spalte -> Taster (auf einer Seite der Breadboard-Rinne) -> GPIO (auf der anderen Seite)
Mein Code wird GPIO 16 für die Play-Taste, GPIO 2 für die Pause-Taste und GPIO 15 für die Skip-Track-Taste verwenden.
Einrichten von IFTTT zur Steuerung von Spotify
Wir müssen drei Applets erstellen, jeweils eines für die Funktionen Abspielen, Pause und Überspringen.
Wenn Sie die Premium-Version von IFTTT haben, können Sie wahrscheinlich die JavaScript-Filter verwenden, um alles in einer App zusammenzufassen. Aber da wir das nicht tun, brauchen wir jeweils ein Applet.
Wenn Sie angemeldet sind, klicken Sie oben rechts im Hauptmenü auf "Erstellen".
Klicken Sie auf die Leiste "Wenn dies" und suchen Sie nach Webhooks.
Klicken Sie dann auf "Receive a web request" (nicht auf die andere Option mit "with a JSON payload").
Für den Ereignisnamen geben Sie ein spotify_skip.
Sie müssen diesen Schritt noch zwei weitere Male wiederholen, um spotify_pause und spotify_play sobald Sie dieses Applet fertig erstellt haben.
Sobald das erledigt ist, gehen Sie zum Menüpunkt "Dann ist das"Leiste und klicken Sie sie an. Suchen Sie nach "Spotify".
Sie müssen IFTTT einmalig autorisieren, sich mit Spotify zu verbinden.
Wenn Sie die spotify_skip Aktion auszuführen, sollten Sie auf "Titel überspringen" klicken. Wenn Sie jedoch ein Applet für eine andere Aktion verwenden, zeigt Ihnen das obige Bild, welche Aktion Sie verwenden müssen.
Sobald Sie alle drei Applets erstellt haben, können Sie mit dem Programmieren beginnen!
Codierung der Spotify-Fernbedienung für den Pico W
Zunächst müssen Sie den Endpunkt kennen, den Sie erreichen müssen.
Gehen Sie zu dieser Seite und klicken Sie auf das Dokumentation.
Dort sehen Sie Ihren Schlüssel. Wenn Sie alle oben genannten Schritte befolgt haben, ist der Unterschied zwischen Ihrem und meinem Endpunkt Ihr Schlüssel. Daraus folgt,
Endpunkt abspielen: https://maker.ifttt.com/trigger/spotify_play/with/key/[your_key_here]
Pause: https://maker.ifttt.com/trigger/spotify_pause/with/key/[your_key_here]
Überspringen: https://maker.ifttt.com/trigger/spotify_skip/with/key/[your_key_here]
Code
from machine import Pin
from wifi import init_wifi
import urequests
import time
init_wifi()
play_btn = Pin(16, Pin.IN, Pin.PULL_DOWN)
pause_btn = Pin(2, Pin.IN, Pin.PULL_DOWN)
skip_btn = Pin(15, Pin.IN, Pin.PULL_DOWN)
def play():
request_url = 'https://maker.ifttt.com/trigger/spotify_play/with/key/[your_key_here]'
res = urequests.post(request_url)
# print response from IFTTT.
print(res.text)
def pause():
request_url = 'https://maker.ifttt.com/trigger/spotify_pause/with/key/[your_key_here]'
res = urequests.post(request_url)
# print response from IFTTT.
print(res.text)
def skip():
request_url = 'https://maker.ifttt.com/trigger/spotify_skip/with/key/[your_key_here]'
res = urequests.post(request_url)
# print response from IFTTT.
print(res.text)
try:
while True:
if play_btn():
print('play btn')
play()
time.sleep(0.25)
if pause_btn():
print('pause btn')
pause()
time.sleep(0.25)
if skip_btn():
skip()
print('skip')
time.sleep(0.25)
except Exception as e:
print(e)
request_url = 'https://maker.ifttt.com/trigger/error/with/key/[your_key_here]'
post_data = ujson.dumps({"value1": str(e)})
urequests.post(request_url, headers={
'content-type': 'application/json'}, data=post_data)
Schauen wir uns den Code an.
Beachten Sie, dass Sie Folgendes ersetzen müssen [your_key_here] mit Ihrem echten Schlüssel, den Sie über die Dokumentation Link.
Zunächst deklarieren wir Variablen für die Drucktasten.
play_btn = Pin(16, Pin.IN, Pin.PULL_DOWN)
pause_btn = Pin(2, Pin.IN, Pin.PULL_DOWN)
skip_btn = Pin(15, Pin.IN, Pin.PULL_DOWN)
Wenn Sie die Taste nicht drücken, hat Ihre Variable derzeit den Wert 0. Wenn Sie ihn drücken, wird er 1. Damit lösen wir das Programm abspielen() , pause() und Überspringen() Funktionen.
Dann erstellen wir Funktionen für die Endpunkte Wiedergabe, Pause und Überspringen. Die allgemeine Vorlage sieht folgendermaßen aus:
def play():
request_url = 'https://maker.ifttt.com/trigger/spotify_play/with/key/[your_key_here]'
res = urequests.post(request_url)
# print response from IFTTT.
print(res.text)
Es ist ziemlich einfach. Wenn diese Funktion ausgeführt wird, wird sie eine POST-Anfrage an IFTTT senden. Das Senden einer GET-Anfrage wird nicht funktionieren.
Dann kommt der try/except-Block.
try:
while True:
if play_btn():
print('play btn')
play()
time.sleep(0.25)
if pause_btn():
print('pause btn')
pause()
time.sleep(0.25)
if skip_btn():
skip()
print('skip')
time.sleep(0.25)
except Exception as e:
print(e)
request_url = 'https://maker.ifttt.com/trigger/error/with/key/[your_key_here]'
post_data = ujson.dumps({"value1": str(e)})
urequests.post(request_url, headers={
'content-type': 'application/json'}, data=post_data)
Wenn eine Taste gedrückt wird, führt der Code die entsprechende Funktion aus. Wenn Sie zum Beispiel die Taste "Überspringen" drücken, wird die Funktion Überspringen().
A time.sleep(0.25) hält die Funktion für 250ms an. Ohne diese Funktion kann selbst ein kurzer Druck den Pico W überlasten und zum Absturz bringen.
Die außer Block ist optional, aber ich habe ihn verwendet, weil ich bereits ein "Fehler"-Applet auf IFTTT hatte. Wenn Sie das vorherige Tutorial verfolgt haben, haben Sie es vielleicht schon benutzt.
Im Grunde wird die Fehlermeldung gesendet, ezu IFTTT, damit Sie die Fehlermeldung als Benachrichtigung der Telefon-App erhalten.
Warum funktioniert es nicht?
Die Verwendung von IFTTT als Medium zur Steuerung von Spotify ist einfach, hat aber auch einige Nachteile.
Sie müssen die Musik zuerst auf die normale Weise starten
Wenn Sie versucht haben, die Wiedergabetaste auf Ihrem Pico W zu drücken und erwartet haben, dass die Musikwiedergabe beginnt... nun, es passiert nichts.
Die Lösung ist, die Musik auf Ihrem Computer oder Telefon normal zu starten. Sie müssen zu Ihrer App gehen und auf "Play" drücken.
Ich glaube, damit wird festgelegt, welches Gerät das aktive Gerät ist. Sobald Sie dies getan haben, können Sie Ihre Pico W Spotify-Fernbedienung verwenden.
Langsame Antworten
Zwischen Tastendruck und Reaktion vergehen ein paar Sekunden. Leider ist das nun einmal so.
Sie könnten für ein IFTTT-Upgrade bezahlen, um schnellere Reaktionszeiten zu erhalten. Zumindest ist es das, was sie für Ihr Geld versprechen.
Gibt es eine direkte Möglichkeit, Spotify zu verbinden?
Ja! Spotify hat eine API, mit der Sie sich verbinden können.
Damit haben Sie wesentlich mehr Kontrolle. Sie könnten einen Drehgeber zur Steuerung der Lautstärke hinzufügen. Sie können einen LCD-Bildschirm hinzufügen, um anzuzeigen, was abgespielt wird. Sehen Sie sich die Spotify-Konsole hier an.
Erstaunlich, aber auch viel schwieriger zu programmieren, besonders auf einem Pico W.
IFTTT macht alles ganz einfach, weil es die ganze Arbeit übernimmt. Wenn Sie die schwere Arbeit übernehmen möchten, sollten Sie sich den Authentifizierungsablauf ansehen.
Natürlich sind wir Raspberry Pi-Enthusiasten. Irgendjemand da draußen wird es tun. Sollten Sie das sein? Oder ich? Kommentieren Sie unten.
Steuern Sie Ihren Pico W drahtlos mit PiCockpit!
Mit PiCockpit können Sie Ihren Pico W drahtlos steuern und Daten von ihm abrufen.
PiCockpit ermöglicht es Ihnen, Werte zu erhalten, zu steuern und PWM durch eine GUI über sein GPIO-Applet zu verwenden.
Sie können die Statistiken Ihres Pico W auch über das PiStats-Applet einsehen.
Die Integration von PiCockpit in Ihren Pico W ist denkbar einfach.
Noch weniger Code schreiben mit PiCockpit und dem Pico W
PiCockpit macht es Ihnen leicht, Ihre GPIO-Pins zu steuern, ohne Code schreiben zu müssen.
Wenn Sie sich Lehrgang Nummer 2Beachten Sie, wie viel Code nötig ist, nur um eine LED umzuschalten.
Mit unserer neuen Pico W-Integration macht PiCockpit alles viel einfacher, denn Sie müssen überhaupt nichts mehr programmieren. Nicht einmal die WiFi-Konfiguration - die wird mit unserem Einrichtungsassistenten erledigt.
10. Einfache LED-Ansteuerung mit PiCockpit und Pico W
Wenn Sie Ihre LED genau so konfiguriert haben, wie ich es in Tutorial Nr. 2 getan habe, dann müssen Sie sie nur noch in PiCockpit einrichten.
Wenn Sie es kodieren, geben Sie an, an welchem Pin die LED leuchtet, indem Sie led = machine.Pin(2, machine.Pin.OUT)
Auf PiCockpit gehen Sie zu Ihrem GPIO-Applet und scrollen Sie zu "GPIO Output (On/Off)".
Wählen Sie BCM02 aus dem Dropdown-Menü, da Ihre LED an GPIO 2 angeschlossen ist.
Schalten Sie dann in der Spalte "Steuerung" den Schalter um, um die LED einzuschalten.
Sie können auch ganz einfach die Software-PWM-Sektion unten verwenden, um die Helligkeit Ihrer LED zu steuern.
Beachten Sie, dass Sie die vorherige Einstellung entfernen müssen, da Sie nicht zwei Ausgänge auf demselben GPIO haben können.
Wenn Sie den Schieberegler "Steuerung" bewegen, werden Sie feststellen, dass sich die Helligkeit der LED ändert.
11. Pico W, 5V Lüfter und ein Transistor, gesteuert von PiCockpit
Versuchen wir es mit etwas umfassenderem, aber mit demselben GPIO-Ausgangstoggle.
Um einige reale Anwendungsfälle zu illustrieren, werde ich einen 5V-Lüfter mit PiCockpit betreiben.
Es handelt sich um einen 5-V-Lüfter mit geringer Leistung, der von meinem Raspberry Pi 4 stammt, also durchaus im Rahmen der Leistungsmöglichkeiten des Raspberry Pi Pico W liegt.
Da es sich jedoch um einen 5-V-Lüfter handelt, kann ich keinen GPIO-Pin verwenden. Bei weniger stromintensiven Komponenten, wie einer LED, kann der GPIO die doppelte Aufgabe übernehmen, die Komponente mit Strom zu versorgen und der "Schalter" zu sein, der sie ein- und ausschaltet.
Aber der 5-V-Lüfter würde eine zu hohe Spannung erfordern. Die nächstbeste Möglichkeit ist also, einen Transistor in die Mitte zu setzen.
So kann ich den Lüfter mit 5 V versorgen und gleichzeitig sicherstellen, dass ich ihn ein- und ausschalten kann.
Wieder einmal habe ich dank PiCockpit keine Programmierung vorgenommen. Ich habe nur die Hardware, die wie folgt verdrahtet ist:
Der Lüfter ist ein 5V/0,12A-Lüfter, der am positiven Ende (roter Draht) an 5V angeschlossen ist, und der negative Draht geht an den Emitterzweig des Transistors.
Der Transistor ist ein PN2222 (NPN)-Transistor, d. h. er schaltet ein, wenn er ein hohes Signal empfängt.
Von links nach rechts, wobei der halbkreisförmige Teil von Ihnen weg zeigt, sind die Beine der Emitter, die Basis und der Collector.
Das Basisbein wird mit einem 1K-Widerstand verbunden und dann an GPIO 15 angeschlossen.
Das Kollektorbeinchen ist mit Masse verbunden.
PiCockpit für die Arbeit mit Transistor konfigurieren
Noch einmal: super einfach.
Gehen Sie zum Dropdown-Menü im Abschnitt GPIO-Ausgang und fügen Sie BCM15 hinzu.
Danach können Sie auf den Pfeil nach unten klicken und die Statusnamen in "Lüfter aus" und "Lüfter ein" ändern.
Schalten Sie den Kontrollschalter um, und Sie sollten sehen, dass sich der Ventilator einschaltet.
Sie können auch PiStats verwenden, um den Temperaturabfall auf Ihrem Board zu sehen.
Anzeige von Fotowiderständen mit MQTT und Node-RED mit Pico W.
Das Hauptziel dieses Tutorials ist die Einführung in MQTT.
In den vorangegangenen Tutorials habe ich Ihnen gezeigt, wie Sie Ihren Pico W zur Bereitstellung von Daten verwenden können, aber was, wenn Sie einen zentralen Datenspeicher in der Cloud wünschen?
HiveMQ Cloud ist ein kostenloser Dienst, den wir zur Erreichung dieses Ziels nutzen können. Indem wir die Computer anderer Leute nutzen, können wir auch den Pico W entlasten.
Hinzu kommt, dass MQTT im Vergleich zu den bisher verwendeten Methoden große Vorteile hat. Zum einen ist es viel effizienter beim Senden kleiner Daten. Die Header des MQTT-Protokolls sind 2 Byte groß. HTTP ist etwa 4000 Mal größer.
Die Verringerung der lokalen Verarbeitungslast und der Netzwerklast bedeutet eine längere Batterielebensdauer für Ihren Pico W, was perfekt für batterie- oder solarbetriebene Projekte ist.
Anschluss eines Fotowiderstands an den Pico W
Ein Fotowiderstand (Fotozelle) lässt sich sehr einfach anschließen.
Legen Sie den Fotowiderstand quer über die Mittelrinne der Lochrasterplatte.
Verbinden Sie dann den Stift 3V3 mit einer Seite des Fotowiderstands.
Sie werden einen ADC-Pin an die andere Seite des Fotowiderstands anschließen wollen, also verbinden Sie GPIO 26.
Schließen Sie schließlich einen 10-kOhm-Widerstand von der Masse zur Fotozelle an.
HiveMQ Cloud und Codierung des Pico W
Der erste, Melden Sie sich hier für HiveMQ Cloud an.
Gehen Sie durch die Einrichtung und erstellen Sie einen Cluster. Sie werden gefragt, ob Sie AWS oder Azure wählen möchten. Für unsere Zwecke gibt es keinen Unterschied.
Klicken Sie dann auf "Cluster verwalten".
Notieren Sie sich Ihre Cluster-URL und klicken Sie auf Access Management, um einen neuen Benutzer anzulegen. Gehen Sie die Schritte durch und erstellen Sie einen neuen Benutzer.
Mit diesen Angaben können Sie nun Ihren Pico W so programmieren, dass er Daten dorthin sendet.
Codierung des Pico W für den Empfang von Fotozellendaten und MQTTClient
from machine import Pin, ADC
from wifi import init_wifi
import time
from umqtt.simple import MQTTClient
init_wifi()
photoresistor = ADC(Pin(26))
def readLight():
light = photoresistor.read_u16()
return light
# Connect MQTT
def connectMQTT():
client = MQTTClient(client_id=b"[your_client_id]",
server=b"[your-host-name]",
port=0,
user=b"[your-user]",
password=b"[your-pw]",
keepalive=7200,
ssl=True,
ssl_params={
'server_hostname': '[your-host-name]'}
)
client.connect()
return client
client = connectMQTT()
def publish(topic, value):
print(topic)
print(value)
client.publish(topic, value)
print("data published")
while True:
brightness = str(readLight()) #to publish, must send string
print(brightness)
publish('picow/brightness', brightness)
time.sleep(0.1)
Lassen Sie uns zunächst unsere Importe in Ordnung bringen.
from machine import Pin, ADC
from wifi import init_wifi
import time
from umqtt.simple import MQTTClient
Die wifi
Import stammt aus den vorherigen Tutorials.
Sie benötigen die Bibliothek umqtt.simple, die kann hier heruntergeladen werden.
Sobald das heruntergeladen ist, können Sie es auf Ihr Board hochladen (Leitfaden hier).
Sie sollten diese Dateien auf Ihrem Pico W haben.
Erstellen Sie dann eine Funktion, um einen Messwert vom Fotowiderstand zu erhalten:
photoresistor = ADC(Pin(26))
def readLight():
light = photoresistor.read_u16()
return light
Dies gibt einen Wert bis zu 65535 zurück. Je heller er ist, desto höher ist der Wert.
Verbinden mit HiveMQ
Um eine Verbindung zu HiveMQ herzustellen, müssen Sie einige Parameter an die MQTTClient-Klasse senden.
# Connect MQTT
def connectMQTT():
client = MQTTClient(client_id=b"[your_client_id]",
server=b"[your-host-name]",
port=0,
user=b"[your-user]",
password=b"[your-pw]",
keepalive=7200,
ssl=True,
ssl_params={
'server_hostname': '[your-host-name]'}
)
client.connect()
return client
client = connectMQTT()
Ersetzen Sie [Ihr-Host-Name] durch die Adresse, die Sie in Ihrem Dashboard finden. Sie müssen dies zweimal tun, einmal für server
und eine weitere für server_hostname
. Ersetzen Sie außerdem [your_client_id] durch einen Namen für Ihr Gerät, z. B. "your_picow".
Ersetzen Sie dann [your-user]
und [your-pw]
mit dem Benutzer, den Sie auf der Seite Zugangsverwaltung erstellt haben (siehe Screenshot der Seite Zugangsverwaltung unten).
Als Referenz sendet diese Funktion Daten an HiveMQ:
def publish(topic, value):
print(topic)
print(value)
client.publish(topic, value)
print("data published")
Nennen wir es in unserem while
Schleife:
while True:
brightness = str(readLight()) #to publish, must send string
print(brightness)
publish('picow/brightness', brightness)
time.sleep(0.1)
Bei der Veröffentlichung müssen Sie Zeichenketten senden, weshalb brightness = str(readLight())
ist da.
Wenn Sie Ganzzahlen oder Fließkommazahlen senden, wird das Programm sterben.
In der Veröffentlichungsfunktion geben Sie Ihrem Thema einen Namen. Sagen Sie, picow/brightness
und fügen Sie dann den Wert hinzu, den Sie senden möchten. In diesem Fall wollen wir den stringifizierten Lichtwert senden, brightness
.
Sie sollten die veröffentlichten Daten sehen können, wenn Sie sich auf der Registerkarte Web Client anmelden.
Node-RED
Das sind nur Zahlen, die online stehen und wie Kauderwelsch erscheinen mögen. Was wäre, wenn Sie auf die Daten in der HiveMQ Cloud zugreifen und sie grafisch darstellen wollten?
Anstatt Ihre eigene Software zu entwickeln, könnten Sie einfach Node-RED verwenden.
Node-RED macht es Ihnen sehr einfach, Daten aus HiveMQ zu übernehmen und sie dann in grafischer Form darzustellen.
Wir werden ein Messgerät mit Node-RED erstellen.
Für den Anfang benötigen Sie nodejs. Prüfen Sie die Dokumentation von HiveMQ um zu sehen, welche Version empfohlen wird.
Sobald Sie Node installiert haben, müssen Sie eine Eingabeaufforderung/Terminal öffnen und diese Befehle ausführen (schließen Sie sudo aus, wenn Sie unter Windows arbeiten):
sudo npm install -g --unsafe-perm node-red
Dies wird den Node Package Manager (npm) verwenden, um Node-RED global zu installieren.
Starten Sie dann Node-RED durch Eingabe von node-red
in die Terminal-/Befehlszeile ein.
Öffnen Sie Ihren Browser und gehen Sie zu http://127.0.0.1:1880 oder die Adresse, die in Ihrem Terminal angegeben ist.
Bauen wir den Fluss auf. Ziehen Sie ein "mqtt in" auf die Leinwand. Sie finden es unter der Registerkarte "Netzwerk" in der linken Seitenleiste.
Wir müssen die Registerkarte konfigurieren, also doppelklicken Sie auf das Rechteck und führen Sie folgende Schritte aus:
Fügen Sie im Feld "Thema" Folgendes hinzu Bild/Helligkeitdenn das ist es, was Sie vom Pico W veröffentlicht haben.
Fügen Sie unter "Server" einen neuen hinzu, indem Sie auf das Stiftsymbol klicken, und Sie gelangen zum nächsten Menü.
Geben Sie eine neue Serveradresse ein und ändern Sie den Port auf 8883. Markieren Sie "TLS verwenden", aber machen Sie sich nicht die Mühe, eine neue tls-config hinzuzufügen.
Gehen Sie dann auf die Registerkarte Sicherheit und geben Sie Ihre Anmeldedaten ein.
Alle diese Details finden Sie in Ihrem Code, wenn Sie den MQTTClient initialisieren.
Hinzufügen eines Messgeräts
Um ein Messgerät hinzuzufügen, müssen Sie die node-red-dashboard.
In der linken Seitenleiste, falls Sie diese nicht sehen:
Gehen Sie dann zum Menü (Schaltfläche oben rechts) -> Palette verwalten. Gehen Sie dann auf die Registerkarte "Installieren" und suchen Sie nach "node-red-dashboard". Klicken Sie auf "Installieren".
Ziehen Sie ein "Messgerät" auf die rechte Seite des Feldes mqtt in Rechteck, und verbinden Sie sie durch Ziehen einer Linie von mqtt in zum Messgerät.
Doppelklicken Sie auf das Messgeräte-Rechteck und ändern Sie die Beschriftung in "Helligkeit" und den "Bereich" auf maximal 65535.
Sehr gut. Drücken wir jetzt auf "Bereitstellen".
Wenn Ihre Einstellungen korrekt waren, sehen Sie einen grünen Kreis und "connected" unter dem Rechteck. Ist dies nicht der Fall, gibt Ihnen Ihr Terminal nähere Informationen über die Ursache des Fehlers.
Nachdem Ihr Pico W Daten an die HiveMQ Cloud geliefert hat, ist es nun an der Zeit, das Dashboard zu überprüfen. Besuchen Sie http://127.0.0.1:1880/ui und Sie sollten sehen, dass die Anzeige regelmäßig aktualisiert wird.
Ihre Vorschläge sind willkommen.
Hinterlassen Sie einen Kommentar in der Kommentarbox unten!
Hallo,
Danke, dass Sie Ihr Wissen mit uns teilen.
Könnten Sie mir sagen, ob die WiFi-Übungen nur für das eigene Netzwerk gelten? Ich konnte nicht auf den Pico W zugreifen, wenn ich mich in einem anderen WiFi-Netzwerk befand. Wenn ja, haben Sie Beispiele für den Zugriff außerhalb des Netzwerks?
Ich danke Ihnen.
Ja, aufgrund der Natur von Netzwerken, Routern und Firewalls funktionieren diese Übungen nur innerhalb desselben WiFi-Netzwerks.
PiCockpit selbst ist eine netzwerkübergreifende Lösung - Sie können von überall im Internet auf Ihren Pico W zugreifen.
Wir arbeiten daran, weitere Funktionen auf die Plattform zu bringen.
Wenn Sie so etwas selbst nachbauen wollen, benötigen Sie eine Art Tunneling-Lösung für Ihr Netzwerk oder einen Relay-Server oder etwas Ähnliches.
Wir bieten Beratungsdienste an, wenn Sie sich eingehender mit diesem Thema befassen möchten.
Vielen Dank für diese tolle Anleitung.
Leider funktioniert das nicht.
Ich bleibe am Ende des Teils "1. eine Webseite mit dem Text "Hello World" auf dem Pico anzeigen" hängen.
Meine Webbrowser Firefox und Chrome melden mir nur "Fehler Verbindung unterbrochen".
In Thonny sehe ich
Verbunden
ip = 192.168.188.198
Abhören von ('0.0.0.0', 80)
Client verbunden von ('192.168.188.100', 54025)
Verbindung geschlossen
Verbindung geschlossen kommt ein paar Mal.
Was kann ich ändern, damit mein Pico W funktioniert?
Ich danke Ihnen im Voraus für Ihre Hilfe.
Mit freundlichen Grüßen Pete
Wenn ich main.py ausführe, gibt es eine Fehlermeldung, wie kann ich sie beheben.
Datei "", Zeile 1, in
ImportError: kein Modul namens 'wifi'
Ich danke Ihnen im Voraus.
Sie müssen die Datei wifi.py erstellen und hinzufügen, die etwas weiter oben auf der Seite angezeigt wird. Ohne wifi.py wird der Code nicht funktionieren.
Das "Raspberry Pi Pico W beginners' components tutorial" ist ein fantastischer Leitfaden für alle, die neu auf der Raspberry Pi Pico W Plattform sind. Das Tutorial ist gut strukturiert und einfach zu folgen, wodurch es ideal für Anfänger ist. Es deckt die wichtigsten Komponenten ab und bietet klare Anweisungen, was es zu einem großartigen Ausgangspunkt für jeden macht, der diese Technologie erkunden möchte. Detaillierte Erklärungen und Bilder erhöhen den Lerneffekt und sorgen dafür, dass der Leser die Konzepte schnell begreift. Insgesamt ist dieses Tutorial eine wertvolle Ressource für alle, die mit dem Raspberry Pi Pico W und seinen Komponenten beginnen möchten.