Tutto sul Bluetooth del Raspberry Pi Pico W

PiCockpit Pico W Bluetooth Titolo immagine

La Fondazione Raspberry Pi ha recentemente annunciato Supporto Bluetooth con il rilascio dell'SDK C/C++ versione 1.5.1 con una nuova versione dell'SDK C/C++ e di Micropython sul Pico W.

E indovinate un po'! Se avete una Pico W, non è necessario acquistarne una nuova.

E se non si possiede ancora una Pico W, è possibile acquistarla qui.

Abbiamo già un articolo che tratta di tutto quello che c'è da sapere sul Pico W. Inoltre, se si è alle prime armi con la Pico W, è possibile Guarda questo articolo.

Ma in questa sede, ci occupiamo di tutto quello che c'è da sapere su Bluetooth sul Raspberry Pi Pico W.

Sfondo Pico W

Vediamo prima di tutto le specifiche del Pico W.

Il Pico W dispone di funzionalità wireless grazie al chip wireless CYW43439.

Il cuore di ogni Pico W è l'RP2040, il primo chip di silicio di Raspberry Pi.

L'Infineon CYW43439 supporta la WLAN (Wi-Fi) IEEE 802.11 b/g/n e il Bluetooth 5.2. Al momento del lancio, solo il Wi-Fi era supportato dal firmware e dal software.

Il CYW43439 supporta BLE e una singola antenna condivisa tra Wi-Fi e Bluetooth.

Antenne Raspberry Pi e Pico W

Se si osserva da vicino il Pico W, si noterà l'antenna PCB a forma di triangolo, simile a quella del Raspberry Pi 4. Il Raspberry Pi utilizza un'antenna a bordo concessa in licenza da ABRACON.

Ciò significa che non è necessaria un'antenna aggiuntiva. L'interfaccia wireless è collegata via SPI all'RP2040.

Il scheda tecnica ufficiale suggerisce inoltre che, per ottenere le migliori prestazioni wireless, non si dovrebbe mettere alcun metallo sotto o vicino all'antenna. Tuttavia, l'aggiunta di metallo collegato a terra ai lati dell'antenna può migliorare la larghezza di banda dell'antenna.

Il LED a bordo è controllato tramite il pin WL_GPIO0 del chip Infineon 43439. Sul Pico, il LED è stato collegato al pin 25 del GPIO.

Inoltre, i pin di debug SWD sono stati spostati verso il centro della scheda, per creare spazio per l'antenna del PCB. Si trovano tra l'RP2040 e il CYW43439 e l'ordine da sinistra a destra è ancora SWCLK, GND, SWDIO.

Con Pico W è possibile programmare in C/C++ e MicroPython.

Bluetooth classico e BLE

Il Pico W funziona sia con Bluetooth Classic che con Bluetooth Low Energy. Bluetooth Classic e Bluetooth Low Energy (BLE) sono due modi diversi di comunicare tra dispositivi nell'ambito delle specifiche Bluetooth.

Bluetooth Classic, noto anche come Bluetooth Basic Rate/Enhanced Data Rate (BR/EDR), è la versione originale di Bluetooth. È stata progettata per la trasmissione di dati ad alta velocità, lo streaming audio e l'accoppiamento dei dispositivi. Il Bluetooth Classic è comunemente utilizzato per applicazioni quali altoparlanti audio wireless, tastiere, mouse e trasferimento di file tra dispositivi.

Il Bluetooth Low Energy (BLE), noto anche come Bluetooth Smart, è una variante a basso consumo del Bluetooth. Il BLE è stato introdotto come parte della specifica Bluetooth 4.0 ed è ottimizzato per dispositivi a basso consumo che richiedono una lunga durata della batteria, come fitness tracker, smartwatch, dispositivi di automazione domestica e sensori wireless.

Il Pico W può funzionare sia come dispositivo centrale che come periferica.

Come iniziare con il Bluetooth sul Pico W

Cominciamo con un rapido progetto per assicurarci che il Bluetooth funzioni correttamente.

Eseguiremo un programma classico per far accendere il LED a bordo del Pico W, ma con il Bluetooth.

A tale scopo sono necessari un Pico W, un cavo micro-USB e una breadboard.

Pico W

FASE UNO

La prima cosa di cui avrete bisogno è di scaricare Thonny IDEse non lo avete già.

Thonny è un modo semplicissimo per programmare MicroPython su Pico W.

È inoltre necessario scaricare questo file UF2che supporta sia il Wi-Fi che il BLE. Una volta scaricato, tenere premuto il pulsante BOOTSEL su Pico W e collegarlo al computer tramite USB. Lasciare il pulsante BOOTSEL dopo circa 3 secondi.

Verrà visualizzata un'unità remota denominata "RPI-RP2". Spostare il file UF2 in questa unità.

A questo punto l'unità scompare.

FASE DUE

A questo punto è possibile scollegare e ricollegare il Pico W (questa volta senza tenere premuto il pulsante BOOTSEL).

Aprire Thonny.

Immagine di Pico W Bluetooth l'IDE Thonny
Cambia il tema e il carattere per salvare i tuoi occhi!

Dopo aver aperto Thonny, andate su Strumenti > Opzioni > Interprete e assicuratevi che l'interprete sia impostato su Micropython e che la porta sia la vostra Pico W. Ecco un esempio:

Il vostro Pico W potrebbe apparire con un nome diverso.

Una volta fatto ciò, fare clic su OK e il gioco è fatto.

Ora, copiare il codice seguente e incollarlo nella sezione :

from micropython import const
import struct
import bluetooth

_ADV_TYPE_FLAGS = const(0x01)
_ADV_TYPE_NAME = const(0x09)
_ADV_TYPE_UUID16_COMPLETE = const(0x3)
_ADV_TYPE_UUID32_COMPLETE = const(0x5)
_ADV_TYPE_UUID128_COMPLETE = const(0x7)
_ADV_TYPE_UUID16_MORE = const(0x2)
_ADV_TYPE_UUID32_MORE = const(0x4)
_ADV_TYPE_UUID128_MORE = const(0x6)
_ADV_TYPE_APPEARANCE = const(0x19)

def advertising_payload(limited_disc=False, br_edr=False, name=None, services=None, appearance=0):
    payload = bytearray()

    def _append(adv_type, value):
        nonlocal payload
        payload += struct.pack("BB", len(value) + 1, adv_type) + value

    _append(
        _ADV_TYPE_FLAGS,
        struct.pack("B", (0x01 if limited_disc else 0x02) + (0x18 if br_edr else 0x04)),
    )

    if name:
        _append(_ADV_TYPE_NAME, name)

    if services:
        for uuid in services:
            b = bytes(uuid)
            if len(b) == 2:
                _append(_ADV_TYPE_UUID16_COMPLETE, b)
            elif len(b) == 4:
                _append(_ADV_TYPE_UUID32_COMPLETE, b)
            elif len(b) == 16:
                _append(_ADV_TYPE_UUID128_COMPLETE, b)

    if appearance:
        _append(_ADV_TYPE_APPEARANCE, struct.pack("<h", appearance))

    return payload


def decode_field(payload, adv_type):
    i = 0
    result = []
    while i + 1 < len(payload):
        if payload[i + 1] == adv_type:
            result.append(payload[i + 2 : i + payload[i] + 1])
        i += 1 + payload[i]
    return result


def decode_name(payload):
    n = decode_field(payload, _ADV_TYPE_NAME)
    return str(n[0], "utf-8") if n else ""


def decode_services(payload):
    services = []
    for u in decode_field(payload, _ADV_TYPE_UUID16_COMPLETE):
        services.append(bluetooth.UUID(struct.unpack("<h", u)[0]))
    for u in decode_field(payload, _ADV_TYPE_UUID32_COMPLETE):
        services.append(bluetooth.UUID(struct.unpack("<d", u)[0]))
    for u in decode_field(payload, _ADV_TYPE_UUID128_COMPLETE):
        services.append(bluetooth.UUID(u))
    return services


def demo():
    payload = advertising_payload(
        name="micropython",
        services=[bluetooth.UUID(0x181A), bluetooth.UUID("6E400001-B5A3-F393-E0A9-E50E24DCCA9E")],
    )
    print(payload)
    print(decode_name(payload))
    print(decode_services(payload))


if __name__ == "__main__":
    demo()

Salvare il file sul Raspberry Pi Pico W come "ble_advertising.py". Questo file è stato progettato per consentire al Pico W di leggere ed essere letto da altri dispositivi.

Quindi, aprire un nuovo file in Thonny e incollarvi il seguente codice:

# PiCockpit.com

import bluetooth
import random
import struct
import time
from machine import Pin
from ble_advertising import advertising_payload

from micropython import const

_IRQ_CENTRAL_CONNECT = const(1)
_IRQ_CENTRAL_DISCONNECT = const(2)
_IRQ_GATTS_WRITE = const(3)

_FLAG_READ = const(0x0002)
_FLAG_WRITE_NO_RESPONSE = const(0x0004)
_FLAG_WRITE = const(0x0008)
_FLAG_NOTIFY = const(0x0010)

_UART_UUID = bluetooth.UUID("6E400001-B5A3-F393-E0A9-E50E24DCCA9E")
_UART_TX = (
    bluetooth.UUID("6E400003-B5A3-F393-E0A9-E50E24DCCA9E"),
    _FLAG_READ | _FLAG_NOTIFY,
)
_UART_RX = (
    bluetooth.UUID("6E400002-B5A3-F393-E0A9-E50E24DCCA9E"),
    _FLAG_WRITE | _FLAG_WRITE_NO_RESPONSE,
)
_UART_SERVICE = (
    _UART_UUID,
    (_UART_TX, _UART_RX),
)


class BLESimplePeripheral:
    def __init__(self, ble, name="mpy-uart"):
        self._ble = ble
        self._ble.active(True)
        self._ble.irq(self._irq)
        ((self._handle_tx, self._handle_rx),) = self._ble.gatts_register_services((_UART_SERVICE,))
        self._connections = set()
        self._write_callback = None
        self._payload = advertising_payload(name=name, services=[_UART_UUID])
        self._advertise()

    def _irq(self, event, data):
        if event == _IRQ_CENTRAL_CONNECT:
            conn_handle, _, _ = data
            print("New connection", conn_handle)
            self._connections.add(conn_handle)
        elif event == _IRQ_CENTRAL_DISCONNECT:
            conn_handle, _, _ = data
            print("Disconnected", conn_handle)
            self._connections.remove(conn_handle)
            self._advertise()
        elif event == _IRQ_GATTS_WRITE:
            conn_handle, value_handle = data
            value = self._ble.gatts_read(value_handle)
            if value_handle == self._handle_rx and self._write_callback:
                self._write_callback(value)

    def send(self, data):
        for conn_handle in self._connections:
            self._ble.gatts_notify(conn_handle, self._handle_tx, data)

    def is_connected(self):
        return len(self._connections) > 0

    def _advertise(self, interval_us=500000):
        print("Starting advertising")
        self._ble.gap_advertise(interval_us, adv_data=self._payload)

    def on_write(self, callback):
        self._write_callback = callback


def demo():
    led_onboard = Pin("LED", Pin.OUT)
    ble = bluetooth.BLE()
    p = BLESimplePeripheral(ble)

    def on_rx(v):
        print("RX", v)

    p.on_write(on_rx)

    i = 0
    while True:
        if p.is_connected():
            led_onboard.on()
            for _ in range(3):
                data = str(i) + "_"
                print("TX", data)
                p.send(data)
                i += 1
        time.sleep_ms(100)


if __name__ == "__main__":
    demo()

Ora, come in precedenza, salvate il file sul Pico W e questa volta potete chiamarlo "led_peripheral.py". Mentre il file di pubblicità consente al Pico W di comunicare con altri dispositivi, il file di periferica gli consente di funzione come periferica. In questo caso, la funzione sarà l'accensione del LED.

Ora premete "Esegui lo script corrente" nella barra degli strumenti di Thonny.

Immagine di Pico W Bluetooth l'IDE Thonny

Come si può vedere nell'immagine, la console visualizza "Starting advertising". A questo punto, è possibile connettersi con un dispositivo Bluetooth come il telefono. Trovare e associare "mpy-uart".

Immagine delle connessioni Bluetooth su un telefono Android

Una volta accoppiati i due dispositivi, il LED del Pico W si accenderà e la console Thonny inizierà a contare la durata del conteggio:

Immagine di Pico W Bluetooth l'IDE Thonny

Congratulazioni! Ora avete la conferma che il Bluetooth della vostra Pico W funziona e potete iniziare a concentrarvi sul vostro prossimo progetto!

Progetti Bluetooth Pico W

Quando iniziate il vostro prossimo progetto Pico W, potete consultare alcuni dei progetti realizzati da altri. Da quando il Pico W ha ricevuto il supporto ufficiale per la tecnologia Bluetooth, sono appena nati nuovi progetti.

Ecco un elenco (in crescita) di alcuni dei progetti apparsi finora:

  1. Pico W Bluetooth Telecomando
  2. Pico W Bluetooth Robot
  3. Pico W Bluetooth Mouse
  4. Pico W Bluetooth Luci
  5. Pico W da USB a Bluetooth Adattatore audio
  6. Pico W Bluetooth PicoDRO (lettura digitale)

FAQ

È possibile utilizzare il Bluetooth Classic con il Pico W?

Assolutamente sì, il Pico W supporta Bluetooth Classic e BLE!

È possibile collegare contemporaneamente più dispositivi a Pico W?

Sì, il Pico W può fungere da dispositivo centrale e collegarsi a più periferiche Bluetooth contemporaneamente. È inoltre possibile utilizzare contemporaneamente Bluetooth Classic e BLE. È quindi possibile creare sistemi ultra complessi in cui il Pico W comunica con diversi sensori o controlla più dispositivi contemporaneamente.

Qual è la portata del Bluetooth del Pico W?

In genere fino a 30 metri (98 piedi) in spazi aperti. Tuttavia, la portata può variare a seconda di fattori ambientali quali ostacoli, interferenze e potenza del segnale.

È possibile utilizzare il Pico W come periferica Bluetooth?

Il Pico W può funzionare come dispositivo centrale o periferico. In questo modo permette ad altri dispositivi centrali Bluetooth (come smartphone, tablet o computer) di collegarsi ad esso. Tutto questo funziona perfettamente con PiCockpit, tra l'altro!

Come si programma la funzionalità Bluetooth sul Pico W?

È possibile programmare la funzionalità Bluetooth sul Pico W utilizzando la versione 1.5.1 dell'SDK di Raspberry Pi Pico. L'SDK fornisce librerie ed esempi specifici per lo sviluppo Bluetooth. Consente di implementare i servizi Bluetooth, le caratteristiche e di gestire i protocolli di comunicazione.

Quali sono i requisiti di alimentazione per il Bluetooth sul Pico W?

Il Bluetooth è progettato per essere efficiente dal punto di vista energetico. Il Pico W consuma quindi una quantità minima di energia durante i periodi di inattività ed è possibile ottimizzare ulteriormente il codice utilizzando tecniche come le modalità di sospensione e gli stati a basso consumo. I requisiti specifici di potenza dipendono ovviamente dall'applicazione e dallo scenario di utilizzo.

11 commenti

  1. Marcos Gutierrez in Agosto 4, 2023 il 1:13 am

    Hola puedo adaptar la pico w a scoppy osciloscopy.agrdeceria su respuesta y como lo haria

  2. Electronikmx in Agosto 17, 2023 il 12:16 am

    Dopo un paio di secondi il dispositivo indica un errore e si disconosce quando si vuole vincerlo.

    • Adam in Agosto 17, 2023 il 6:51 am

      In quale momento?

      • Electronikmx in Agosto 17, 2023 il 4:19 pm

        Come commentato, al momento di dare nel móvil un "vincular" en solicitud de enlace por medio de bluetooth observo che sì, RPI pico W invia una serie di números propios del programa en la tarjeta "TX 1_, TX 2_ ..." Tuttavia, dopo alcuni secondi, il cellulare o il tablet (l'ho fatto con 3 dispositivi) mi indicano che c'è stato un errore nel tentativo di collegarsi e se il bluetooth del dispositivo viene interrotto, appare il messaggio "Disconected 64", e sotto la linea appare di nuovo "Starting advertising" e devo collegarmi di nuovo.

        • Javier in Ottobre 5, 2023 il 11:08 pm

          Me pasa lo mismo

  3. Alex in Ottobre 2, 2023 il 8:00 am

    È possibile avere una connessione wifi aperta contemporaneamente a una connessione bluetooth su pi pico W? In caso contrario, è possibile passare da una all'altra in tempo reale?

  4. Javier in Ottobre 5, 2023 il 11:10 pm

    Mi è successo lo stesso.... già lo avevo inteso con diversi dispositivi e applicazioni. Non funziona.

  5. Peter in Novembre 12, 2023 il 11:33 am

    Come impostare il controller kitronik mini Pico per l'accoppiamento e il controllo della scheda robotica kitronik Pico?

  6. Brian in Novembre 27, 2023 il 12:27 am

    Salve, ho seguito le vostre istruzioni ma non riesco a trovare la mpy-uart sul mio iPhone alla voce Bluetooth.

    Ho un Pico W collegato via USB al mio computer.
    Ho flashato il tuo UF2
    Ho copiato il tuo codice e salvato i file con il nome sul pico W tramite Thonny
    Sto eseguendo Thonny e nell'angolo in basso a destra c'è la fabbrica denominata MicroPython (Raspberry Pi Pico) {dot. come se ci fosse un punto in bilico} Scheda CDC @ COM3
    Eseguo led_peripheral.py
    La shell visualizza "Avvio della pubblicità".
    Non riesco a vederlo sull'iPhone

    Qualche idea?

    Grazie per aver contribuito alla causa.

    • Anant in Marzo 19, 2024 il 2:31 pm

      Ciao, ho lo stesso problema. Sei riuscito a risolvere questo problema?

  7. Paul B. in Febbraio 22, 2024 il 3:04 pm

    Invece di collegarmi via BT con un telefono, ho un modulo GPS Arduino che trasmette le sue coordinate via Bluetooth; c'è un modo per accoppiare e leggere questo segnale con un Pico W?

Lascia un commento