Все о Bluetooth на Raspberry Pi Pico W

Изображение заголовка PiCockpit Pico W Bluetooth

Фонд Raspberry Pi недавно объявил о том, что Поддержка Bluetooth с выходом C/C++ SDK версии 1.5.1 с новым выпуском C/C++ SDK и Micropython на Pico W.

И знаете что! Если у вас есть Pico W, вам не нужно покупать новый.

А если у вас еще нет Pico W, то вы можете приобрести его здесь.

У нас уже есть статья, посвященная Все, что нужно знать о Pico W. Кроме того, если вы начинаете работать с Pico W, вы можете ознакомьтесь с этой статьей.

Но здесь мы расскажем обо всем, что вам нужно знать о Bluetooth на Raspberry Pi Pico W.

Pico W Background

Сначала рассмотрим некоторые технические характеристики Pico W.

Pico W обладает беспроводными возможностями благодаря микросхеме беспроводной связи CYW43439.

Сердцем каждого Pico W является RP2040, который представляет собой первый кремниевый чип Raspberry Pi.

Infineon CYW43439 поддерживает беспроводные локальные сети IEEE 802.11 b/g/n (Wi-Fi) и Bluetooth 5.2. На момент запуска в прошивке и программном обеспечении поддерживался только Wi-Fi.

CYW43439 поддерживает BLE и одну антенну, разделяемую между Wi-Fi и Bluetooth.

Антенны для Raspberry Pi и Pico W

Если вы внимательно посмотрите на Pico W, вы заметите антенну на печатной плате в форме треугольника, похожую на антенну Raspberry Pi 4. В Raspberry Pi используется встроенная антенна, лицензированная компанией ABRACON.

Это означает, что дополнительная антенна не требуется. Беспроводной интерфейс подключается через SPI к RP2040.

Сайт официальный технический паспорт также рекомендует для обеспечения наилучшей работы беспроводной сети не размещать под антенной или в непосредственной близости от нее никаких металлических предметов. Однако добавление заземленного металла по бокам антенны может улучшить ее пропускную способность.

Управление встроенным светодиодом осуществляется через вывод WL_GPIO0 микросхемы Infineon 43439. На Pico светодиод был подключен к выводу 25 GPIO.

Кроме того, отладочные контакты SWD были перемещены к центру платы, чтобы освободить место для антенны печатной платы. Вы можете найти их между RP2040 и CYW43439, и порядок слева направо по-прежнему SWCLK, GND, SWDIO.

С помощью Pico W можно программировать на языках C/C++ и MicroPython.

Bluetooth Classic & BLE

Pico W работает как с Bluetooth Classic, так и с Bluetooth Low Energy. Bluetooth Classic и Bluetooth Low Energy (BLE) - это два различных способа взаимодействия устройств в рамках спецификации Bluetooth.

Bluetooth Classic, также известный как Bluetooth Basic Rate/Enhanced Data Rate (BR/EDR), является первоначальной версией Bluetooth. Она была разработана для высокоскоростной передачи данных, потокового аудио и сопряжения устройств. Bluetooth Classic обычно используется в таких приложениях, как беспроводные аудиоколонки, клавиатуры, мыши, а также для передачи файлов между устройствами.

Bluetooth Low Energy (BLE), также известный как Bluetooth Smart, представляет собой энергоэффективный вариант Bluetooth. BLE был представлен как часть спецификации Bluetooth 4.0 и оптимизирован для устройств с низким энергопотреблением, требующих длительного времени автономной работы, таких как фитнес-трекеры, смарт-часы, устройства домашней автоматизации и беспроводные датчики.

Pico W может работать как в качестве центрального, так и периферийного устройства.

Начало работы с Bluetooth на Pico W

Давайте начнем с небольшого проекта, чтобы убедиться, что Bluetooth работает правильно.

Запустим классическую программу для включения бортового светодиода на Pico W, но с использованием Bluetooth.

Для этого вам понадобится Pico W, кабель micro-USB и макетная плата.

Пико В

ШАГ ПЕРВЫЙ

Прежде всего, необходимо загрузить Идентификация Тонниесли у вас его еще нет.

Thonny - это очень простой способ программирования на MicroPython для Pico W.

Вам также необходимо загрузить данный файл UF2в котором есть поддержка Wi-Fi и BLE. После загрузки удерживайте кнопку BOOTSEL на Pico W и подключите его к компьютеру через USB-порт. Отпустите кнопку BOOTSEL примерно через 3 секунды.

Появится удаленный диск с именем "RPI-RP2". Переместите файл UF2 на этот диск.

После этого диск исчезнет.

ШАГ ДВА

Теперь можно отключить и снова подключить Pico W (на этот раз не удерживайте кнопку BOOTSEL).

Откройте Тонни.

Изображение Pico W Bluetooth the Thonny IDE
Измените тему и шрифт, чтобы сохранить ваши глаза!

После того как вы открыли Thonny, перейдите в меню Tools > Options > Interpreter и убедитесь, что в качестве интерпретатора выбран Micropython, а в качестве порта - Pico W. Вот пример:

Ваш Pico W может отображаться под другим именем.

После этого нажмите кнопку OK, и все готово.

Теперь скопируйте следующий код и вставьте его в секцию :

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

Сохраните этот файл на Raspberry Pi Pico W под именем "ble_advertising.py". Этот файл предназначен для того, чтобы Pico W мог читать и быть прочитанным другими устройствами.

Далее откройте новый файл в Thonny и вставьте в него следующий код:

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

Теперь, как и раньше, сохраните файл на Pico W и на этот раз назовите его "led_peripheral.py". В то время как файл advertising позволяет Pico W взаимодействовать с другими устройствами, файл peripheral позволяет ему функция как периферийное устройство. В данном случае этой функцией будет включение светодиода.

Теперь нажмите кнопку "Run current script" на панели инструментов Thonny.

Изображение Pico W Bluetooth the Thonny IDE

Как видно на рисунке, консоль выдаст сообщение "Starting advertising". На этом этапе можно установить соединение с Bluetooth-устройством, например с телефоном. Найдите и установите сопряжение с устройством "mpy-uart".

Изображение Bluetooth-соединений на телефоне Android

После сопряжения светодиод Pico W загорится, а консоль Thonny начнет отсчет времени:

Изображение Pico W Bluetooth the Thonny IDE

Поздравляем! Теперь вы убедились, что Bluetooth в Pico W работает, и можете приступать к реализации следующего проекта!

Проекты Pico W Bluetooth

Приступая к реализации своего следующего проекта Pico W, вы можете обратиться к некоторым проектам, выполненным другими пользователями. Поскольку Pico W только что получил официальную поддержку Bluetooth, новые проекты только начинают появляться.

Ниже приведен (растущий) список некоторых из появившихся на данный момент проектов:

  1. Pico W Bluetooth Пульт дистанционного управления
  2. Pico W Bluetooth Робот
  3. Pico W Bluetooth Мышь
  4. Pico W Bluetooth Светильники
  5. Pico W USB - Bluetooth Аудиоадаптер
  6. Pico W Bluetooth PicoDRO (цифровое считывание)

ЧАСТО ЗАДАВАЕМЫЕ ВОПРОСЫ

Можно ли использовать Bluetooth Classic с Pico W?

Безусловно, Pico W поддерживает Bluetooth Classic и BLE!

Можно ли одновременно подключить к Pico W несколько устройств?

Да, Pico W может выступать в качестве центрального устройства и подключаться к нескольким периферийным устройствам Bluetooth одновременно. Кроме того, можно одновременно использовать Bluetooth Classic и BLE. Таким образом, можно создавать сверхсложные системы, в которых Pico W взаимодействует с множеством датчиков или управляет несколькими устройствами одновременно.

Какова дальность действия Bluetooth в Pico W?

Обычно до 30 м (98 футов) на открытом пространстве. Однако дальность действия может изменяться в зависимости от факторов окружающей среды, таких как препятствия, помехи и уровень сигнала.

Можно ли использовать Pico W в качестве периферийного устройства Bluetooth?

Pico W может функционировать как центральное или периферийное устройство. Таким образом, он позволяет подключать к себе другие центральные устройства Bluetooth (например, смартфоны, планшеты или компьютеры). Все это прекрасно сочетается с PiCockpit, кстати!

Как запрограммировать функцию Bluetooth на Pico W?

Для программирования функций Bluetooth на Pico W можно использовать Raspberry Pi Pico SDK версии 1.5.1. SDK содержит библиотеки и примеры, специально предназначенные для разработки Bluetooth. Он позволяет реализовать сервисы, характеристики и протоколы связи Bluetooth.

Каковы требования к питанию Bluetooth в Pico W?

Bluetooth разработан с учетом требований энергоэффективности. Поэтому в периоды простоя Pico W потребляет минимальное количество энергии, и вы можете дополнительно оптимизировать свой код, используя такие приемы, как спящий режим и состояние низкого энергопотребления. Конкретные требования к энергопотреблению, разумеется, зависят от приложения и сценария использования.

11 комментариев

  1. Marcos Gutierrez Август 4, 2023 в 1:13 дп

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

  2. Electronikmx Август 17, 2023 в 12:16 дп

    Спустя несколько секунд устройство выдаст ошибку и отключится при попытке закрепить его

    • Adam Август 17, 2023 в 6:51 дп

      В какой момент?

      • Electronikmx Август 17, 2023 в 4:19 пп

        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.

  3. Alex Октябрь 2, 2023 в 8:00 дп

    Можно ли на pi pico W одновременно иметь открытое соединение wifi и соединение bluetooth? Если нет, то можно ли переключаться между ними в реальном времени?

  4. Javier Октябрь 5, 2023 в 11:10 пп

    Я сделал то же самое, что и другие пользователи и приложения. No funcionó.

  5. Peter Ноябрь 12, 2023 в 11:33 дп

    Как настроить контроллер kitronik mini Pico для сопряжения с роботизированной платой kitronik Pico и управления ею?

  6. Brian Ноябрь 27, 2023 в 12:27 дп

    Здравствуйте. Я следовал вашим инструкциям, но не могу найти mpy-uart на iPhone в разделе Bluetooth.

    У меня есть Pico W, подключенный через USB к компьютеру.
    Я прошил ваш UF2
    Я скопировал ваш код и сохранил названные файлы на pico W через Thonny
    Я запускаю Thonny, и в правом нижнем углу находится фабрика с именем MicroPython (Raspberry Pi Pico) {точка. как будто парящая точка} Board CDC @ COM3
    Я запускаю файл led_peripheral.py
    Оболочка выдает сообщение "Запуск рекламы"
    Не видно на iPhone

    Есть какие-нибудь мысли?

    Спасибо, что внесли свой вклад в это дело.

    • Anant Март 19, 2024 в 2:31 пп

      Привет, столкнулся с той же проблемой. Удалось ли вам разобраться с этим?

  7. Paul B. Февраль 22, 2024 в 3:04 пп

    Вместо BT-связи с телефоном у меня есть GPS-модуль Arduino, который передает свои координаты по Bluetooth, есть ли способ сопряжения и считывания этого сигнала с помощью Pico W?

Комментировать