Allt om Bluetooth på Raspberry Pi Pico W

PiCockpit Pico W Bluetooth Titelbild

Raspberry Pi Foundation tillkännagav nyligen Bluetooth-stöd med lanseringen av C/C++ SDK version 1.5.1 med en ny utgåva av C/C++ SDK och av Micropython på Pico W.

Och gissa vad! Om du har en Pico W behöver du inte köpa en ny.

Och om du ännu inte har en Pico W kan du köpa en här.

Vi har redan en artikel som behandlar allt du behöver veta om Pico W. Om du är nybörjare med Pico W kan du dessutom kolla in den här artikeln.

Men här går vi igenom allt du behöver veta om Bluetooth på Raspberry Pi Pico W.

Pico W Bakgrund

Låt oss först gå igenom några av specifikationerna för Pico W.

Pico W har trådlösa funktioner tack vare det trådlösa chipet CYW43439.

Kärnan i varje Pico W är RP2040, som är Raspberry Pis första kiselchip.

Infineon CYW43439 har stöd för IEEE 802.11 b/g/n WLAN (Wi-Fi) och Bluetooth 5.2. Vid lanseringen var det endast Wi-Fi som stöddes av den fasta programvaran och programvaran.

CYW43439 har stöd för BLE och en enda antenn som delas mellan Wi-Fi och Bluetooth.

Raspberry Pi och Pico W-antenner

Om du tittar närmare på Pico W ser du den triangelformade PCB-antennen som liknar Raspberry Pi 4. Raspberry Pi använder en inbyggd antenn med licens från ABRACON.

Det betyder att det inte behövs någon extra antenn. Det trådlösa gränssnittet är anslutet via SPI till RP2040.

The officiellt datablad föreslår också att du för bästa trådlösa prestanda inte bör placera någon metall under eller nära antennen. Om du däremot lägger jordad metall på antennens sidor kan du förbättra antennens bandbredd.

Den inbyggda lysdioden styrs via WL_GPIO0-pinnen på Infineon 43439-chipet. På Pico var lysdioden ansluten till GPIO Pin 25.

Dessutom flyttades SWD-debugstiften till mitten av kretskortet för att skapa utrymme för PCB-antennen. Du hittar dem mellan RP2040 och CYW43439 och ordningen från vänster till höger är fortfarande SWCLK, GND, SWDIO.

Med Pico W kan du programmera i C/C++ och MicroPython.

Klassisk Bluetooth & BLE

Pico W fungerar med både Bluetooth Classic och Bluetooth Low Energy. Bluetooth Classic och Bluetooth Low Energy (BLE) är två olika sätt för enheter att kommunicera inom Bluetooth-specifikationen.

Bluetooth Classic, även känt som Bluetooth Basic Rate/Enhanced Data Rate (BR/EDR), är den ursprungliga versionen av Bluetooth. Den är utformad för höghastighetsdataöverföring, ljudstreaming och enhetsparning. Bluetooth Classic används ofta för applikationer som trådlösa ljudhögtalare, tangentbord, möss och filöverföring mellan enheter.

Bluetooth Low Energy (BLE), även känt som Bluetooth Smart, är en strömsnål variant av Bluetooth. BLE introducerades som en del av Bluetooth 4.0-specifikationen och är optimerad för strömsnåla enheter som kräver lång batteritid, t.ex. fitness trackers, smartwatches, hemautomatiseringsenheter och trådlösa sensorer.

Pico W kan fungera både som en central enhet och som en perifer enhet.

Komma igång med Bluetooth på Pico W

Låt oss börja med ett snabbt projekt för att säkerställa att Bluetooth fungerar som det ska.

Vi kör ett klassiskt program för att få den inbyggda lysdioden på Pico W att tändas, men med Bluetooth.

För detta behöver du en Pico W, en mikro-USB-kabel och ett breadboard.

Pico W

STEG ETT

Det första du behöver är att ladda ner Thonny IDE, om du inte redan har det.

Thonny är ett superenkelt sätt att programmera MicroPython på Pico W.

Du behöver också ladda ner denna UF2-filsom har stöd för både Wi-Fi och BLE. När du har laddat ner den håller du ned BOOTSEL-knappen på Pico W och ansluter den till datorn via USB. Släpp BOOTSEL-knappen efter ca 3 sekunder.

En fjärrenhet med namnet "RPI-RP2" visas. Flytta UF2-filen till denna enhet.

Då försvinner drivningen.

STEG TVÅ

Du kan nu koppla bort och återansluta din Pico W (håll inte ned BOOTSEL-knappen den här gången).

Öppna upp Thonny.

Bild av Pico W Bluetooth för Thonny IDE
Ändra tema och typsnitt för att spara dina ögon!

När du har öppnat Thonny går du till Tools > Options > Interpreter och ser till att tolken är inställd på Micropython och att porten är din Pico W. Här är ett exempel:

Din Pico W kan visas under ett annat namn.

När du har gjort det klickar du på OK och är klar att köra.

Kopiera nu följande kod och klistra in den i avsnittet :

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

Spara den filen på Raspberry Pi Pico W som "ble_advertising.py". Denna fil är avsedd att göra det möjligt för Pico W att läsa och läsas av andra enheter.

Öppna sedan en ny fil i Thonny och klistra in följande kod i den:

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

Precis som tidigare sparar du nu filen på Pico W och den här gången kan du kalla den "led_peripheral.py". Medan reklamfilen gör det möjligt för Pico W att kommunicera med andra enheter, gör periferifilen det möjligt för den att funktion som en kringutrustning. I det här fallet är funktionen att tända lysdioden.

Klicka nu på "Kör aktuellt skript" i Thonnys verktygsfält.

Bild av Pico W Bluetooth för Thonny IDE

Som du kan se på bilden kommer konsolen att visa "Starta reklam". Nu kan du ansluta till en Bluetooth-enhet, t.ex. din telefon. Hitta och para ihop med "mpy-uart".

Bild av Bluetooth-anslutningarna på en Android-telefon

När du har parat ihop de två kommer Pico W:s LED att tändas och Thonny-konsolen kommer att börja räkna hur länge de två har räknats:

Bild av Pico W Bluetooth för Thonny IDE

Nu kan vi gratulera! Du har nu bekräftat att Bluetooth-funktionen i din Pico W fungerar och du kan nu börja fokusera på ditt nästa projekt!

Pico W Bluetooth-projekt

När du påbörjar ditt nästa Pico W-projekt kan du titta på några av de projekt som andra har gjort. Eftersom Pico W precis fått officiellt Bluetooth-stöd har nya projekt bara börjat dyka upp.

Här är en (växande) lista över några av de projekt som har dykt upp hittills:

  1. Pico W Bluetooth Fjärrkontroll
  2. Pico W Bluetooth Robot
  3. Pico W Bluetooth Mus
  4. Pico W Bluetooth Ljus
  5. Pico W USB till Bluetooth Ljudadapter
  6. Pico W Bluetooth PicoDRO (digital avläsning)

VANLIGA FRÅGOR

Kan jag använda Bluetooth Classic med Pico W?

Absolut, Pico W stöder Bluetooth Classic och BLE!

Kan jag ansluta flera enheter till Pico W samtidigt?

Ja, Pico W kan fungera som en central enhet och ansluta till flera Bluetooth-kringutrustningar samtidigt. Du kan också använda Bluetooth Classic och BLE samtidigt. På så sätt kan du skapa ultrakomplexa system där Pico W kommunicerar med ett antal sensorer eller styr flera enheter samtidigt.

Vad är Bluetooth-räckvidden för Pico W?

Normalt upp till 30 meter (98 fot) i öppna utrymmen. Räckvidden kan dock variera beroende på miljöfaktorer som hinder, störningar och signalstyrka.

Kan jag använda Pico W som en Bluetooth-periferienhet?

Pico W kan fungera som en central eller en perifer enhet. Det innebär att andra centrala Bluetooth-enheter (t.ex. smartphones, surfplattor eller datorer) kan anslutas till den. Allt detta fungerar utmärkt med PiCockpit, förresten!

Hur programmerar jag Bluetooth-funktionen på Pico W?

Du kan programmera Bluetooth-funktionalitet på Pico W med Raspberry Pi Pico SDK version 1.5.1. SDK innehåller bibliotek och exempel som är särskilt avsedda för Bluetooth-utveckling. Det gör att du kan implementera Bluetooth-tjänster, egenskaper och hantera kommunikationsprotokoll.

Vilka är strömkraven för Bluetooth på Pico W?

Bluetooth är utformat för att vara strömsnålt. Pico W förbrukar därför minimalt med ström under inaktiva perioder och du kan optimera din kod ytterligare genom att använda tekniker som vilolägen och lågenergitillstånd. De specifika strömkraven beror naturligtvis på applikationen och användningsscenariot.

11 Kommentarer

  1. Marcos Gutierrez den augusti 4, 2023 kl 1:13 f m

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

  2. Electronikmx den augusti 17, 2023 kl 12:16 f m

    Efter några sekunder indikerar apparaten ett fel och avaktiveras när du försöker vinkla den

    • Adam den augusti 17, 2023 kl 6:51 f m

      ¿En qué momento?

      • Electronikmx den augusti 17, 2023 kl 4:19 e m

        Como comentaba, al momento de darle en el móvil a "vincular" en solicitud de enlace por medio de bluetooth observo que sí, RPI pico W envía una serie de números propios del programa en la tarjeta "TX 1_, TX 2_ ..." , sin embargo después de varios segundos el celular o tablet (lo intenté con 3 dispositivos) me indica que hubo un error al intentar vincular y se desconecta el bluetooth del móvil aparece el mensaje "Disconected 64", y bajo esa línea nuevamente aparece "Starting advertising" y tengo que darle en conectar de nuevo.

        • Javier den oktober 5, 2023 kl 11:08 e m

          Me pasa lo mismo

  3. Alex den oktober 2, 2023 kl 8:00 f m

    Kan du ha en wifi-anslutning öppen samtidigt som du har en Bluetooth-anslutning på pi pico W? Om inte, kan du växla mellan dem i realtid?

  4. Javier den oktober 5, 2023 kl 11:10 e m

    Me pasa lo mismo.... ya lo intenté de varios dispositivos y aplicaciones. No funcionó.

  5. Peter den november 12, 2023 kl 11:33 f m

    Hur ställer man in kitronik mini Pico-styrenheten för att koppla ihop den med och styra kitronik Pico-robotkortet?

  6. Brian den november 27, 2023 kl 12:27 f m

    Hej. Jag följde dina instruktioner men kan inte hitta mpy-uart på min iPhone under Bluetooth.

    Jag har en Pico W ansluten via USB till min dator.
    Jag flashade din UF2
    Jag kopierade din kod och sparade filerna enligt namnet på pico W via Thonny
    Jag kör Thonny och i det nedre högra hörnet finns fabriksnamnet MicroPython (Raspberry Pi Pico) {punkt. som om det finns en svävande punkt} Board CDC @ COM3
    Jag körde led_peripheral.py
    Shell utgångar "Starta reklam"
    Kan inte se det på iPhone

    Några tankar?

    Tack för att du bidrar till saken.

    • Anant den mars 19, 2024 kl 2:31 e m

      Hej, jag står inför samma problem här. Kunde du räkna ut det här?

  7. Paul B. den februari 22, 2024 kl 3:04 e m

    I stället för en BT-länk med en telefon har jag en Arduino GPS-modul som sänder sina koordinater via Bluetooth. Finns det något sätt att para ihop med och läsa av den signalen med en Pico W?

Lämna en kommentar