Raspberry Pi Pico W - handledning för nybörjare om komponenter

hallon pi pico w komponenter handledning

I den här handledningen för Raspberry Pi Pico W-komponenter för nybörjare lär du dig hur du interagerar med mikrokontrollern för att interagera med enkla komponenter som lysdioder, ultraljudssensorer och många andra saker som finns i ett nybörjarkit.

Om du är helt nybörjare kommer denna handledning att hjälpa dig att förstå MicroPython så att du kan läsa, skriva och modifiera kod. Med denna kunskap kan du kombinera kod och komponenter för att skapa något som har ett verkligt användningsfall.

Om du kommer från en Pico kommer du i den här handledningen att lära dig hur du styr Pico W trådlöst. Tidigare kunde du bara interagera med Pico via en strömbrytare, knapp eller någon annan fysisk interaktionsenhet. Så är det inte längre! Du kan nu styra komponenterna med din telefon eller skrivbord.

Självstudie flöde

Introduktion

  1. Lödning av sidhuvudstift
  2. Använda Thonny
  3. Uppdatering av din firmware

Hello World-handledning för Pico W

  1. Visa en webbsida som säger "Hello World" på Pico
  2. Trådlös styrning av en LED

Ett steg upp

  1. Styr RGB LED trådlöst
  2. Summerfunktion på Pico W

Grundläggande sätt att överföra data från sensorn

  1. Pico W och HC-SR04 ultraljudssensor
  2. Sänd en webbsida med sensordata
  3. Minska nyttolasten med AJAX
  4. Pimoroni Phew effektiviserar kodning av endpoint

Ansluta till webbverktyg

  1. Logga klimatdata från DHT22-sensorn till Google Sheets med IFTTT
  2. Bygg en Spotify-fjärrkontroll med funktioner för play/pause/skip

GPIO-styrning utan kod med PiCockpit

  1. Superenkel installation av PiCockpit på Pico W
  2. Enkel LED-styrning med PiCockpit och Pico W
  3. Pico W, 5V fläkt och en transistor, styrs av PiCockpit

MQTT

  1. Displayfotoresistor med hjälp av MQTT och Node-RED med Pico W

Innehållsförteckning

Innehåll dölja

Tutorial-mål i sammanfattning

  • Lär dig hur du interagerar med grundläggande komponenter som utgör större projekt
  • Styr alla dessa trådlöst - inga strömbrytare, knappar eller andra interaktionsenheter.
  • Få en bättre förståelse för Pico W:s styrkor

Viktiga länkar

Github-repokatalog för handledningskod (utom secrets.py)

MicroPython-dokumentation

Felaktigheter, förslag, kommentarer? Lämna en kommentar i kommentarsfältet nedan, maila mig eller . Tweeta mig.

OSError: [Errno 98] EADDRINUSE

Om du får det här felet ska du bara koppla ur och koppla in din Raspberry Pi Pico.

Du kan också göra detta genom att skriva in dessa kommandon i Thonnys Shell:

import machine
machine.reset()

Resultat:

Lödning av sidhuvudstift

När du köper en Raspberry Pi Pico W kanske det inte medföljer några headers som gör att du kan ansluta komponenter till din Pico.

I skrivande stund har Pico WH (H för headers) inte släppts. Vår megaartikel om Pico W håller koll på lanseringen av den.

Om du däremot kan hitta en Pico W med förlödda headers skulle jag råda dig att köpa den.

För oss andra är det dock enkelt att löda in sidhuvuden på Pico W. Du kommer att behöva:

  • Brädbräda
  • Lödkolv och lödtenn
  • Rubriker

När du köper dina headers, se till att du köper en som är avsedd för Pico W. Till skillnad från headers för Raspberry Pi Zero-serien är headers på Pico W inte sida vid sida. De sitter på motsatta ändar av kortet.

En brödskiva, Pico W och 2×20 stifthuvuden

Stiften har en långsida och en kortsida. Du vill att de längre stiften ska vara på den sida där du ser GPIO-etiketterna (GP0, GP1, GND, VBUS, VSYS, etc.)

Du vill att de längre stiften ska sitta på den sida som är motsatt den där USB-kontakten sitter.

Sätt därför i de längre stiften i brödbrädan. Du behöver fyra hål och ett avstånd mellan dem som motsvarar en rännsten. Om du är osäker kan du testa med din Pico W.

Lödning är enkelt. Se till att lödkolven är varm och att du använder lödkolvens spets.

Det jag tyckte var mest effektivt var att föra lödkolvens spets nära stiftet, få lodet att röra vid spetsen och se det rinna ner längs stiftet och skapa en anslutning.

Efter lödningen ska du kontrollera att det inte finns något främmande lödtenn som kan koppla ihop två GPIO-stift eller något överblivet lödtenn som finns på ditt kort.

Använd Thonny som kodredigerare

Thonny programmerar en Raspberry Pi Pico W

Thonny är fortfarande det enklaste sättet att programmera din Raspberry Pi Pico W.

Om du använder Raspberry Pi OS har du det redan installerat.

Om du använder Windows eller Mac måste du dock ladda ner det och konfigurera det.

Här är en guide som guidar dig genom stegen.

Se också till att se guiden om hur du laddar upp filer till din Pico W.

Uppdatera din firmware genom att ladda upp den senaste UF2

När du köpte din Pico W kan du redan ha haft den föråldrade firmware.

Många förändringar kommer att ske med Pico W, så det är perfekt att uppdatera din firmware nu.

Några förändringar som jag har sett sedan lanseringsdagen är förbättringar av WLAN:s accesspunktsfunktion, och framtida uppdateringar kan låsa upp Bluetooth-funktionen på kortet.

Uppdatering nu! Här är en guide i vår megaartikel.


1. Servera en webbsida som säger "Hello World" på Pico

"Hello World"-projektet för Raspberry Pi Pico W

Ett av de mest grundläggande projekten i alla programmeringshandledningar är "Hello World"-projektet.

En mikrokontrollers "Hello World" brukar innebära att en lysdiod blinkar. Det är superenkelt. Så här gör du.

Men eftersom Pico W kan visa en webbsida ska vi börja med att lära oss hur man visar en webbsida med ett "Hello World"-meddelande.

Den installation som används här kommer att utgöra den mest grundläggande byggstenen för resten av handledningarna.

Det finns två sätt att ansluta till Pico W. Du kan få den att ansluta till ett WiFi-nätverk eller så kan du sänder en SoftAP-hotspot på samma sätt som din smartphone gör. Om du vill prova det senare, följ denna länk. För att vara konsekventa i den här handledningen kommer vi dock alltid att ansluta till ett WiFi-nätverk i stället för att sända ett från Pico W.

Så i grund och botten innebär stegen för att servera en webbsida:

  • Ansluta till WiFi
  • Skriva kod för att servera index.html till alla som ansluter till Pico W:s IP-adress

Låt oss skapa några filer. Spara dessa och ladda upp dem till din Raspberry Pi Pico W. Så här gör du för att ladda upp filer, om du har missat det.

wifi.py

wifi.py är en boilerplate som är tänkt att hjälpa dig att ansluta till ditt WiFi-nätverk. Skapa en separat fil och importera den till main.py fil senare kommer att bidra till att minska rörig kod.

Observera att du bör ändra ditt lands kod i raden rp2.land('DE') om ditt land inte är Tyskland.

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])

secrets.py

wifi.py import secrets.py, där du lagrar information om ditt WiFi-nätverk.

secrets.py är en enkel JSON-fil som innehåller ditt WiFi SSID och lösenord.

secrets = {
    'ssid': 'SM-A520W9371',
    'pw': 'starting',
    }

serve_webpage.py

Som namnet antyder serverar den här sidan webbplatser till användare som ansluter till Pico W.

När Pico W tar emot en anslutning hittar den en fil som heter index.html och skickar den till den anslutna klienten, vilket framgår av raden svar = 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')

Slutligen måste vi skapa index.html fil som ska skickas till en ansluten klient.

<!DOCTYPE html>
<html>
    <head>
        <title>Pico W</title>
    </head>
    <body>
        <h1>Hello World</h1>
    </body>
</html>

Detta är en enkel HTML-boilerplate med två ändringar: en till <title>tagg som anger "Pico W" som titel och <h1> tagg som anger "Hello World".

main.py

Eftersom vi har placerat all kod på andra ställen, kommer vår main.py filen behöver bara importera och anropa dessa funktioner för att betjäna webbsidan Hello World.

Som du kan se initialiserar vi WiFi först innan vi serverar webbsidan.

from wifi import init_wifi
from serve_webpage import serve_webpage

init_wifi()
serve_webpage()

Du är nästan framme!

Med hänvisning till skärmdumpen nedan, se till:

  • Du har laddat upp fem filer till din Raspberry Pi Pico W (se den röda rutan längst ner till vänster)
  • Kontrollera att din tolk är inställd på MicroPython (Raspberry Pi Pico) (se rutan längst ner till höger)
  • Markera sedan main.py i din kodredigerare och klicka på den gröna körknappen (övre vänstra röda rutan)
  • När du har kört detta kommer du att se din IP-adress i Shell. Gå till din webbläsare och skriv in denna adress så kommer du att se webbsidan Hello World.
  • Om ditt Shell inte är öppet, gå till View -> Shell.

Om allt går som det ska kommer du att se nedanstående sida.


2. Trådlös styrning av en LED

Nu när grunderna är klara kan vi ta ett steg framåt.

Ett av de mest grundläggande Raspberry Pi-projekten handlar om att blinka med en lysdiod.

Låt oss höja det ett snäpp genom att styra LED-lampan trådlöst. Vi vill kunna blinka, tända och släcka LED-lampan.

För att göra detta måste du ställa in en krets och en webbserver med tre knappar - ON, OFF, BLINK.

För det här projektet behöver du en lysdiod, ett 330 ohm-motstånd, en bygelkabel och en brödbräda.

Vi använder en röd lysdiod eftersom de flesta byggsatser har en sådan. Observera att om du använder en LED i någon annan färg måste du justera motståndet.

Så här kopplar du ihop komponenterna

  • GPIO 2 -> LED:s långa ben (anod/positiv)
  • GND -> 330 ohm motstånd -> LED:s korta ben (katod/negativ)

Kod för att styra LED på Pico W

Låt oss bygga vidare på det vi gjorde i den föregående handledningen. De enda två filer vi behöver ändra är index.html för att lägga till knappar och main.py för att interagera med LED-lampan baserat på input från index.html.

De delar som är fetmarkerade anger de nya rader som lagts till i index.html. De lägger till tre knappar och ett stycke som säger "Control the LED".

<!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>&nbsp;
        <a href=\"?led=off\"><button>OFF</button></a>
        <a href=\"?led=blink\"><button>BLINK</button></a>
    </body>
</html>

När du trycker på knapparna ser du att en parameter läggs till i din Pico W:s IP-adress (t.ex. http://192.168.43.134/%22?led=blink\). Dessa parametrar fångas upp av Pico W:s backend och styr LED-lampan.

Vi kommer att flytta serve_webpage.pykod till den main.py fil.

Här är 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')

Det första, och viktigaste, segmentet är nedan:

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()

Variabeln "request", när den skrivs ut, matar ut det första textblocket nedan. De tre sista raderna är utskriftssatserna som kontrollerar om lysdioden är på, av eller blinkar:

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

Koden ovan kommer att försöka söka efter specifika strängar som "led=på". Om den finns kommer värdet att vara större än -1, vilket utlöser den relevanta om uttalande.

Om till exempel led=on finns i parametrarna kommer variabeln led_on att vara mer än -1, och därför kommer om led_on > -1 meddelandet triggas och körs led.on();

Den enda komplicerade delen här är led_blink funktion som kommer att utlösa funktionen:

    def blink_led():
        led.on()
        time.sleep(0.2)
        led.off()
        time.sleep(0.2)

Slutligen, så här initialiserar du GPIO 2 för att driva LED-lampan:

import machine
import time
    
#LED controls
led = machine.Pin(2, machine.Pin.OUT)

Vi importerar maskinen för att interagera med GPIO-pinnen. Som du kan se i variabeln ledvill vi att Pico W ska strömförsörja GPIO 2.

Vi importerar tid så att vi kan ha en paus på 0,2 sekunder i blink_led().


3. RGB LED på Pico W

För att lysa upp din RGB LED behöver du:

  • Tre 330 ohms motstånd
  • En RGB LED
  • En bygelkabel

På RGB LED-lampan finns fyra ben. Ett ben är det längsta. Det är antingen en katod (negativ) eller en anod (positiv). Min RGB LED hade en delad katod så här är anslutningen:

Bilden visar R-, G- och B-benen på en RGB-LED med gemensam katod. (Bild från Raspberry Pi Foundation CC-BY-SA)
  • GPIO 15 -> 330 ohms motstånd -> röd LED
  • GPIO 17 -> motstånd -> grön LED
  • GPIO 16 -> motstånd -> blå LED

Här är lite kod för att se om du har kopplat upp det rätt:

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)

I det här exemplet använder vi PWM, vilket gör att du kan variera ljusstyrkan på lysdioderna R, G, B.

Du kan ändra värdena som skickas till [color].duty_u16 till ett värde mellan 0 och 65534. Teoretiskt sett borde du kunna skicka 65535, men på något sätt verkar det inte fungera för mig.

Tänk på att om du skickar "0" betyder det att du vill ha noll procent ljusstyrka. Om du skickar 65534 vill du ha 100 procents ljusstyrka.

Om du gör 65534 för en färg och noll för resten kan du se om du har kopplat rätt GPIO-stift till rätt LED-färg.

Så varför använder vi PWM? För att det hjälper dig att få fram fler färger. Om du bara använder en "på-och-av"-metod kan du få rött, grönt, blått, vitaktigt och inget ljus. Med PWM kan du variera intensiteten hos R, G, B LED och skapa så många färger du bara kan föreställa dig.

Låt oss nu skapa något som du kan styra trådlöst!

index.html

Den viktigaste förändringen här är att ha en <form> som har tre skjutreglage. Dessa skjutreglage har ett värde mellan noll och 100.

Genom att använda värden mellan noll och 100 kan du visualisera ljusstyrkan som en procentsats. Det minskar också mängden kod som behövs för att tolka värdet från parametrarna (se senare i main.py)

När du har ställt in värdena för lysdioderna R, G, B trycker du på submit, och dessa data registreras av Pico W.

<!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')

När du trycker på "Skicka" på index.html webbsida tar Pico W emot parametrarna och bearbetar dem.

Låt oss titta på några viktiga punkter i koden, fetmarkerade i kodblocket ovan.

funktionen find_intensity

Denna funktion tar två parametrar: färg och begäran_str. färg tar in "röd", "grön" eller "blå" och hittar värdet efter likhetstecknet (=).

Till exempel är din URL efter att du skickat in formuläret "http://192.168.1.142/?red=89&green=50&blue=50".

Om du skickar "red" till find_intensity får du tillbaka 89.

Intensitetsanalysator

Det andra fetstilta kodblocket representerar koden som talar om för Pico W:s GPIO hur mycket ljusstyrka du vill ha från varje LED.

Först måste vi se till att parametrarna finns i URL:en. Detta görs av om uttalande request_str.find('röd') > -1. Jag använde bara 'röd' eftersom parametrarna kommer 100% att innehålla strängen 'röd' om du använder formuläret.

Om du besöker din Pico W:s IP-adress (t.ex. http://192.168.1.142/) för första gången har du inga parametrar, så programmet kommer att krascha om du kör hitta_intensitet.

Om params finns, hittar vi intensiteten för varje LED enligt de värden som angetts. Låt oss ta en titt på röd_intensitet.

red_intensity = int(find_intensity('red=', request_str) /100 * 65534)
...
red_led.duty_u16(red_intensity)

hitta_intensitet returnerar ett heltal mellan noll och 100. Vi delar detta med 100 så att du kan få en procentsats. Denna procentsats dividerar det maximala värdet som tull_u16 metod kan ta.

Vi behöver dock en int funktion för att omsluta detta eftersom du ibland kan få en flottör och tull_u16 behöver en int. Till exempel, säg att du ville ha 41% ljusstyrka - 41% av 65534 är 26 868,94. Du kan inte skicka denna float eftersom programmet kommer att krascha.


4. Summerfunktion på Pico W

En summer är en ganska viktig komponent för grundläggande meddelanden, precis som en LED kan berätta om tillståndet för något, ger en summer dig ett hörbart meddelande.

Anslut summerns positiva terminal till GPIO 16 och jorda till ett GND-stift på Pico W.

I stället för att implementera min egen kod har jag valt att använda Giuseppe Cassibbas genomförande. Om du kör hans kod på Pico W kommer du att höra pip på din summer.

Men eftersom den här koden är avsedd för Pico kommer den inte att ha några funktioner för trådlös interaktivitet.

Så låt oss ta fram gaffeln!

Låt oss först modifiera index.html för att implementera knapparna. Låt oss ha en knapp för "ON", "OFF", "SCALE", "MUSIC".

De två första knapparna är självförklarande. Den tredje knappen spelar en C-skala och den sista spelar ett musikstycke.

<!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>&nbsp;
        <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>

Precis som tidigare skapar vi några <button> taggar med <a> taggar som omger dem. När du klickar på knapparna kommer webbadressen att ha en parameter som t.ex. /buzzer=on. Pico W läser av detta och slår på summern.

Låt oss nu titta på Giuseppes kod för Pico:

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()

Hans kod spelar en C-skala när den körs med funktionen summer(), som tar in fyra parametrar: Summerobjekt, frekvens i Hertz, ljudlängd och pauslängd innan nästa ljud spelas upp.

Låt oss modifiera koden så att vi kan aktivera PÅ, AV, SKALA och MUSIK.

Så här integrerar vi Giuseppes kod i vår 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')

I implementationen ovan har vi inte skrivit koden för MUSIK.

Koden är mycket lik den för den röda lysdioden ovan, där Pico W fångar upp parametrarna efter Pico W:s IP-adress. Om parametrarna summer=ON, kommer den att spela ett 440Hz-ljud. Om summer=skalakommer den att spela skalan som är hämtad från Giuseppes kod.

Hur är det med att implementera musik? Att implementera musik är lite mer komplicerat så vi bör skapa en ny fil som heter konstanter.py och lägga till några rader i vår main.py.

Denna kod är en förgrening från Rowan Packards Arduino-kod.

konstanter.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 (tillägg fetmarkerade)

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')

Som du kan se finns det två matriser, musik_noter och rytm. Du skulle sedan köra en for-slinga för att lägga in dessa värden i summer() funktion. I början av koden importerar vi också alla variabler från konstanter.py.

The summer() funktionen använder också två nya variabler - t och pausa. Dessa två variabler hjälper dig att ställa in musikens tempo. t definierar hur länge varje not ska spelas och pausa definierar hur lång tystnad det ska vara mellan tonerna.


5. Pico W och HC-SR04 ultraljudssensor

pico-w-ultrasonic-sensor
`

I de tidigare handledningarna har vi använt Pico W för att skicka kommandon till lysdioderna och summern.

Men vad händer om vi använder Pico W för att ta emot information?

I det här fallet talar vi om HC-SR04 ultraljudsavståndssensor.

När du ansluter din ultraljudssensor, var noga med att veta om det är en 5V eller 3,3V komponent. Jag kopplade in min 5V-version i 3,3V-stiftet och fick inget svar från programmet, vilket jag kommer att dela nedan. När jag flyttade strömkällan till 5V-stiftet fick jag omedelbart ett svar.

Tydligen kan vissa nyare versioner av HC-SR04 ta både 3,3V till 5V. Kanske är det bäst att bara prova 3,3V-stiftet först och se om du får ett resultat. Om inte, prova 5V.

Här är schemat och programmet som du kan köra i Thonny. Om du får ett svar betyder det att du har kopplat in allt på rätt sätt, inklusive spänningen.

Ledningar

Ledningarna från de märkta stiften på HC-SR04-givarna är enligt följande:

  • VCC till 3,3V eller 5V stift (om du är osäker, prova 3,3 V först)
  • TRIG till GPIO 16
  • ECHO till GPIO 15
  • GND till GND

Testprogram för HC-SR04

För att testa om din kabeldragning är korrekt kan du prova den här koden som skriver ut avståndet på Thonny Shell.

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)

Din utgång bör vara:

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

Om programmet körs och avslutas utan någon utmatning, har du förmodligen kopplat något fel. När jag anslöt sensorn till ett 3,3V-stift istället för ett 5V-stift, avslutades programmet utan svar.

Hämta data som skickas till din webbläsare

Låt oss ta fram filerna som vi använde för att servera en webbsida och ändra dem så att vi kan se avståndsvärdena.

Här är den slutliga koden:

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>

Låt oss titta på några utdrag ur koden för att förstå vad som händer.

Kod för att få ultraljudsavstånd

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

Kodblocket ovan utlöser utsändningen av en ultraljudsvåg. Den tid.sömn mellan låg- och högpunkterna är nödvändiga för att ultraljudssensorn ska fungera.

För att mäta hur lång tid det tar mellan utsändningen av ultraljudsvågen och den tid det tar för ljudvågen att återvända använder vi tid.ticks_us för att mäta tiden för utsändning och tiden för ekot att detekteras.

tid.ticks_us är ett godtyckligt tal, så vi måste subtrahera signalon från signalavstängning för att få tiden att gå.

För att få fram avståndet använder vi formeln avstånd = (tid passerad * ljudets hastighet) / 2. Ljudets hastighet är 340m/s, vilket därför är 0,0340.

Anledningen till att vi måste dela det med två är att ljudvågen färdas till objektet och återvänder tillbaka.

Kod för att visa webbsida med avståndsvärde

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())

Denna funktion har modifierats lite från de tidigare handledningarna, med en ytterligare parameter avstånd, som körs ultraljud().

Funktionen öppnar index.html filen normalt men använder ersätta metod för att hitta <h2> och infogar avstånd variabel.

index.html pingar servern var 500:e sekund för att få ett nytt värde

index.html

Huvudwebbsidan får en funktion som laddar om webbsidan var 500:e sekund. Varje omladdning pingar Pico W för att få det nya ultraljudsavståndsvärdet.

    <script>
            setInterval(() => location.reload(), 500)
        </script>

6. Ultraljudsdata, men låt oss använda AJAX för att minska nyttolasten

Den tidigare handledningen fungerar genom att Raspberry Pi Pico W skickar en helt ny index.html fil varje gång det finns en anslutning.

Detta fungerar men är otroligt ineffektivt eftersom hela index.html skickas när du bara behöver uppdatera ultraljudets avståndsdata.

Vi vill ha samma resultat som i den tidigare handledningen, men utan den tunga belastning som den tidigare metoden innebar.

Så vi måste få klienten (din telefon eller dator) att pinga en slutpunkt som bara svarar med ultraljudsdata.

Den nya metoden är följande: om människor besöker rot-URL:en, t.ex. 192.168.1.119, kommer de att serveras index.html.

index.html kommer att ha JavaScript som pingar /data slutpunkt, som triggar Pico W att hämta ultraljudsdata om avstånd och svara med dem.

Då så, index.html kommer att ta emot dessa uppgifter och uppdatera webbsidan.

Splicing av begäran från klient

Kom ihåg att i main.pyfinns det alltid en replik som säger förfrågningar = cl.recv(1024). Förfrågningsobjektet ser ut ungefär så här:

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

Först och främst måste vi filtrera bort den här textväggen.

Vi använder hitta() metod för att ta reda på om begäran variabeln har "/data". Om den gör det, svarar du med ultraljudsdata för avståndet. Om det inte finns något "/data", svara då med index.html.

Före

request = cl.recv(1024)
        print(ultrasonic())
        response = get_html('index.html', ultrasonic())

Efter

 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())

Om du besöker /data i din webbläsare kommer du att se avståndsvärdet skrivas ut, enligt nedan.

Tidigare hanterade backend nästan allt. Ultraljudsavståndet modifierades innan det serverades som index.html.

Nu, index.html hämtar sensordata från Pico W, så vi måste göra några ändringar i det JavaScript som finns i HTML-filen. Ändringar är markerade med fet stil.

<!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>

Centralt för koden här är Hämta API och den senaste asynkron/avvakta syntax här.

Funktionen hämtaData() pingar Pico W:s /data-slutpunkt och Pico W svarar. Vi ser till att programmet inte hoppar vidare innan vi får ett fullständigt svar där vi ber det att invänta.

Fetch blir ett Response-objekt som du måste använda Response.text()-metoden för att komma till svarstexten. Därav raderna const distance = vänta på data.text();

När vi väl har ultraljudsdata ändrar vi <h2 id="”ultrasonic”"> elementets inre HTML, som börjar tomt, med avståndsdata. Du kan rikta in ett element med en id direkt utan att använda getElementById() eller . querySelector() metoder.

När all kod är klar vill vi köra getData() igen. Varför använde jag en setInterval för att ställa in ett intervall på 100 ms?

Vad jag upptäckte var att om du anropade getData() utan intervall, får du fler pauser mellan utmatningarna. Du får en sekvens av snabba uppdateringar och sedan en paus. Med 100 ms andrum går Pico W lite bättre och uppdateringarna verkar fortfarande vara mer eller mindre i realtid.

Om du vill förstå vad som händer under motorhuven kan du läsa mer i Dokumentation om Fetch API och asynkron/avvakta dokumentation.


7. Pimoroni Phew för renare kod

Pimoroni Phew används för att leverera ultraljudsdata

I det förra avsnittet beskrev vi AJAX-metoden för uppdatering av ultraljudssensordata.

Men finns det ett ännu bättre sätt att göra detta på?

Pimoroni's Phew är ett bibliotek som hjälper dig att göra mycket nätverkande enkelt eftersom du kan undvika en hel del drugery.

Målen är desamma:

  • Hämta ultraljudsdata och visa dem på index.html
  • Håll nyttolasten så låg som möjligt.

Så här gör du main.py ser ut som.

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()

Som du kan se är koden mycket mer läsbar eftersom du kan ange slutpunkter och koppla dem till funktioner som returnerar specifika data.

Istället för att fumla med kod för att köra uttagen anropar man bara en funktion från Phews bibliotek.

Några saker som är bra med Phew är:

  • Inget mer användande av begäran.hitta() för att skapa en slutpunkt
  • Inte mer get_html() funktion för att öppna index.html fil, använd bara Phews render_template()
  • main.py är mycket lättare att läsa, med minimal extra ansträngning!
  • Phew lägger också till loggningsfunktioner som gör det lättare att felsöka din kod.

Den enda nackdelen är att Phew fortfarande är "ett mycket nytt projekt och bör betraktas som, i bästa fall, alfa-stadiet". Så du kan hitta oväntade vägspärrar ibland.

Kolla in det här.

De tidigare handledningarna handlade om hur du kan interagera med din Pico W via din PC/mobiltelefon.

Låt oss ta ett steg längre och få Pico W att interagera med en molntjänst.

Låt oss därför skapa en temperatur- och luftfuktighetsloggare med en DHT22-sensor som skickar data till Google Sheets via IFTTT.


8. Konfigurera temperatur- och fuktighetssensorn DHT22 till Pico W

Raspberry Pi Pico W ihop med en DHT22 temperatur- och fuktighetsloggare.

Alla dessa steg fungerar för DHT11 och DHT22. Den största skillnaden mellan de två är noggrannheten i avläsningarna. DHT11 är blå i färgen medan DHT22 är vit.

Om du har en DHT11, observera att hänvisningar till DHT22 i koden ska ändras till DHT11. Till exempel,

import dht
#dht22 = dht.DHT22(Pin(16))
#should be
dht11 = dht.DHT11(Pin(16))
DHT22 stift

Om du tittar på diagrammet nedan, från topp till botten av DHT22, ansluter du 3,3 V till det första stiftet.

Det andra stiftet är datastiftet. Du måste strömförsörja den. Så anslut ett 10K ohm-motstånd från strömskenan till den och anslut sedan en annan bygelkabel till GPIO 16 på Raspberry Pi Pico.

GND går till GND.

För att testa sensorn, kör detta:

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())

Om du får OSError: [Errno 110] ETIMEDOUT betyder att du kör skriptet för tidigt. DHT22 kräver två sekunders paus innan den kan returnera ett annat värde. DHT11 kräver en sekund.

Koppla samman IFTTT och Google Sheets

Pico W loggar data om tid, temperatur och luftfuktighet i Google Sheets

Det enklaste sättet att få data från Pico W till Google Sheets är via IFTTT.

Först, registrera dig för ett IFTTT-konto.

Klicka sedan på knappen "Skapa" för att skapa appleten.

Du kommer att se denna skärm:

Klicka på "If This" och sök efter Webhooks. Klicka på "Ta emot en webbförfrågan". Välj inte JSON-versionen. Namnge händelsenamnet "dht22". Händelsenamnet är kritiskt eftersom det är så IFTTT vet vilken applet som ska utlösas.

Välj detta, inte alternativet JSON-laddningen.

Vad du gör här är att skapa en slutpunkt som du kan pinga med DHT22:s sensordata.

Klicka sedan på "Sedan det". Välj "Google Kalkylblad". Välj sedan "Lägg till rad i kalkylbladet". Du måste länka ditt Google Sheets-konto.

Ändra "Kalkylbladets namn" och "Sökväg till hårddiskmapp" till vad du vill. Det enda som är kritiskt här är "Formaterad rad", där du vill att den ska vara

{{OccurredAt}} ||| {{Value1}} ||| {{Value2}}

Nu måste du hämta den slutpunkt som Pico W kan skicka sensordata till.

Gå till https://ifttt.com/maker_webhooks och klicka på "Dokumentation".

I dokumentationen får du veta vilken nyckel du ska använda, vilken endpoint du ska skicka data till och hur JSON-kroppen ska struktureras.

Eftersom du använde "dht22" som händelsenamn är din slutpunkt:

ttps://maker.ifttt.com/trigger/dht22/with/key/[your_key_here]

Du vill också strukturera din JSON-kropp så här:

{'value1': *** temperature data *** , value2': *** humidity data *** }

Kodning av Pico W för att hämta DHT22-data och skicka dem till IFTTT

Så här gör du.

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()

Om du ska kopiera den här koden, se till att ersätta [din_nyckel_här] värdshuset begäran_url variabel.

Du bör få en ny avläsning varje minut som loggas till Google Sheet, enligt nedan.

Pico W loggar data om tid, temperatur och luftfuktighet i Google Sheets

Observera att den loggade temperaturen är i Celcius. Om du vill ha den i Fahrenheit, här är formeln:

fahrenheit = dht22.temperature() * 1.8000 + 32.00

Om du vill att data ska loggas oftare (eller mer sällan) ändrar du värdet i tid.sömn().

Använd IFTTT för att meddela dig om ett fel inträffar

Den här koden är naturligtvis fortfarande ganska bräcklig.

Låt oss säga att något inte går rätt till. Till exempel att din katt drar i 3,3V-bygelkabeln medan du ligger på golvet för att logga temperaturen.

Programmet kommer att dö, men du kommer inte att få något meddelande förrän du märker att dina data inte loggas.

Hur löser du det här?

Få IFTTT att skicka ett meddelande till dig när det händer!

Du skulle behöva IFTTT-appen på din telefon. Så ladda ner den.

Sedan skapar du en ny applet.

För "Om detta" del, Välj Webhooks -> Ta emot en webbförfrågan. Namnge ditt evenemang "fel".

För "Sedan detta" del, välj "Meddelanden" och "Skicka ett meddelande från IFTTT-appen".

Jag gjorde budskapet enkelt

Error: {{Value1}}

Låt oss nu bygga try-error-blocken.

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)

Försök med det. Koppla ur 3,3V-kabeln från din DHT22 och du kommer att få ett meddelande som sådant:


9. Bygg en fysisk Spotify-fjärrkontroll med Raspberry Pi Pico W

Vi bygger vidare på det tidigare projektet och använder IFTTT för att styra Spotify.

Vi skapar en enhet som har en knapp för att spela, pausa och hoppa över spår.

Den största fördelen med att använda IFTTT för att styra Spotify är hur enkelt det är.

Nackdelen är att du behöver ett betalt Spotify-konto och att svaren är långsamma. Det betyder att om du trycker på hoppa över-knappen måste du vänta ett tag innan du ser resultatet.

Det fina med att ha en dedikerad Spotify-fjärrkontroll är att du kan ändra din musik utan att bära med dig din telefon eller behöva öppna Spotify-appen.

Om du någonsin har kört en modern bil vet du hur trevligt det är att ha rattkontroller.

Koppla upp en fjärrkontroll för Spotify

Spotify Raspberry Pi Pico W-styrenhet
Spotify Raspberry Pi Pico W-kontroller. Från topp till botten är knapparna paus, spela, hoppa över spår.

Du kommer att behöva...

  • 7x bygelkablar
  • 3x knappar
  • Raspberry Pi Pico W
  • Spotify betalkonto

Det är många kablar som korsar varandra där uppe i bilden, så här kommer en textförklaring.

Tryckknapparna är som strömbrytare. Du måste ansluta 3V3-stiftet till var och en av dem, vilket innebär att du använder den positiva kolumnen på brödbrädan. Det är därför:

3V3 -> positiv kolumn på brödbrädan -> tryckknapp (på ena sidan av brödbrädans ränna) -> GPIO (på andra sidan)

Min kod använder GPIO 16 för uppspelningsknappen, GPIO 2 för pausknappen och GPIO 15 för knappen för att hoppa över spår.

Konfigurera IFTTT för att styra Spotify

Vi ska skapa tre IFTTT-appletter för att styra Spotify.

Vi måste skapa tre applets, en vardera för funktionerna play, pause och skip.

Om du har premiumversionen av IFTTT kan du förmodligen använda JavaScript-filtren för att innehålla allt i en app. Men eftersom vi inte gör det behöver vi en applet vardera.

När du är inloggad klickar du på "Skapa" längst upp till höger i huvudmenyn.

Klicka på "If This" i fältet och sök efter Webhooks.

Klicka på "If This" eller "Then That" och välj Webhooks respektive Spotify.

Klicka sedan på "Ta emot en webbförfrågan" (inte det andra alternativet som har "med en JSON-nyttolast").

För händelsens namn, skriv spotify_skip.

Du måste upprepa detta steg ytterligare två gånger för att spotify_paus och spotify_play när du är klar med att skapa den här appleten.

När det är gjort går du till "Sedan det"-fältet och klicka på det. Sök efter "Spotify".

Du måste godkänna att IFTTT ansluter till Spotify en gång.

Om du gör det spotify_skip handling, vill du klicka på "Hoppa över spår". Men om du gör en applet för att utföra någon annan åtgärd, visar bilden ovan vilken du ska använda.

När du har skapat alla tre applets är det dags att koda!

Kodning av Spotify-fjärrkontrollen för Pico W

Först och främst måste du veta vilken slutpunkt du behöver träffa.

Gå till denna sida och klicka på Dokumentation.

Du kommer att se din nyckel där. Om du har följt alla stegen ovan är skillnaden mellan din och min slutpunkt din nyckel. Hence,

Spela slutpunkt: https://maker.ifttt.com/trigger/spotify_play/with/key/[din_nyckel_här]

Paus: https://maker.ifttt.com/trigger/spotify_pause/with/key/[din_nyckel_här]

Hoppa över: https://maker.ifttt.com/trigger/spotify_skip/with/key/[din_nyckel_här]

Kod

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)

Låt oss gå igenom koden.

Observera att du kommer att behöva byta ut [din_nyckel_här] med din riktiga nyckel, som erhållits genom Dokumentation länk.

Först deklarerar vi variabler för tryckknapparna.

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)

Om du för närvarande inte trycker på knappen kommer din variabel att ha ett värde på 0. Om du trycker på den blir den 1. Detta är vad vi kommer att använda för att utlösa spela() , paus() och hoppa över() funktioner.

Sedan skapar vi funktioner för slutpunkterna för uppspelning, paus och hoppa över. Den allmänna mallen är som följer:

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)

Det är ganska enkelt. Om den här funktionen körs kommer den att skicka en POST-begäran till IFTTT. Att skicka en GET-begäran kommer inte att fungera.

Sedan har vi try/except-blocket.

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)

Om en knapp trycks in kommer koden att köra den relevanta funktionen. Om du t.ex. trycker på skip-knappen körs funktionen hoppa över().

A tid.sömn(0.25) pausar funktionen i 250 ms. Utan detta kan även en kort tryckning överbelasta och krascha Pico W.

The utom block är valfritt, men jag gjorde det eftersom jag redan hade en "fel" -applet på IFTTT. Om du har följt den tidigare handledningen kanske du har använt den.

I grund och botten skickar den felmeddelandet, e, till IFTTT, så att du får felmeddelandet som ett meddelande från telefonappen.

Varför fungerar det inte?

Det är enkelt att använda IFTTT för att styra Spotify, men det finns vissa nackdelar med det.

Du måste starta musiken på vanligt sätt först

Om du har försökt trycka på play-knappen på din Pico W och förväntat dig att musik ska börja spelas... ja, då händer ingenting.

Lösningen är att starta musiken på din dator eller telefon på vanligt sätt. Du måste gå till din app och trycka på play.

Jag tror att detta förklarar vilken enhet som är den aktiva enheten. När du har gjort detta kommer du att kunna använda din Pico W Spotify-fjärrkontroll.

Långsamma svar

Det tar några sekunder mellan knapptryckning och svar. Tyvärr är det så här det är.

Du kan betala för en IFTTT-uppgradering för att få snabbare svarshastigheter. Åtminstone är det vad de lovar för dina pengar.

Finns det ett direkt sätt att ansluta Spotify?

Ja! Spotify har ett Spotify har ett API som du kan ansluta till.

Det ger dig betydligt mer kontroll. Du kan lägga till en roterande kodare för att styra volymen. Du kan lägga till en LCD-skärm för att visa vad som spelas. Kolla in Spotifys konsol här.

Fantastiskt, men också mycket svårare att programmera, särskilt på en Pico W.

IFTTT gör allt enkelt eftersom de gör alla tunga lyft. Om du vill vara den tunga lyftaren, kolla in autentiseringsflödet.

Flödesschema för auktoriseringskod av Spotify

Självklart, vi är Raspberry Pi-entusiaster. Någon där ute kommer att göra det. Borde det vara du? Eller jag? Kommentera nedan.

Styr din Pico W trådlöst med PiCockpit!

Du kan styra och få data från din Pico W trådlöst med hjälp av PiCockpit.

Med PiCockpit kan du få värden, styra och använda PWM via ett grafiskt gränssnitt via dess GPIO-applet.

Du kan också se din Pico W:s statistik med hjälp av appletten PiStats.

Det är superenkelt att integrera PiCockpit i din Pico W.

Följ den här handledningen.

Skriv ännu mindre kod med PiCockpit och Pico W

PiCockpit gör det enkelt för dig att styra dina GPIO-stift utan att behöva skriva någon kod.

Om du tittar på handledning nummer 2Lägg märke till hur mycket kod som krävs för att bara växla en lysdiod.

Med vår nya Pico W-integration gör PiCockpit det mycket enklare eftersom du inte behöver programmera någonting alls. Inte ens WiFi-konfigurationen - det görs med vår installationsguide.

10. Enkel LED-styrning med PiCockpit och Pico W

Om du har konfigurerat din lysdiod precis som jag gjorde i handledning nr 2 är allt som återstår att konfigurera den i PiCockpit.

Om du kodar ut det, anger du vilken stift din lysdiod är på med hjälp av led = machine.Pin(2, machine.Pin.OUT)

I PiCockpit går du till din GPIO-applet och bläddrar till "GPIO Output (On/Off)".

Välj BCM02 från rullgardinsmenyn eftersom din lysdiod är på GPIO 2.

I kolumnen "Control" (kontroll) växlar du sedan mellan strömbrytaren för att tända lysdioden.

Du kan också enkelt använda Software PWM-avsnittet nedan för att styra ljusstyrkan på din lysdiod.

Observera att du måste ta bort den tidigare inställningen eftersom du inte kan ha två utgångar på samma GPIO.

När du vänder på reglaget "Control" kommer du att märka att ljusstyrkan på lysdioden ändras.

Picockpit gpio pwm fjärrkontroll

11. Pico W, 5V fläkt och en transistor, styrd av PiCockpit

Låt oss prova något lite mer omfattande men med samma GPIO Output toggle.

För att illustrera några verkliga användningsfall kommer jag att driva en 5V-fläkt med hjälp av PiCockpit.

Det här är en 5V-fläkt med låg effekt från min Raspberry Pi 4, så den ligger väl inom Raspberry Pi Pico W:s kapacitet.

Eftersom det är en 5V-fläkt kan jag inte använda en GPIO-stift. I mindre strömkrävande komponenter, t.ex. en lysdiod, kan du låta GPIO-stiftet göra dubbla uppgifter, nämligen att leverera ström till komponenten och vara den "strömbrytare" som slår på och av den.

Men 5V-fläkten skulle kräva för hög spänning. Så det näst bästa sättet är att sätta en transistor i mitten.

På så sätt kan jag leverera 5 V till fläkten och samtidigt se till att jag kan slå på och stänga av den.

Återigen, tack vare PiCockpit, gjorde jag ingen programmering. Jag gjorde bara hårdvaran, som är kopplad på följande sätt:

Fläkten är en 5V/0,12A fläkt, ansluten till 5V i den positiva änden (röd tråd), och den negativa tråden går till transistorens emitterben.

Transistorn är en PN2222-transistor (NPN), vilket innebär att den slår på när den får en hög signal.

Från vänster till höger, med den halvcirkelformade delen vänd bort från dig, är benen Emitter, Base och Collector.

Base-benet ansluts till ett motstånd på 1 K och ansluts sedan till GPIO 15.

Kollektorbenet är anslutet till jord.

Konfigurera PiCockpit för att arbeta med transistorer

Återigen, superenkelt.

Gå till rullgardinsmenyn i avsnittet GPIO Output och lägg till BCM15.

När den är inne kan du klicka på pilen nedåt och ändra State Names till "fan off" (fläkt av) och "fan on" (fläkt på).

Om du vrider på strömbrytaren bör du se att fläkten startar.

Du kan också använda PiStats för att se hur temperaturen sjunker på ditt kort.

Displayfotoresistor med hjälp av MQTT och Node-RED med Pico W.

Huvudsyftet med denna handledning är att introducera MQTT.

I de tidigare handledningarna har jag visat hur du kan använda din Pico W för att leverera data, men vad händer om du vill ha en central lagringsplats för data i molnet?

HiveMQ Cloud är en gratistjänst som vi kan använda för att uppnå detta mål. Genom att använda andras datorer kan vi också minska belastningen på Pico W.

MQTT har dessutom stora fördelar jämfört med de tidigare metoder som använts. För det första är det mycket effektivare när det gäller att skicka små data. MQTT-protokollets rubriker är 2 byte stora. HTTP är ungefär 4000 gånger större.

Minskad lokal processbelastning och nätverksbelastning innebär längre batteritid för din Pico W, vilket är perfekt för batteri- eller soldrivna projekt.

Fotoresistoranslutning med Pico W

En fotoresistor (fotocell) är superenkel att ansluta.

Placera fotoresistorn över den centrala rännan på brödbrädan.

Anslut sedan 3V3-stiftet till ena sidan av fotoresistorn.

Du vill ansluta ett ADC-stift till andra sidan av fotoresistorn, så anslut GPIO 26.

Anslut slutligen ett 10K ohm-motstånd från jord till fotocellen.

HiveMQ Cloud och kodning av Pico W

Först ut, registrera dig för HiveMQ Cloud här.

Gå igenom installationen och skapa ett kluster. Du kommer att bli ombedd att välja AWS eller Azure. För våra syften är det ingen skillnad.

Klicka sedan på "Hantera kluster".

Klustrets huvudmeny. Notera de två orangefärgade rektanglarna.

Anteckna din Cluster URL och klicka på Access Management för att skapa en ny användare. Gå igenom stegen och skapa en ny användare.

Med dessa uppgifter kan du nu programmera din Pico W att skicka data dit.

Kodning av Pico W för att ta emot data från fotoceller och 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)

Låt oss först få ordning på vår import.

from machine import Pin, ADC
from wifi import init_wifi
import time
from umqtt.simple import MQTTClient

The wifi import kommer från de tidigare handledningarna.

Du kommer att behöva biblioteket umqtt.simple, som kan laddas ner här.

När den har laddats ner kan du ladda upp den till ditt kort (guide här).

Du bör ha dessa filer på din Pico W.

Skapa sedan en funktion för att få en avläsning från fotoresistorn:

photoresistor = ADC(Pin(26))

def readLight():
    light = photoresistor.read_u16()
    return light

Detta returnerar ett värde upp till 65535. Ju ljusare det är, desto högre är värdet.

Ansluta till HiveMQ

För att ansluta till HiveMQ måste du skicka några parametrar till MQTTClient-klassen.

# 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()

Ersätt [your-host-name] med den adress som finns på din instrumentpanel. Du kommer att behöva göra detta två gånger, en gång för server och en annan för server_hostname. Ersätt också [your_client_id] med ett namn för din enhet, t.ex. "your_picow".

Byt sedan ut [your-user] och [your-pw] med den användare som du skapade på sidan Access Management (skärmdump av sidan Access Management nedan).

Som referens kan nämnas att denna funktion skickar data till HiveMQ:

def publish(topic, value):
    print(topic)
    print(value)
    client.publish(topic, value)
    print("data published")

Låt oss kalla det i vår while loop:

while True:
    brightness = str(readLight()) #to publish, must send string

    print(brightness)

    publish('picow/brightness', brightness)

    time.sleep(0.1)

När du publicerar måste du skicka strängar, vilket är anledningen till att brightness = str(readLight()) är där.

Om du skickar heltal eller flyttal kommer programmet att dö.

I publiceringsfunktionen ger du ditt ämne ett namn. Säg till exempel picow/brightnessoch lägg sedan till det värde du vill skicka. I det här fallet vill vi skicka den stringifierade ljusavläsningen, brightness.

Du bör kunna se de data som publiceras när du loggar in på fliken Web Client.

HiveMQ:s webbklient, till vänster, visar data som har publicerats.

Node-RED

Det är bara siffror på nätet som kan verka som rappakalja. Vad händer om du vill komma åt data på HiveMQ Cloud och presentera dem grafiskt?

I stället för att utveckla din egen kan du bara använda Node-RED.

Node-RED gör det väldigt enkelt för dig att ta data från HiveMQ och sedan presentera den med hjälp av grafiska representationer.

Vi ska göra en mätare med hjälp av Node-RED.

För att börja behöver du ha nodejs. Kontrollera HiveMQ:s dokumentation för att se vilken version som rekommenderas.

När du har installerat Node måste du öppna en kommandotolk/terminal och köra de här kommandona (uteslut sudo om du använder Windows):

sudo npm install -g --unsafe-perm node-red

Detta kommer att använda Node Package Manager (npm) för att installera Node-RED globalt.

Kör sedan Node-RED genom att skriva node-red i Terminal/kommandotolken.

Öppna din webbläsare och gå till http://127.0.0.1:1880 eller den adress som anges i din terminal.

Låt oss bygga upp flödet. Dra en "mqtt in" till Canvas. Du hittar den under fliken "network" i vänstra sidofältet.

Vi måste konfigurera fliken, så dubbelklicka på rektangeln och gör följande:

I fältet "topic", se till att lägga till picow/brightness, eftersom det är vad du publicerade från Pico W.

I "server" lägger du till en ny genom att klicka på pennikonen så kommer du till nästa meny.

Lägg in en ny serveradress och ändra porten till 8883. Kryssa i "Use TLS" men bry dig inte om att lägga till ny tls-config.

Gå sedan till säkerhetsfliken och lägg till dina inloggningsuppgifter.

Alla dessa detaljer finns i din kod när du initierar MQTTClient.

Lägga till en mätare

För att lägga till en mätare måste du ha nod-röd-tavla.

På vänster sidofält, om du inte ser dessa:

Gå sedan till menyn (övre högra knappen) -> Hantera palett. Gå sedan till fliken Installera och sök efter node-red-dashboard. Klicka på "Installera".

Dra och släpp en "mätare" till höger om mqtt i rektangel, och koppla ihop dem genom att dra en linje från mqtt i till mätaren.

Dubbelklicka på mätrektangeln och ändra etiketten till "brightness" och "range" max till 65535.

Jättebra. Nu trycker vi på "Deploy".

Om inställningarna var korrekta kommer du att se en grön cirkel och "connected" under rektangeln. Om inte, kommer din terminal att ge dig mer information om varför det finns ett fel.

Nu när din Pico W levererar data till HiveMQ Cloud är det dags att kolla in instrumentpanelen. Besök http://127.0.0.1:1880/ui och du bör se att mätaren uppdateras ofta.


Dina förslag är välkomna.

Lämna en kommentar i kommentarsfältet nedan!

6 Kommentarer

  1. Quang den januari 10, 2023 kl 2:21 e m

    Hallå?
    Tack för att du delar med dig av din kunskap till oss.
    Kan du berätta om WiFi-övningarna endast gäller inom nätverket? Jag kunde inte komma åt Pico W om jag var på ett annat WiFi-nätverk. Om så är fallet, har du några exempel på åtkomst utanför nätverket?
    Tack så mycket.

    • raspi berry den februari 4, 2023 kl 11:52 f m

      Ja, på grund av nätverkens, routrarnas och brandväggarnas natur fungerar dessa övningar endast inom samma WiFi-nätverk.
      PiCockpit är i sig en lösning som sträcker sig över nätverk - du kan komma åt din Pico W från var som helst på Internet.
      Vi arbetar med att ta fram fler funktioner till plattformen.

      Om du vill återskapa något liknande själv måste du ha någon form av tunnellösning till ditt nätverk, eller en reläserver eller något liknande.
      Vi erbjuder konsulttjänster om du vill gå djupare in i detta ämne.

  2. Peter Mayr den mars 29, 2023 kl 10:44 f m

    Tack för den här fantastiska handledningen.
    Tyvärr fungerar det inte.
    Jag har fastnat i slutet av del "1. Servera en webbsida som säger "Hello World" på Pico"

    Mina webbläsare Firefox och Chrome säger bara "Error connection interrupted".
    I Thonny ser jag

    Ansluten
    ip = 192.168.188.198
    Lyssnar på ('0.0.0.0', 80)
    Klient ansluten från ('192.168.188.100', 54025)
    Anslutningen är stängd

    Connection closed kommer ett par gånger.
    Vad kan jag ändra för att få min Pico W att fungera?
    Tack på förhand för din hjälp.
    Hälsningar Pete

  3. mokcp den maj 3, 2023 kl 10:58 f m

    När du kör main.py finns det ett felmeddelande, hur kan jag lösa det.

    Fil "", rad 1, i
    ImportError: ingen modul med namnet 'wifi'

    Tack på förhand.

    • PiCaptain den maj 10, 2023 kl 12:31 e m

      Du måste skapa och lägga till wifi.py - som visas lite högre upp på sidan. Utan wifi.py kommer koden inte att fungera.

  4. màn hình led den augusti 26, 2023 kl 2:18 e m

    Handledningen "Raspberry Pi Pico W komponenter för nybörjare" är en fantastisk guide för dig som är ny på Raspberry Pi Pico W-plattformen. Handledningen är välstrukturerad och lätt att följa, vilket gör den idealisk för nybörjare. Den täcker viktiga komponenter och ger tydliga instruktioner, vilket gör den till en bra utgångspunkt för alla som vill utforska den här tekniken. Detaljerade förklaringar och bilder förbättrar inlärningsupplevelsen och säkerställer att läsarna snabbt kan förstå begreppen. Sammantaget är denna handledning en värdefull resurs för dem som vill komma igång med Raspberry Pi Pico W och dess komponenter.

Lämna en kommentar