ubluetooth — 低功耗蓝牙

该模块提供蓝牙控制器接口。 支持低功耗蓝牙(BLE)主控制, 外围设备控制,广播, 以及可见性, 并且一个设备可以同时进行多个 角色的操作。

该API用于匹配蓝牙低功耗(BLE)协议并提供用于高级抽象化(比如特定设备类型等)的模块。

注解

This module is still under development and its classes, functions, methods and constants are subject to change.

BLE 类

函数

class ubluetooth.BLE

返回单个BLE对象。

配置

BLE.active([active])

无线低功耗蓝牙(BLE)的状态(可选项), 返回当前状态。

在使用其他任何一个库之前必须开启无线低功耗蓝牙(BLE)。

BLE.config('param')
BLE.config(param=value, ...)

Get or set configuration values of the BLE interface. To get a value the parameter name should be quoted as a string, and just one parameter is queried at a time. To set values use the keyword syntax, and one ore more parameter can be set at a time.

通过*name*获取一个配置值. 现支持以下值:

  • 'mac': 返回该设备的MAC地址。 如果该设备的MAC地址被修改 (如PYBD) ,它将会返回一个值. 另外(如ESP32)当BLE接口被激活时,会生成一个随机的地址。

    Note: on some ports, accessing this value requires that the interface is active (so that the MAC address can be queried from the controller).

  • 'gap_name': Get/set the GAP device name used by service 0x1800, characteristic 0x2a00. This can be set at any time and changed multiple times.

  • 'rxbuf': Get/set the size in bytes of the internal buffer used to store incoming events. This buffer is global to the entire BLE driver and so handles incoming data for all events, including all characteristics. Increasing this allows better handling of bursty incoming data (for example scan results) and the ability for a central role to receive larger characteristic values.

事件处理

BLE.irq(handler)

注册一个BLE栈回调事件. *handler*需要两个对象, event (执行的函数)和``data`` (特定事件的一组值).

*trigger*(可选项)让你设置你的程序的目标事件。 默认设置为所有事件。

Note: the addr, adv_data, char_data, notify_data, and uuid entries in the tuples are references to data managed by the ubluetooth module (i.e. the same instance will be re-used across multiple calls to the event handler). If your program wants to use this data outside of the handler, then it must copy them first, e.g. by using bytes(addr) or bluetooth.UUID(uuid).

An event handler showing all possible events:

一个事件处理展示所有可能的事件:

def bt_irq(event, data):
    if event == _IRQ_CENTRAL_CONNECT:
        # 一个中央单元连接到这个外围设备
        conn_handle, addr_type, addr = data
    elif event == _IRQ_CENTRAL_DISCONNECT:
        # 一个中央单元与这个外围设备断开链接
        conn_handle, addr_type, addr = data
    elif event == _IRQ_GATTS_WRITE:
        # 中央单元已写入此特征或描述符
        conn_handle, attr_handle = data
    elif event == _IRQ_GATTS_READ_REQUEST:
        # 中央单元发布消息,这是一个硬中断请求
        # 返回None值以拒绝读取
        # 请注意:该事件不支持ESP32
        conn_handle, attr_handle = data
    elif event == _IRQ_SCAN_RESULT:
        # 单次扫描结果
        addr_type, addr, adv_type, rssi, adv_data = data
    elif event == _IRQ_SCAN_DONE:
        # 扫描过程完成或者被手动停止
        pass
    elif event == _IRQ_PERIPHERAL_CONNECT:
        # 一个成功的gap_connect()
        conn_handle, addr_type, addr = data
    elif event == _IRQ_PERIPHERAL_DISCONNECT:
        # 与已连接的外围设备断开
        conn_handle, addr_type, addr = data
    elif event == _IRQ_GATTC_SERVICE_RESULT:
        # 为gattc_discover_services()找到的每个服务调用
        conn_handle, start_handle, end_handle, uuid = data
    elif event == _IRQ_GATTC_SERVICE_DONE:
        # Called once service discovery is complete.
        # Note: Status will be zero on success, implementation-specific value otherwise.
        conn_handle, status = data
    elif event == _IRQ_GATTC_CHARACTERISTIC_RESULT:
        # 为gattc_discover_services()找到的每个特征调用
        conn_handle, def_handle, value_handle, properties, uuid = data
    elif event == _IRQ_GATTC_CHARACTERISTIC_DONE:
        # Called once service discovery is complete.
        # Note: Status will be zero on success, implementation-specific value otherwise.
        conn_handle, status = data
    elif event == _IRQ_GATTC_DESCRIPTOR_RESULT:
        # 为gattc_discover_descriptors()找到的每个描述符调用
        conn_handle, dsc_handle, uuid = data
    elif event == _IRQ_GATTC_DESCRIPTOR_DONE:
        # Called once service discovery is complete.
        # Note: Status will be zero on success, implementation-specific value otherwise.
        conn_handle, status = data
    elif event == _IRQ_GATTC_READ_RESULT:
        # 已完成的gattc_read()
        conn_handle, value_handle, char_data = data
    elif event == _IRQ_GATTC_READ_DONE:
        # A gattc_read() has completed.
        # Note: The value_handle will be zero on btstack (but present on NimBLE).
        # Note: Status will be zero on success, implementation-specific value otherwise.
        conn_handle, value_handle, status = data
    elif event == _IRQ_GATTC_WRITE_DONE:
        # A gattc_write() has completed.
        # Note: The value_handle will be zero on btstack (but present on NimBLE).
        # Note: Status will be zero on success, implementation-specific value otherwise.
        conn_handle, value_handle, status = data
    elif event == _IRQ_GATTC_NOTIFY:
        # 外部设备已发送通知请求
        conn_handle, value_handle, notify_data = data
    elif event == _IRQ_GATTC_INDICATE:
        # 外部设备已发送指示请求
        conn_handle, value_handle, notify_data = data
    elif event == _IRQ_GATTS_INDICATE_DONE:
        # A central has acknowledged the indication.
        # Note: Status will be zero on successful acknowledgment, implementation-specific value otherwise.
        conn_handle, value_handle, status = data

以下是事件码:

from micropython import const
_IRQ_CENTRAL_CONNECT = const(1)
_IRQ_CENTRAL_DISCONNECT = const(2)
_IRQ_GATTS_WRITE = const(3)
_IRQ_GATTS_READ_REQUEST = const(4)
_IRQ_SCAN_RESULT = const(5)
_IRQ_SCAN_DONE = const(6)
_IRQ_PERIPHERAL_CONNECT = const(7)
_IRQ_PERIPHERAL_DISCONNECT = const(8)
_IRQ_GATTC_SERVICE_RESULT = const(9)
_IRQ_GATTC_SERVICE_DONE = const(10)
_IRQ_GATTC_CHARACTERISTIC_RESULT = const(11)
_IRQ_GATTC_CHARACTERISTIC_DONE = const(12)
_IRQ_GATTC_DESCRIPTOR_RESULT = const(13)
_IRQ_GATTC_DESCRIPTOR_DONE = const(14)
_IRQ_GATTC_READ_RESULT = const(15)
_IRQ_GATTC_READ_DONE = const(16)
_IRQ_GATTC_WRITE_DONE = const(17)
_IRQ_GATTC_NOTIFY = const(18)
_IRQ_GATTC_INDICATE = const(19)
_IRQ_GATTS_INDICATE_DONE = const(20)

为了节省固件的空间, 这些内容没有包含在:mod:ubluetooth — 低功耗蓝牙 模块,需自行从上面的列表中选择你所 需要的事件码到你的程序中。

广播规则(对外宣传者)

BLE.gap_advertise(interval_us, adv_data=None, resp_data=None, connectable=True)

在指定时间间隔开始广播(秒). 该间隔将会精确到625us(微妙)。 将*interval_us*设为``None``以停止广播。

adv_data*和*resp_data*可以是任何可实现的缓冲协议 (例如``bytes``, ``bytearray``, ``str``)。 *adv_data*包含于任何广播里, *resp_data 是对已激活的扫描仪的回复。

说明:如果*adv_data* (或*resp_data*)是``None``, 接下来传递给上一个对``gap_advertise``调用 的值将会被再次使用。 This allows a broadcaster to resume advertising 这就意味着只要``gap_advertise(interval_us)`` 就可以让广播恢复对外宣传. 提供一个空的``bytes``以清除广播负载,例如``b’‘``.

观察者角色(扫描仪)

BLE.gap_scan(duration_ms[, interval_us][, window_us])

持续扫描一段时间(秒)。

如果要让开发版一直扫描,请将*duration_ms*设置为``0``.

如果要停止扫描,将*duration_ms*设置为``None``.

扫描仪将每*interval_us*微秒运行*window_us*微秒,共*duration_ms*毫秒。 默认选项分别为 1.28 秒和11.25毫秒(后台扫描).

For each scan result the _IRQ_SCAN_RESULT event will be raised, with event data (addr_type, addr, adv_type, rssi, adv_data). adv_type values correspond to the Bluetooth Specification:

  • 0x00 - ADV_IND - connectable and scannable undirected advertising
  • 0x01 - ADV_DIRECT_IND - connectable directed advertising
  • 0x02 - ADV_SCAN_IND - scannable undirected advertising
  • 0x03 - ADV_NONCONN_IND - non-connectable undirected advertising
  • 0x04 - SCAN_RSP - scan response

当扫描停止时(由于扫描过程结束或者明确地停止),会引发``_IRQ_SCAN_COMPLETE``事件

外围角色 (GATT服务器)

一个蓝牙外设已经有一套已经注册好的服务。每个服务可能包含带有一个值的特征, 特征也包含了自带值的描述符。

这些值都存储在本地,并由服务注册期间生成的“值句柄”访问。他们也被远程中央设备读取 或写入。另外,外围设备可以通过连接句柄将特征“通知”到连接的中央设备。

特征和描述有一个20字节的缺省最大值。 任何通过中央单元写入的内容将会被截断到此长度。然而, 任何一次本地写入将会增加最大尺寸,因此如果你想允许从中心向给定特征进行更大的写入, 在注册之后请使用:meth:gatts_write。 例如:gatts_write(char_handle, bytes(100))

BLE.gatts_register_services(services_definition)

使用特定的服务配置外设, 替代任何设备。

services_definition*是一个**服务**列表,每一个**服务**是一个包含两 个元素的元组,包含了一个UUID和一整个列表的**特征*

每个**特征** 是一个由两到三个元素的元组t,包含一个UUID,一个**flags**值, 以及可选的*descriptors*列表。

每个**描述符**是一个包含两个元素的元组,包含一个UUID和一个**flags**。

The flags are a bitwise-OR combination of the ubluetooth.FLAG_READ, ubluetooth.FLAG_WRITE and ubluetooth.FLAG_NOTIFY values defined below.

返回的是是一列表(一个服务一个元素)的元组(每一个元素有值句柄). 特征和描述符句柄按定义顺序展平到同一元组中。

下面的示例注册了两个服务(心跳和Nordic通用异步收发器):

HR_UUID = bluetooth.UUID(0x180D)
HR_CHAR = (bluetooth.UUID(0x2A37), bluetooth.FLAG_READ | bluetooth.FLAG_NOTIFY,)
HR_SERVICE = (HR_UUID, (HR_CHAR,),)
UART_UUID = bluetooth.UUID('6E400001-B5A3-F393-E0A9-E50E24DCCA9E')
UART_TX = (bluetooth.UUID('6E400003-B5A3-F393-E0A9-E50E24DCCA9E'), bluetooth.FLAG_READ | bluetooth.FLAG_NOTIFY,)
UART_RX = (bluetooth.UUID('6E400002-B5A3-F393-E0A9-E50E24DCCA9E'), bluetooth.FLAG_WRITE,)
UART_SERVICE = (UART_UUID, (UART_TX, UART_RX,),)
SERVICES = (HR_SERVICE, UART_SERVICE,)
( (hr,), (tx, rx,), ) = bt.gatts_register_services(SERVICES)

这里有三个值句柄(hr, tx, rx)可用于:meth:gatts_read, gatts_read, gatts_write, gatts_notify, and gatts_indicate.

提示: 注册服务前对外显示必须被停止。

BLE.gatts_read(value_handle)

读取此句柄的本地值(要么是由:meth:`gatts_write <BLE.gatts_write>`编写的, 要么是由远程中央单元编写的).

BLE.gatts_write(value_handle, data)

写入此句柄的本地值,该值可以被中央单元读取。

BLE.gatts_notify(conn_handle, value_handle[, data])

Sends a notification request to a connected central.

If data is specified, then that value is sent to the central as part of the notification. The local value will not be modified.

Otherwise, if data is not specified, then the current local value (as set with gatts_write) will be sent.

BLE.gatts_indicate(conn_handle, value_handle)

Sends an indication request to a connected central.

Note: This does not currently support sending a custom value, it will always send the current local value (as set with gatts_write).

On acknowledgment (or failure, e.g. timeout), the _IRQ_GATTS_INDICATE_DONE event will be raised.

BLE.gatts_set_buffer(value_handle, len, append=False, /)

设置以字节为单位的值的内部缓冲区大小。这将限制可接收的最大可能写操作。 默认值是20。

将*append*设为``True`` 将所有远程写入追加,而不是替换,当前的值。 大部分*len*字节可以通过这个方式缓冲。 当你使用:meth:gatts_read,这个值将在读取后被清除。 此功能在实现Nordic UART服务时非常有用。

中央处理规则(GATT客户端)

BLE.gap_connect(addr_type, addr, scan_duration_ms=2000, /)

连接到外设。

连接成功后, 将引发``_IRQ_PERIPHERAL_CONNECT``事件。

BLE.gap_disconnect(conn_handle)

断开指定的连接句柄。

断开成功后,将引发``_IRQ_PERIPHERAL_DISCONNECT``事件。

如果链接句柄,返回``False``,``True``则相反。

BLE.gattc_discover_services(conn_handle[, uuid])

查询连接的外围设备以获取其服务。

Optionally specify a service uuid to query for that service only.

For each service discovered, the _IRQ_GATTC_SERVICE_RESULT event will be raised, followed by _IRQ_GATTC_SERVICE_DONE on completion.

BLE.gattc_discover_characteristics(conn_handle, start_handle, end_handle[, uuid])

查询连接的外围设备以获取指定范围内的特征。

Optionally specify a characteristic uuid to query for that characteristic only.

You can use start_handle=1, end_handle=0xffff to search for a characteristic in any service.

For each characteristic discovered, the _IRQ_GATTC_CHARACTERISTIC_RESULT event will be raised, followed by _IRQ_GATTC_CHARACTERISTIC_DONE on completion.

BLE.gattc_discover_descriptors(conn_handle, start_handle, end_handle)

查询连接的外设以查找指定范围内的描述符。

For each descriptor discovered, the _IRQ_GATTC_DESCRIPTOR_RESULT event will be raised, followed by _IRQ_GATTC_DESCRIPTOR_DONE on completion.

BLE.gattc_read(conn_handle, value_handle)

查询连接的外设以查找指定范围内的描述符。对连接的外设发出远程读取以 获取指定的特征或描述符句柄。

When a value is available, the _IRQ_GATTC_READ_RESULT event will be raised. Additionally, the _IRQ_GATTC_READ_DONE will be raised.

BLE.gattc_write(conn_handle, value_handle, data, mode=0, /)

为指定的特征或描述符句柄向连接的外围设备发出远程写入。

The argument mode specifies the write behaviour, with the currently supported values being:

  • mode=0 (default) is a write-without-response: the write will be sent to the remote peripheral but no confirmation will be returned, and no event will be raised.
  • mode=1 is a write-with-response: the remote peripheral is requested to send a response/acknowledgement that it received the data.

If a response is received from the remote peripheral the _IRQ_GATTC_WRITE_DONE event will be raised.

class UUID

Constructor

class ubluetooth.UUID(value)

创建具有指定**值**的UUID实例。

**值**可以是:

  • 16位整数 例如 0x2908.
  • 128位UUID字符串 例如 '6E400001-B5A3-F393-E0A9-E50E24DCCA9E'.

常数

ubluetooth.FLAG_READ
ubluetooth.FLAG_WRITE
ubluetooth.FLAG_NOTIFY