Tutorial de componentes para principiantes do Raspberry Pi Pico W

tutorial de componentes de framboesa pi pico w

Este tutorial de componentes para principiantes do Raspberry Pi Pico W vai ensinar-lhe como interagir com o microcontrolador para interagir com componentes simples como LEDs, sensores ultra-sónicos e muitos outros itens encontrados num kit para principiantes.

Se for um principiante completo, este tutorial ajudá-lo-á a compreender MicroPython para que possa ler, escrever e modificar o código. Com este conhecimento, poderá combinar código e componentes para criar algo que tenha um caso de utilização no mundo real.

Se vier de um Pico, este tutorial ensinar-lhe-á como controlar o Pico W sem fios. Anteriormente, só se podia interagir com o Pico através de um interruptor, botão ou algum dispositivo de interacção física. Já não! Agora pode controlar os componentes com o seu telefone ou desktop.

Fluxo tutorial

Introdução

  1. Pinos de cabeçalho de soldadura
  2. Usando Thonny
  3. Actualização do seu firmware

O tutorial "Olá Mundo" para o Pico W

  1. Servir uma página web que diz "Olá Mundo" no Pico
  2. Controlo de um LED sem fios

Um passo acima

  1. Controlo RGB LED sem fios
  2. Operação Buzzer no Pico W

Formas básicas de transmissão de dados do sensor

  1. Sensor ultra-sónico Pico W e HC-SR04
  2. Transmitir uma página web com dados de sensores
  3. Redução da carga útil com AJAX
  4. Pimoroni Phew para racionalizar a codificação do ponto final

Ligação a utilitários web

  1. Registar os dados climáticos do sensor DHT22 no Google Sheets com IFTTT
  2. Construir um Spotify remoto com funções play/pause/skip

Controlo sem código GPIO com PiCockpit

  1. Instalação super simples do PiCockpit no Pico W
  2. Controlo LED simples com PiCockpit e Pico W
  3. Pico W, ventilador 5V e um transístor, controlado por PiCockpit

MQTT

  1. Exibir fotossistor usando MQTT e Node-RED com Pico W

Índice

Conteúdo esconder

Objectivos tutoriais em resumo

  • Aprender a interagir com componentes fundamentais que constituem projectos de maior dimensão
  • Controlar todos estes sem fios - sem interruptores, botões ou outros dispositivos de interacção.
  • Ganhar uma melhor compreensão dos pontos fortes do Pico W

Ligações importantes

Github repo para código tutorial (excepto secrets.py)

Documentação MicroPython

Erros, sugestões, comentários? Deixe um comentário na caixa de comentários abaixo, envia-me um e-mail ou Tweet me.

OSError: [Errno 98] EADDRINUSE

Se receber este erro, basta desligar e ligar o seu Raspberry Pi Pico.

Também pode fazer isto digitando estes comandos em Thonny's Shell:

import machine
machine.reset()

Resultado:

Pinos de cabeçalho de soldadura

Quando compra um Raspberry Pi Pico W, este pode não vir com cabeçalhos que lhe permitam ligar componentes ao seu Pico.

No momento da redacção, o Pico WH (H para cabeçalhos) ainda não foi lançado. O nosso mega-artigo do Pico W está a acompanhar a sua libertação.

Se, no entanto, encontrar um Pico W com cabeçalhos pré-soldados, aconselho-o a comprá-lo.

No entanto, para o resto de nós, soldar cabeçalhos no Pico W é uma coisa simples de se fazer. Vai precisar:

  • Tabuleiro do pão
  • Ferro de soldar e solda
  • Cabeçalhos

Quando comprar os seus cabeçalhos, certifique-se de comprar um que se destina ao Pico W. Ao contrário dos cabeçalhos da série Pi Zero-série Raspberry, os cabeçalhos do Pico W não estão lado a lado. Estão em extremos opostos do quadro.

Uma tábua de pão, as cabeças do Pico W e 2×20 pinos

Os pinos têm um lado longo e um lado curto. Vai querer que os pinos mais compridos estejam no lado onde vê as etiquetas GPIO (GP0, GP1, GND, VBUS, VSYS, etc.)

Vai querer que os pinos mais compridos fiquem do lado oposto onde se encontra o conector USB.

Por conseguinte, inserir os pinos mais compridos na tábua de pão. Serão necessários quatro buracos' e um espaçamento entre eles. Se não tiver a certeza, teste com o seu Pico W.

A soldadura é fácil. Certifique-se de que o seu ferro de soldar está quente, e certifique-se de utilizar a ponta do ferro de soldar.

O que achei mais eficaz foi colocar a ponta do ferro de soldar perto do pino, pôr a solda a tocar na ponta e vê-la fluir para baixo do pino e criar uma ligação.

Após a soldadura, certifique-se de verificar e de que não há nenhuma solda estranha que possa estar a ligar dois pinos GPIO juntos ou algum resíduo de solda que esteja na sua placa.

Use Thonny como seu editor de código

Thonny programando um Raspberry Pi Pico W

Thonny continua a ser a forma mais fácil de programar o seu Raspberry Pi Pico W.

Se estiver a utilizar o SO Raspberry Pi, já o teria instalado.

No entanto, se estiver a utilizar Windows ou Mac, terá de descarregar e configurar o mesmo.

Aqui está um guia que o guiará através dos degraus.

Assegure-se também de consulte o guia sobre como carregar ficheiros no seu Pico W.

Actualize o seu firmware carregando o mais recente UF2

Quando compra o seu Pico W, pode já ter o firmware desactualizado.

Muitas alterações estão a chegar ao Pico W, por isso é ideal actualizar agora o seu firmware.

Algumas mudanças que tenho visto desde o dia do lançamento são melhorias na função de ponto de acesso da WLAN, e futuras actualizações poderiam desbloquear a função Bluetooth no quadro.

Actualizar agora! Aqui está um guia no nosso mega-artigo.


1. Servir uma página web que diz "Olá Mundo" no Pico

O projecto "Olá Mundo" do Raspberry Pi Pico W

Um dos projectos mais fundamentais em todos os tutoriais de programação é o projecto "Hello World".

O "Hello World" de um microcontrolador geralmente envolve piscar um LED. É super fácil. Aqui está como.

No entanto, como o Pico W pode servir uma página web, comecemos por aprender a servir uma página web que tenha uma mensagem "Olá Mundo".

A configuração aqui utilizada constituirá o bloco de construção mais fundamental para o resto dos tutoriais.

Há duas maneiras de se ligar ao Pico W. Pode fazê-lo aderir a uma rede WiFi ou pode emite um hotspot SoftAP semelhante ao que o seu smartphone faz. Se quiser experimentar este último, siga esta ligação. No entanto, por uma questão de coerência ao longo deste tutorial, ligar-nos-emos sempre a uma rede WiFi em vez de a difundirmos a partir do Pico W.

Assim, fundamentalmente, os passos para servir uma página web envolvem:

  • Ligação a WiFi
  • Escrever código para servir index.html a qualquer pessoa que se ligue ao endereço IP do Pico W

Vamos criar alguns ficheiros. Guarde-os e carregue-os para o seu Raspberry Pi Pico W. Veja aqui como carregar ficheiros, no caso de não o ter visto.

wifi.py

wifi.py é uma placa de caldeira destinada a ajudá-lo a ligar-se à sua rede WiFi. Criar um ficheiro separado e importá-lo para main.py mais tarde, ajudará a reduzir o código desordenado.

Note que deve alterar o código do seu país na linha rp2.country('DE') se o seu país não for a Alemanha.

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 importações secrets.pyonde guarda as informações da sua rede WiFi.

secrets.py é um simples ficheiro JSON que contém o seu SSID WiFi e palavra-passe.

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

serve_webpage.py

Como o nome sugere, esta página serve os sítios web aos utilizadores que se ligam ao Pico W.

Ao receber uma ligação, o Pico W encontra um ficheiro chamado index.html e envia-o para o cliente ligado, como se vê na linha resposta = 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')

Finalmente, precisamos de criar o index.html ficheiro que será enviado para um cliente ligado.

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

Esta é uma simples placa de caldeira HTML com duas alterações: uma para a <title>tag que produz "Pico W" como título e a tag <h1> que diz "Olá Mundo".

main.py

Uma vez que colocámos todo o código noutro lugar, o nosso main.py só tem de importar e chamar estas funções a fim de servir a página web Hello World.

Como pode ver, inicializamos primeiro o WiFi antes de servir a página web.

from wifi import init_wifi
from serve_webpage import serve_webpage

init_wifi()
serve_webpage()

Está quase lá!

Referindo-se à captura de ecrã abaixo, certifique-se:

  • Carregou cinco ficheiros no seu Raspberry Pi Pico W (ver caixa vermelha inferior esquerda)
  • Assegure-se de que o seu intérprete está preparado para MicroPython (Raspberry Pi Pico) (ver caixa inferior direita)
  • Em seguida, destacar o main.py no seu editor de código, e clique no botão verde de execução (caixa superior esquerda vermelha)
  • Uma vez executado isto, verá o seu endereço IP na Shell. Vá ao seu navegador e digite este endereço e verá a página web Hello World.
  • Se a sua concha não estiver aberta, vá a View -> Shell.

Se tudo for bem sucedido, verá a página abaixo.


2. Controlo de um LED sem fios

Agora que já tem as bases estabelecidas, vamos dar um passo em frente.

Um dos projectos mais fundamentais do Raspberry Pi envolve piscar um LED.

Vamos aumentar esse nível controlando o LED sem fios. Queremos ser capazes de piscar, ligar e desligar o LED.

Para o fazer, terá de configurar um circuito e um servidor web com três botões - ON, OFF, BLINK.

Para este projecto, será necessário um LED, uma resistência de 330 ohm, um fio de jumper e uma tábua de pão.

Usaremos um LED vermelho porque a maioria dos kits o terá. Note que se usar um LED de qualquer outra cor, terá de ajustar a resistência.

Aqui está como ligar os componentes

  • GPIO 2 -> Perna longa de LED (ânodo/positivo)
  • GND -> resistor de 330 ohm -> perna curta de LED (catódico/negativo)

Código para controlar o LED no Pico W

Vamos construir com base no que fizemos no tutorial anterior. Os únicos dois ficheiros que teremos de modificar são index.html para adicionar botões e main.py para interagir com o LED com base na entrada do index.html.

As partes que são ousadas indicam as novas linhas que foram acrescentadas a index.html. Acrescentam três botões e um parágrafo que diz "Controlar o 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>

Note que ao premir os botões, verá um parâmetro adicionado ao endereço IP do seu Pico W (por exemplo http://192.168.43.134/%22?led=blink\). Estes parâmetros são capturados pelo backend do Pico W e controla o LED.

Vamos avançar serve_webpage.pys no código main.py ficheiro.

Aqui está 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')

O primeiro, e chave, segmento está abaixo:

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

A variável "request" (pedido), quando impressa, produz o primeiro bloco de texto abaixo. As últimas três linhas são as declarações de impressão que verificam se o LED está ligado, desligado ou pisca-pisca:

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

O código acima tentará pesquisar cadeias específicas, tais como "led=em“. Se existir, o valor será superior a -1, desencadeando assim o respectivo se declaração.

Por exemplo, se led=on existir nos parâmetros, então a variável led_on será mais de -1, portanto a se led_on > -1 a declaração desencadeia e corre led.on();

A única parte complicada aqui é a led_blink função que irá desencadear a função:

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

Finalmente, eis como se inicializa o GPIO 2 para operar o LED:

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

Importamos máquina para interagir com o pino GPIO. Como se pode ver na variável conduzidoqueremos que o Pico W energize a GPIO 2.

Importamos hora para que possamos ter uma pausa de 0,2 segundos em blink_led().


3. LED RGB no Pico W

Para iluminar o seu LED RGB, precisa:

  • Três resistências de 330 ohm
  • Um LED RGB
  • Um fio de jumper

No LED do RGB, encontrará quatro pernas. Uma perna será a mais longa. Ou é um cátodo (negativo) ou um ânodo (positivo). O meu RGB LED tinha um cátodo partilhado, por isso aqui está a ligação:

A imagem mostra as pernas R, G, B num LED RGB catódico comum. (Imagem da Fundação Raspberry Pi CC-BY-SA)
  • GPIO 15 -> resistência de 330 ohm -> LED vermelho
  • GPIO 17 -> resistor -> LED verde
  • GPIO 16 -> resistor -> LED azul

Aqui está um código para ver se o ligou correctamente:

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)

Neste exemplo, estamos a utilizar PWM, o que lhe permite variar o brilho dos LEDs R, G, B.

Pode alterar os valores passados para [cor].duty_u16 para um valor entre 0 e 65534. Teoricamente, deverá ser capaz de passar 65535, mas de alguma forma isso não parece funcionar para mim.

Pense em passar "0" como se quisesse um brilho de zero por cento. Se passar "65534", quer 100 por cento de brilho.

Se fizer 65534 para uma cor e zero para o resto, poderá dizer se ligou os pinos GPIO correctos à cor LED correcta.

Então porque é que estamos a usar PWM? Porque o ajudará a obter mais cores. Se utilizar apenas um método "ligado e desligado", pode obter vermelho, verde, azul, branco-esbranquiçado e sem luz. Com o PWM, pode variar a intensidade do LED R, G, B e criar tantas cores quantas possa imaginar.

Agora, vamos criar algo que se possa controlar sem fios!

index.html

A principal mudança aqui é ter um <form> que tem três barras deslizantes. Estes deslizadores têm um valor entre zero e 100.

A utilização de valores de zero a 100 ajuda-o a visualizar o brilho como uma percentagem. Também reduz a quantidade de código necessária para separar o valor dos parâmetros (visto mais à frente em main.py)

Quando tiver definido os valores para os LEDs R, G, B, premir para enviar, e estes dados são capturados pelo 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')

À medida que se vai submetendo no index.html a página web, o Pico W tomará os parâmetros e processá-la-á.

Vejamos alguns pontos-chave do código, em negrito no bloco de código acima.

função find_intensity

Esta função requer dois paramédicos: cor e request_str. cor recebe "vermelho", "verde" ou "azul" e encontra o valor após o sinal de igual (=).

Por exemplo, o seu URL depois de submeter o formulário é "http://192.168.1.142/?red=89&green=50&blue=50".

Se passar "vermelho" para encontrar_intensidade, ele retornará 89.

analisador de intensidade

O segundo bloco de código em negrito representa o código que diz ao GPIO do Pico W quanto brilho quer de cada LED.

Em primeiro lugar, temos de assegurar que os param no URL. Isto é feito pelo se declaração request_str.find('red') > -1. Acabei de usar vermelho porque o 100% conterá a corda "vermelha" se utilizar o formulário.

Se estiver a visitar o endereço IP do seu Pico W (por exemplo http://192.168.1.142/) pela primeira vez, não terá os param, por isso o programa irá falhar se correr find_intensity.

Se os parâmetros existirem, encontramos a intensidade para cada LED de acordo com os valores apresentados. Vamos dar uma vista de olhos a red_intensity.

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

find_intensity devolve um zero inteiro a 100. Dividimos isto por 100 para que se possa obter uma percentagem. Esta percentagem divide o valor máximo que o duty_u16 método pode ser utilizado.

No entanto, precisamos de um int função para embrulhar isto porque pode obter um carro alegórico por vezes e duty_u16 precisa de um int. Por exemplo, digamos que queria 41% de brilho - 41% de 65534 é 26.868,94. Não pode passar este carro alegórico pois o programa irá falhar.


4. Operação de campainha no Pico W

Uma campainha é um componente bastante importante para notificações básicas, tal como um LED pode dizer-lhe sobre o estado de algo, uma campainha dá-lhe uma notificação auditiva.

Ligar o terminal positivo da campainha ao GPIO 16 e aterrar a um pino GND no Pico W.

Em vez de implementar o meu próprio código, optei por utilizar A implementação de Giuseppe Cassibba. Se passar o seu código no Pico W, ouvirá bipes na sua campainha.

Mas uma vez que este código se destina ao Pico, não terá quaisquer características de interactividade sem fios.

Então, vamos tirar o garfo para fora!

Primeiro, vamos modificar o index.html para implementar os botões. Vamos ter um botão para "ON", "OFF", "SCALE", "MUSIC".

Os dois primeiros botões são auto-explicativos. O terceiro botão toca uma escala C e o último toca uma peça de música.

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

Tal como antes, criamos alguns <button> etiquetas com <a> etiquetas que os rodeiam. Ao clicar nos botões, o URL terá um parâmetro tal como /buzzer=em. O Pico W lê isto e acende a campainha.

Agora, vejamos o código de Giuseppe para o 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()

O seu código toca uma escala C quando executado utilizando a função campainha()que aceita quatro parâmetros: Objecto da campainha, frequência em Hertz, duração do som e duração da pausa antes de tocar o som seguinte.

Vamos modificar o código para que possamos activar o ON, OFF, ESCALA e MÚSICA.

Eis como integramos o código de Giuseppe no nosso 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')

Na implementação acima referida, não escrevemos o código para MÚSICA.

O código é muito semelhante ao tutorial do LED vermelho acima, onde o Pico W captura os parâmetros após o endereço IP do Pico W. Se o parâmetro campainha=ON, tocará um som de 440Hz. Se campainha=escala, jogará a escala que é retirada do código de Giuseppe.

E a implementação da música? A implementação de música é um pouco mais complicada, por isso devemos criar um novo ficheiro chamado constants.py e acrescentar algumas linhas no nosso main.py.

Este código é uma bifurcação de O código Arduino de Rowan Packard.

constants.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 (adições em negrito)

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

Como se pode ver, existem duas matrizes, music_notes e ritmo. Depois, seria feito um laço para colocar estes valores no campainha() função. Além disso, na parte superior do código, importamos todas as variáveis de constants.py.

O campainha() a função também utiliza duas novas variáveis - t e pausa. Estas duas variáveis ajudam a afinar o ritmo da música. t define quanto tempo cada nota deve ser tocada e pausa define quanto tempo de silêncio deve haver entre as notas.


5. Sensor ultra-sónico Pico W e HC-SR04

pico-w-ultrasonic-sensor
`

Para os tutoriais anteriores, temos utilizado o Pico W para enviar comandos para os LEDs e buzzers.

Mas e se estivermos a utilizar o Pico W para receber informações?

Neste caso, estamos a falar do sensor de distância ultra-sónico HC-SR04.

Quando ligar o seu sensor ultra-sónico, certifique-se de saber se é um componente de 5V ou 3,3V. Liguei a minha versão de 5V ao pino de 3.3V e não obtive resposta do programa, que partilharei abaixo. Assim que movi a fonte de alimentação para o pino de 5V, obtive imediatamente uma resposta.

Aparentemente, algumas versões mais recentes do HC-SR04 podem levar tanto 3,3V como 5V. Talvez seja melhor experimentar primeiro o pino de 3,3V e ver se se obtém um resultado. Se não, tente o de 5V.

Aqui estão os esquemas e o programa que pode executar em Thonny. Se obtiver uma resposta, isso significa que ligou tudo da forma correcta, incluindo a voltagem.

Cablagem

Os cabos dos pinos rotulados dos sensores HC-SR04 são os seguintes:

  • VCC a 3.3V ou 5V pino (em caso de dúvida, tente 3.3V primeiro)
  • TRIG para GPIO 16
  • ECHO para GPIO 15
  • GND para GND

Programa de teste para HC-SR04

Para testar se a sua cablagem está correcta, tente este código que irá imprimir a distância na 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)

A sua produção deve ser:

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

Se o programa correr e sair sem qualquer saída, provavelmente ligou algo de errado. Quando liguei o sensor a um pino de 3,3V em vez de um de 5V, o programa desistiu sem resposta.

Receber dados enviados para o seu navegador

Vamos arranjar os ficheiros que usávamos para servir uma página web e modificá-la para que possamos ver os valores da distância.

Aqui está o código final:

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>

Vejamos alguns trechos do código para compreender o que está a acontecer.

Código para obter distância ultra-sónica

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

O bloco de código acima desencadeia a emissão de uma onda ultra-sónica. O tempo.sono entre os baixos e os altos são necessários para o funcionamento do sensor ultra-sónico.

Para medir quanto tempo leva entre a emissão da onda ultra-sónica e o tempo para a onda sonora regressar, utilizamos time.ticks_us para medir o tempo de emissão e o tempo para o eco ser detectado.

time.ticks_us é um número arbitrário, pelo que teremos de subtrair signalon a partir de signaloff para que o tempo passe.

Para obter a distância, usamos a fórmula distância = (timepassed * speedofsound) / 2. A velocidade do som é de 340m/s, que por conseguinte é de 0,0340.

A razão pela qual temos de o dividir por dois é porque a onda sonora viaja até ao objecto e regressa.

Código para servir página web com valor à distância

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

Esta função foi modificada um pouco em relação aos tutoriais anteriores, tendo em conta um parâmetro adicional distânciaque funciona ultra-sónico().

A função abre o index.html normalmente, mas utiliza o ficheiro substituir método para encontrar o <h2> e insere o distância variável.

index.html servidor de pings a cada 500ms para obter um novo valor

index.html

A página web principal recebe uma função que recarrega a página web a cada 500ms. Cada recarregamento faz o Pico W para obter o novo valor da distância ultra-sónica.

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

6. Dados ultra-sónicos, mas vamos usar AJAX para reduzir a carga útil

O tutorial anterior funciona fazendo com que o Raspberry Pi Pico W envie um novo index.html arquivar cada vez que há uma ligação.

Isto funciona mas é incrivelmente ineficiente porque o conjunto index.html está a ficar ressentido quando só precisa de actualizar os dados da distância ultra-sónica.

Queremos os mesmos resultados que o tutorial anterior, mas sem a pesada carga útil do método anterior.

Portanto, precisamos de fazer com que o cliente (o seu telefone ou PC) pingue um ponto final que responderá apenas com os dados ultra-sónicos.

A nova metodologia é a seguinte: se as pessoas visitarem o URL de raiz, digamos 192.168.1.119, ser-lhes-á servido o index.html.

index.html terá Javascript que pingará o /dados o que desencadeia o Pico W para obter dados de distância ultra-sónicos, e responder com eles.

Então, index.html receberá estes dados e actualizará a página web.

Emendando o pedido do cliente

Lembre-se que no main.pyhá sempre uma frase que diz pedidos = cl.recv(1024). O objecto de pedido parece-se um pouco com isto:

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

Em primeiro lugar, precisamos de filtrar esta parede de texto.

Utilizamos o find() método para descobrir se o pedido variável tem "/dados". Se tiver, responder com os dados da distância ultra-sónica. Se não houver "/dados", então responda com index.html.

Antes de

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

Depois de

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

Se visitou /dados no seu navegador, verá o valor da distância impresso, como abaixo.

Anteriormente, o backend tratava de quase tudo. A distância ultra-sónica foi modificada antes de ser servida como index.html.

Agora, index.html está a ir buscar os dados do sensor ao Pico W, por isso teríamos de fazer algumas alterações ao JavaScript que está dentro do ficheiro HTML. As alterações estão destacadas em negrito.

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

No centro do código aqui está o Buscar API e o mais recente async/await sintaxe aqui.

A função getData() pings o Pico W's /data endpoint, e o Pico W responde. Asseguramos que o programa não salta à frente antes de recebermos uma resposta completa, pedindo-lhe que aguarde.

Fetch torna-se um objecto de resposta que terá de usar o método Response.text() para chegar ao corpo da resposta. Daí as linhas const distância = aguardar data.text();

Assim que tivermos os dados ultra-sónicos, alteramos o <h2 id="”ultrasonic”"> HTML interno do elemento, que começa vazio, com os dados da distância. É possível apontar um elemento com um id directamente sem utilizar o getElementById() ou querySelector() métodos.

Uma vez terminado todo o código, queremos executar novamente getData(). Porque é que utilizei um setInterval para estabelecer um intervalo de 100ms?

O que descobri é que se chamar getData() sem um intervalo, obterá mais pausas entre as saídas. Receberá uma sequência de actualizações rápidas, depois uma pausa. Com os 100ms de espaço para respirar, o Pico W funciona um pouco melhor e as actualizações parecem ainda mais ou menos em tempo real.

Se quiser compreender o que está a acontecer debaixo do capuz, consulte o Buscar documentação API e o async/await documentação.


7. Pimoroni Phew para código de limpeza

Pimoroni Phew a ser utilizado para fornecer dados ultra-sónicos

Na última secção, cobrimos o método AJAX de actualização dos dados dos sensores ultra-sónicos.

Mas haverá uma maneira ainda melhor de o fazer?

Pimoroni's Phew é uma biblioteca que o ajuda a fazer muito networking facilmente porque pode evitar muita drogaria.

Os objectivos são os mesmos:

  • Obtenha dados ultra-sónicos e exiba-os em index.html
  • Manter a carga útil tão baixa quanto possível.

Eis como main.py parece.

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

Como pode ver, o código é muito mais legível, uma vez que pode definir pontos finais e ligá-los com funções que devolvem dados específicos.

Em vez de se enrolar com o código para executar as tomadas, bastava chamar uma função da biblioteca de Phew.

Algumas coisas que são como as de Phew são:

  • Acabou-se o uso de request.find() para criar um ponto final
  • Não mais get_html() função para abrir a index.html utilize apenas o ficheiro Phew's render_template()
  • main.py é muito mais fácil de ler, com um esforço adicional mínimo!
  • Phew também acrescenta a funcionalidade de registo que lhe permitirá depurar o seu código mais facilmente.

A única desvantagem é que Phew ainda é "um projecto muito novo e deve ser considerado, na melhor das hipóteses, uma fase alfa". Por isso, poderá por vezes encontrar bloqueios de estradas inesperados.

Veja isto.

Os tutoriais anteriores falavam sobre como interagir com o seu Pico W com o seu PC/telefone móvel.

Vamos dar um passo fora disto e fazer com que o Pico W interaja com um serviço de nuvem.

Para isso, vamos fazer um registador de temperatura e humidade com um sensor DHT22 que envia dados para o Google Sheets via IFTTTT.


8. Configuração do sensor de temperatura e humidade DHT22 para o Pico W

Raspberry Pi Pico W emparelhado com um registador de temperatura e humidade DHT22.

Todos estes passos funcionam para o DHT11 e DHT22. A principal diferença entre os dois é a exactidão das leituras. O DHT11 é de cor azul enquanto que o DHT22 é branco.

Se tiver um DHT11, note que as referências ao DHT22 no código devem ser alteradas para DHT11. Por exemplo,

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

Olhando para o diagrama abaixo, de cima para baixo do DHT22, ligar-se-ia 3,3V ao primeiro pino.

O segundo pino é o pino de dados. Seria necessário alimentá-lo. Assim, ligar-lhe uma resistência de 10K ohm da calha de alimentação, e depois ligar outro fio de jumper ao GPIO 16 no Raspberry Pi Pico.

A GND vai para a GND.

Para testar o sensor, executar isto:

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

Se obtiver OSError: [Errno 110] ETIMEDOUT significa que está a executar o guião demasiado cedo. O DHT22 requer uma pausa de dois segundos antes de poder devolver outro valor. O DHT11 requer um segundo.

Ligação de IFTTT e Google Sheets

Pico W registo de dados de tempo, temperatura e humidade no Google Sheets

A forma mais fácil de obter dados do Pico W ao Google Sheets é através do IFTTT.

Primeiro, inscrever-se na conta IFTTT.

Depois, clicar no botão "Criar" para criar a applet.

Verá este ecrã:

Clicar em "Se Isto" e pesquisar por "Webhooks". Clicar em "Receber um pedido da Web". Não escolher a do JSON. Nomear o nome do evento "dht22". O nome do evento é crítico porque é assim que o IFTTT sabe qual o applet a activar.

Escolha esta, não a opção de carga útil do JSON.

O que está a fazer aqui é criar um ponto final que pode pingar com os dados dos sensores do DHT22.

Depois, clique em "Then That". Escolher "Google Sheets". Depois, escolher "Adicionar linha à folha de cálculo". Teria de ligar a sua conta Google Sheets.

Altere o "Nome da folha de cálculo" e "Caminho da pasta de condução" para o que quiser. A única coisa crítica aqui é a "Fileira formatada", onde vai querer que seja

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

Agora, terá de ir buscar o ponto final para onde o Pico W pode enviar os dados dos sensores.

Ir para https://ifttt.com/maker_webhooks e clique em "Documentação".

A documentação dir-lhe-á a sua chave, o ponto final para o qual necessita de enviar dados e como estruturar o corpo do JSON.

Uma vez que usou "dht22" como nome do seu evento, o seu ponto final é:

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

Também vai querer estruturar o seu corpo JSON desta forma:

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

Codificação do Pico W para obter dados DHT22 e enviá-los ao IFTTT

Eis como.

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

Se vai copiar este código, não se esqueça de substituir [a_chave_a_aqui] na request_url variável.

Deverá obter uma nova leitura a cada minuto que for registado no Google Sheet, como abaixo indicado.

Pico W registo de dados de tempo, temperatura e humidade no Google Sheets

Note-se que a temperatura registada está em Celcius. Se a quiser em Fahrenheit, aqui está a fórmula:

fahrenheit = dht22.temperature() * 1.8000 + 32.00

Se quiser que os dados sejam registados com maior (ou menor frequência), altere o valor em tempo.sono().

Utilize o IFTTT para o notificar se ocorrer um erro

É claro que este código ainda é bastante frágil.

Digamos que algo não corre bem. Por exemplo, o seu gato puxou o fio de 3,3V enquanto o senhor colocava no chão para registar a temperatura.

O programa morrerá, mas não receberá qualquer notificação até que note que os seus dados não estão a ser registados.

Como se resolve isto?

Bem, peça ao IFTTT para lhe enviar uma notificação quando isso acontecer!

Precisaria da aplicação IFTTT no seu telefone. Por isso, descarregue-a.

Depois, criaria um novo applet.

Para a "Se Isto" parte, Escolha Webhooks -> Receber um pedido web. Dê um nome ao seu evento "erro“.

Para o "Então isto". parte, escolha "Notificações" e "Enviar uma notificação da aplicação IFTTT"..

Tornei a mensagem simples

Error: {{Value1}}

Agora, vamos construir os blocos de tentativa-erro.

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)

Experimente-o. Desligue o fio 3.3V do seu DHT22 e receberá uma notificação como tal:


9. Construir um controlo remoto Spotify físico com Raspberry Pi Pico W

Com base no projecto anterior, utilizaremos o IFTTT para controlar o Spotify.

Vamos criar um dispositivo que tenha um botão de play, pause e salte o track.

O principal benefício de usar o IFTTT para controlar o seu Spotify é como é fácil.

A desvantagem é que precisa de uma conta Spotify paga e as respostas são lentas. O que significa que se premir o botão de saltar, terá de esperar um pouco antes de ver o resultado.

A beleza de ter um Spotify remoto dedicado é que pode mudar a sua música sem carregar o seu telefone por perto ou ter de abrir a aplicação Spotify.

Se alguma vez conduziu um carro moderno, saberá como é bom ter comandos no volante.

Ligação de um controlador Spotify remoto

Spotify Raspberry Pi Pico W controlador
Spotify Raspberry Pi Pico W controlador. De cima para baixo, os botões são pausar, tocar, saltar pista.

Vai precisar...

  • 7x fios de jumper
  • 3x botões
  • Framboesa Pi Pico W
  • Spotify conta paga

Há muitos fios cruzados lá em cima na imagem, por isso aqui está uma explicação textual.

Os botões de pressão são como interruptores. É necessário ligar o pino de 3V3 a cada um deles, o que significa utilizar a coluna positiva na tábua de pão. Portanto:

3V3 -> Coluna positiva da placa de pão -> Botão de pressão (de um lado da calha da placa de pão) -> GPIO (do outro lado)

O meu código utilizará GPIO 16 para o botão play, GPIO 2 para o botão pause e GPIO 15 para o botão skip track.

Criação do IFTTT para controlar o Spotify

Vamos criar três applets de IFTTT para controlar Spotify.

Temos de criar três applets, um para cada peça de teatro, pausa e função de saltar.

Se tiver a versão premium do IFTTT, provavelmente poderá usar os filtros JavaScript para conter tudo numa única aplicação. Mas como não temos, precisamos de um applet cada um.

Uma vez conectado, clique em "Criar" no canto superior direito do menu principal.

Na barra "Se Isto", clicar sobre ela e procurar por ganchos da Web.

Clique em "If This" ou "Then That" e escolha "Webhooks" e "Spotify" respectivamente.

Depois, clicar em "Receber um pedido da web" (não a outra opção que tem "com uma carga útil JSON").

Para nome do evento, digite spotify_skip.

Terá de repetir esta etapa duas vezes mais para spotify_pause e spotify_play uma vez terminada a criação desta applet.

Uma vez isso feito, vá para o "Então que" e clique sobre ela. Pesquisar por "Spotify“.

Terá de autorizar o IFTTT a ligar-se ao Spotify uma vez.

Se estiver a fazer o spotify_skip acção, vai querer clicar em "Saltar faixa". Mas se estiver a fazer um applet para fazer alguma outra acção, a imagem acima mostrar-lhe-á qual utilizar.

Uma vez criadas as três applets, é tempo de codificar!

Codificação do Spotify remoto para o Pico W

Em primeiro lugar, é preciso saber o ponto final a atingir.

Ir para esta página e clique no botão Documentação.

Verá aí a sua chave. Se tiver seguido todos os passos acima, a diferença entre o seu ponto final e o meu é a sua chave. Daí,

Ponto final de jogo: https://maker.ifttt.com/trigger/spotify_play/with/key/[your_key_here]

Pausa: https://maker.ifttt.com/trigger/spotify_pause/with/key/[your_key_here]

Saltar: https://maker.ifttt.com/trigger/spotify_skip/with/key/[your_key_here]

Código

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)

Vamos analisar o código.

Note que terá de substituir [a_chave_a_aqui] com a sua verdadeira chave, tal como obtida através do Documentação ligação.

Em primeiro lugar, declaramos variáveis para os botões de pressão.

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)

Actualmente, se não pressionar o botão, a sua variável terá um valor de 0. Se o premir, ele torna-se 1. Isto é o que vamos usar para desencadear o peça() , pausa() e skip() funções.

Depois, criamos funções para o jogo, pausamos e saltamos os pontos finais. O modelo geral é como tal:

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)

É bastante simples. Se esta função for executada, enviará um pedido de POST ao IFTTT. O envio de um pedido de GET não funcionará.

Depois, temos o bloco de tentativa/excepção.

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)

Se um botão for premido, o código executará a função relevante. Por exemplo, se se premir o botão de saltar, a função será executada skip().

A time.sleep(0.25) irá fazer uma pausa de 250ms na função. Sem isto, mesmo uma pequena prensa pode sobrecarregar e destruir o Pico W.

O excepto O bloco é opcional, mas fi-lo porque já tinha um applet de "erro" no IFTTT. Se seguiu o tutorial anterior, poderá tê-lo utilizado.

Basicamente, envia a mensagem de erro, epara IFTTT, para que receba a mensagem de erro como uma notificação de aplicação telefónica.

Porque é que não está a funcionar?

Usar o IFTTT como meio para controlar o seu Spotify é fácil, mas vem com alguns inconvenientes.

Deve iniciar a música da forma regular primeiro

Se tentou carregar no botão play no seu Pico W e esperava que a música começasse a tocar... bem, nada acontece.

A solução é iniciar a música no seu computador ou telefone normalmente. Tem de ir à sua aplicação e carregar no play.

Penso que isto declara que dispositivo é o dispositivo activo. Depois de o ter feito, poderá utilizar o seu Pico W Spotify à distância.

Respostas lentas

Demora alguns segundos entre o premir de um botão e a resposta. Infelizmente, é assim que as coisas são.

Poderia pagar por uma actualização do IFTTT para obter velocidades de resposta mais rápidas. Pelo menos, é isso que prometem pelo seu dinheiro.

Existe uma forma directa de ligar Spotify?

Sim! Spotify tem um API ao qual se pode ligar.

Proporciona-lhe significativamente mais controlo. Pode adicionar um codificador rotativo para controlar o volume. Poderia adicionar um ecrã LCD para mostrar o que está a tocar. Veja a consola do Spotify aqui.

Incrível, mas também muito mais difícil de programar, especialmente num Pico W.

O IFTTT torna tudo mais fácil porque eles fazem todo o trabalho pesado. Se quiser ser o levantador pesado, verifique o fluxo de autenticação.

Código de Autorização Diagrama de fluxo por Spotify

Claro, somos entusiastas do Raspberry Pi. Alguém lá fora o fará. Deveria ser você? Ou eu? Comente abaixo.

Controle o seu Pico W sem fios com o PiCockpit!

Pode controlar e obter dados do seu Pico W sem fios, utilizando o PiCockpit.

PiCockpit permite-lhe obter valores, controlar e utilizar PWM através de uma GUI através da sua applet GPIO.

Também pode ver as estatísticas do seu Pico W através do applet PiStats.

Integrar o PiCockpit no seu Pico W é super fácil.

Siga este tutorial.

Escreva ainda menos código com o PiCockpit e o Pico W

PiCockpit facilita-lhe o controlo dos seus pinos GPIO sem ter de escrever qualquer código.

Se olhar para tutorial número 2, repare quanto código é necessário apenas para alternar um LED.

Com a nossa nova integração no Pico W, PiCockpit torna-o muito mais fácil, uma vez que não é necessário programar absolutamente nada. Nem sequer a configuração WiFi - isso é feito com o nosso assistente de configuração.

10. Controlo LED simples com PiCockpit e Pico W

Se tiver o seu LED configurado exactamente como eu o fiz no tutorial nº 2, então tudo o que lhe resta é configurá-lo no PiCockpit.

Se estiver a codificá-lo, irá declarar qual o pino do seu LED que está a usar led = machine.Pin(2, machine.Pin.OUT)

No PiCockpit, irá para a sua applet GPIO, e o pergaminho para "Saída GPIO (On/Off)".

Escolha BCM02 no menu suspenso porque o seu LED está no GPIO 2.

Em seguida, na coluna "Controlo", alternar o interruptor para ligar o LED.

Pode também utilizar facilmente a secção de Software PWM abaixo para controlar o brilho do seu LED.

Note que terá de remover a configuração anterior porque não pode ter duas saídas na mesma GPIO.

Ao alternar o selector "Control", notará o brilho da mudança do LED.

picockpit gpio pwm controlo remoto

11. Pico W, ventilador 5V e um transistor, controlado por PiCockpit

Vamos tentar algo um pouco mais abrangente, mas usando o mesmo alternador de saída GPIO.

Para ilustrar alguns casos de utilização no mundo real, vou alimentar um ventilador de 5V usando o PiCockpit.

Este é um ventilador de 5V de baixa potência retirado do meu Raspberry Pi 4, por isso está bem dentro das capacidades de saída do Raspberry Pi Pico W.

Dito isto, por ser um ventilador de 5V, não posso usar um pino GPIO. Em componentes menos potentes, como um LED, pode-se fazer com que a GPIO faça o duplo dever de fornecer energia ao componente e ser o "interruptor" que o liga e desliga.

Mas o ventilador de 5V exigiria uma tensão demasiado alta. Portanto, a próxima melhor maneira é colocar um transístor no meio.

Isto permite-me fornecer 5V ao ventilador, garantindo ao mesmo tempo que o posso ligar e desligar.

Mais uma vez, por causa do PiCockpit, fiz uma programação zero. Só fiz o hardware, que está ligado da seguinte forma:

O ventilador é um ventilador de 5V/0.12A, ligado a 5V na extremidade positiva (fio vermelho), e o fio negativo vai para a perna emissora do transístor.

O transistor é um transistor PN2222 (NPN), o que significa que se liga quando recebe um sinal elevado.

Da esquerda para a direita, com a parte semi-circulada virada para longe de si, as pernas são o Emissor, Base e Colector.

A perna Base é ligada a uma resistência de 1K, depois ligada à GPIO 15.

A perna do Colector está ligada à terra.

Configuração do PiCockpit para trabalhar com transístor

Mais uma vez, super fácil.

Ir para o menu dropdown na secção Saída GPIO e adicionar BCM15.

Uma vez dentro, pode clicar na seta para baixo e mudar os Nomes de Estado para "ventilador desligado" e "ventilador ligado".

Alterne o interruptor de controlo e deverá ver o ventilador a ligar-se.

Também pode usar o PiStats para ver a queda de temperaturas no seu tabuleiro.

Exibir fotossistor usando MQTT e Node-RED com Pico W.

O principal objectivo deste tutorial é a introdução do MQTT.

Nos tutoriais anteriores, mostrei-te como podes usar o teu Pico W para entregar dados, mas e se quiseres um repositório central de dados na nuvem?

O HiveMQ Cloud é um serviço gratuito que podemos utilizar para atingir este objectivo. Utilizando os computadores de outra pessoa, podemos também aliviar a carga no Pico W.

Para além disso, o MQTT tem grandes vantagens em comparação com os métodos anteriores utilizados. Para um, é muito mais eficiente no envio de pequenos dados. Os cabeçalhos do protocolo MQTT são de 2 bytes de tamanho. O HTTP é cerca de 4000 vezes maior.

Reduzir a carga de processamento local e a carga de rede significa uma maior duração da bateria para o seu Pico W, que é perfeito para projectos alimentados por bateria ou por energia solar.

Ligação fotorresistente com o Pico W

Um fotossistor (fotocélula) é super fácil de ligar.

Colocar o fotossistor através da sarjeta central da tábua de pão.

Em seguida, ligar o pino 3V3 a um dos lados do fotossistor.

Vai querer ligar um pino ADC ao outro lado do fotossistor, por isso ligue o GPIO 26.

Finalmente, ligar uma resistência de 10K ohm do solo à fotocélula.

Nuvem HiveMQ e codificação do Pico W

Em primeiro lugar, inscreva-se aqui no HiveMQ Cloud.

Percorrer a configuração e criar um agrupamento. Pedir-lhe-á para escolher AWS ou Azure. Para os nossos propósitos, não há diferença.

Depois, clicar em "Manage Cluster".

Menu principal do Cluster. Tomar nota dos dois rectângulos laranja.

Tome nota do seu URL do Cluster, e clique em Gestão de Acesso para criar um novo utilizador. Percorra os passos e crie um novo utilizador.

Com estes detalhes, pode agora programar o seu Pico W para enviar dados para lá.

Codificação do Pico W para receber dados de fotocélulas e MQTTCliente

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)

Primeiro, vamos pôr as nossas importações em ordem.

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

O wifi A importação provém dos tutoriais anteriores.

Irá precisar da biblioteca umqtt.simple, que pode ser descarregado aqui.

Uma vez descarregado, pode carregá-lo para o seu quadro (guia aqui).

Deverá ter estes ficheiros no seu Pico W.

Em seguida, criar uma função para obter uma leitura do fotossistor:

photoresistor = ADC(Pin(26))

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

Isto devolve um valor até 65535. Quanto mais brilhante for, mais alto é o valor.

Ligação ao HiveMQ

Para se ligar ao HiveMQ, terá de enviar alguns parâmetros para a classe de clientes do MQTTC.

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

Substitua [o seu nome de anfitrião] pelo endereço encontrado no seu tablier. Terá de fazer isto duas vezes, uma vez por server e outro para server_hostname. Substitua também [seu_id_cliente] por um nome para o seu dispositivo, tal como "seu_picow".

Depois, substitua [your-user] e [your-pw] com o utilizador que criou na página Gestão de Acesso (imagem de ecrã da página Gestão de Acesso abaixo).

Para referência, esta função envia dados para o HiveMQ:

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

Chamemos-lhe no nosso while laço:

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

    print(brightness)

    publish('picow/brightness', brightness)

    time.sleep(0.1)

Ao publicar, deve enviar cordas, e é por isso brightness = str(readLight()) está lá.

Se enviar inteiros ou bóias flutuantes, o programa morrerá.

Na função de publicação, dê um nome ao seu tópico. Digamos, picow/brightnesse depois acrescente o valor que pretende enviar. Neste caso, pretendemos enviar a leitura de luz de stringified light, brightness.

Deverá poder ver os dados a serem publicados quando iniciar sessão no separador Web Client.

O cliente web do HiveMQ, à esquerda, mostra-lhe os dados que foram publicados.

Node-RED

Estes são apenas números em linha que podem parecer algaraviados. E se quisesse aceder aos dados no HiveMQ Cloud e apresentá-los graficamente?

Em vez de enrolar o seu próprio, poderia simplesmente usar o Node-RED.

O Node-RED facilita-lhe realmente a recolha de dados do HiveMQ e depois a sua apresentação utilizando representações gráficas.

Vamos fazer um medidor usando Node-RED.

Para começar, terá de ter nodejs. Verifique a documentação do HiveMQ para ver qual é a versão recomendada.

Uma vez instalado o Nodo, terá de abrir um prompt de comando/Terminal e executar estes comandos (excluir o sudo se estiver no Windows):

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

Isto irá utilizar o gestor de pacotes de nós (npm) para instalar o Node-RED globalmente.

Em seguida, executar Node-RED digitando node-red para o Terminal/comando imediato.

Abra o seu navegador e dirija-se a http://127.0.0.1:1880 ou qualquer endereço que esteja listado no seu Terminal.

Vamos construir o fluxo. Arrastar um "mqtt in" para a tela. Pode encontrá-lo sob o separador "rede" na barra lateral esquerda.

Vamos precisar de configurar o separador, por isso clique duas vezes no rectângulo e faça o seguinte:

No campo "tópico", certifique-se de acrescentar picow/brightnessuma vez que foi isso que publicou a partir do Pico W.

Em "servidor", adicione um novo clicando no ícone do lápis e será levado para o menu seguinte.

Introduzir um novo endereço de servidor e mudar o porto para 8883. Assinalar "Use TLS" mas não se preocupe em adicionar novo tls-config.

Depois, vá para o separador de segurança e acrescente as suas credenciais de login.

Todos estes detalhes podem ser encontrados no seu código quando inicializa o MQTTClient.

Acrescentar uma bitola

Para adicionar uma bitola, deve ter o painel de instrumentos vermelho-avermelhado.

Na barra lateral esquerda, se não os vir:

Depois ir para o menu (botão superior direito) -> Manage Palette. Em seguida, ir para o separador Instalar e procurar por painel vermelho-aceno. Clique em "Instalar".

Arrastar e largar um "calibre" à direita do mqtt em rectângulo, e conectá-los arrastando uma linha de mqtt em para a bitola.

Duplo clique no rectângulo do calibre e mudar a etiqueta para "brilho" e o "alcance" máximo para 65535.

Óptimo. Agora vamos carregar em "Deploy".

Se as suas definições estiverem correctas, verá um círculo verde e "ligado" sob o rectângulo. Caso contrário, o seu terminal dar-lhe-á mais pormenores sobre a razão pela qual existe um erro.

Com o seu Pico W a entregar dados ao HiveMQ Cloud, é agora altura de verificar o painel de instrumentos. Visite http://127.0.0.1:1880/ui e deverá ver a bitola ser actualizada frequentemente.


As vossas sugestões são bem-vindas.

Deixe um comentário na caixa de comentários abaixo!

6 comentários

  1. Quang em Janeiro 10, 2023 às 2:21 pm

    Olá,
    Obrigado por partilhar connosco os seus conhecimentos.
    Poderia aconselhar se os exercícios WiFi são apenas para trabalho em rede? Não consegui aceder ao Pico W se estiver numa rede WiFi diferente. Em caso afirmativo, tem alguns exemplos de acesso fora da rede?
    Obrigado.

    • raspi berry em Fevereiro 4, 2023 às 11:52 am

      Sim, devido à natureza das redes, routers e firewalls, estes exercícios funcionam apenas dentro da mesma rede WiFi.
      O próprio PiCockpit é uma solução que abrange redes - pode aceder ao seu Pico W a partir de qualquer lugar na Internet.
      Estamos a trabalhar para trazer mais características para a plataforma.

      Se quiser recriar algo do género, precisaria de ter algum tipo de solução de túnel para a sua rede, ou um servidor de retransmissão, ou algo do género.
      Oferecemos serviços de consultoria se quiser aprofundar este tópico.

  2. Peter Mayr em Março 29, 2023 às 10:44 am

    Obrigado por este grande tutorial.
    Infelizmente, não funciona.
    Estou preso no final da parte "1. servir uma página web que diz "Olá Mundo" no Pico".

    Os meus navegadores Firefox e Chrome apenas me dizem "Ligação de erro interrompida" .
    Em Thonny vejo

    Ligado
    ip = 192.168.188.198
    Ouvir em ('0.0.0.0', 80)
    Cliente ligado a partir de ('192.168.188.100', 54025)
    Ligação fechada

    A ligação fechada vem um par de vezes.
    O que posso modificar para que o meu Pico W funcione?
    Obrigado antecipadamente pela sua ajuda.
    Cumprimentos ao Pete

  3. mokcp em Maio 3, 2023 às 10:58 am

    Quando executo o main.py, surge uma mensagem de erro, como posso resolvê-la?

    Ficheiro "", linha 1, em
    ImportError: nenhum módulo com o nome 'wifi'

    Desde já, obrigado.

    • PiCaptain em Maio 10, 2023 às 12:31 pm

      Tens de criar e adicionar o wifi.py - que é mostrado um pouco mais acima na página. Sem o wifi.py, o código não funcionará.

  4. màn hình led em Agosto 26, 2023 às 2:18 pm

    O "Raspberry Pi Pico W beginners' components tutorial" é um guia fantástico para quem é novo na plataforma Raspberry Pi Pico W. O tutorial está bem estruturado e é fácil de seguir, o que o torna ideal para principiantes. Abrange os componentes essenciais e fornece instruções claras, o que o torna um ótimo ponto de partida para quem quer explorar esta tecnologia. A inclusão de explicações detalhadas e imagens melhora a experiência de aprendizagem, garantindo que os leitores possam compreender rapidamente os conceitos. No geral, este tutorial é um recurso valioso para quem quer começar a usar o Raspberry Pi Pico W e seus componentes.

Deixe um comentário