模块: Bluetooth
约 5760 字大约 19 分钟
2026-03-18
构建固件和导入到JS
额外组件
该功能需要安装 beshell-bt 组件才能使用。
安装方法:
- 编辑项目根目录下的
idf_component.yml文件,添加依赖:
dependencies:
become-cool/beshell-bt: '>=1.0.2'- 或在 ESP-IDF 环境的命令行中执行:
idf.py add-dependency "become-cool/beshell-bt>=1.0.2"在 C++ 里加入以下代码, 然后重新编译构建固件:
// 为了控制固件的尺寸,BeShell 的 module 是按需引入的。
beshell.use<be::bt::BT>() ;在JS中导入 bt module:
import * as bt from 'bt'import bt简介
bt 模块提供了完整的 BLE(低功耗蓝牙)功能,支持 Central(主机)和 Peripheral(从机)两种模式。
导出对象
bt 模块预创建了以下对象:
peripheral - 类 Peripheral 实例,用于 BLE 从机模式
此外,bt 模块还导出了以下简写形式,与完整名称等价:
bt.centbt.periphbt.pher
使用示例:
import * as bt from 'bt'
// 以下写法等价
bt.central.init()
bt.cent.init()
bt.peripheral.addService({...})
bt.periph.addService({...})
bt.pher.addService({...})Central 模式(主机)
Central 模式用于连接并操作其他 BLE 设备(Peripheral):
import * as bt from 'bt'
// 初始化并扫描设备
bt.central.init()
bt.startScan()
bt.on('scan-res', async (device) => {
if (device.addr === 'AA:BB:CC:DD:EE:FF') {
bt.stopScan()
// 连接设备
const peer = await bt.central.connect(device.addr, 5000)
await peer.search()
// 读写特征
const data = await peer['2a37'].read()
await peer['2a37'].write(new Uint8Array([0x01]))
}
})Peripheral 模式(从机)
Peripheral 模式用于创建 BLE 服务,供其他设备(Central)连接:
import * as bt from 'bt'
// 初始化并创建服务
bt.peripheral.init()
const service = bt.peripheral.addService({
uuid: '180d',
primary: true,
chars: [
{ uuid: '2a37', props: ['read', 'notify'] }
]
})
// 设置特征值并发送通知
service.chars['2a37'].setValue('hello')
service.chars['2a37'].notify('data updated')
// 开始广播
bt.startAdv()模块函数
函数 setPower
原型: setPower (level:number, type:number=0)
设置 BLE 发射功率
示例:
import * as bt from 'bt'
// 设置默认发射功率为 6dBm
bt.setPower(6)
// 设置指定类型的发射功率
bt.setPower(6, 0) // 设置默认功率类型参数:
level
类型number
参数说明功率等级,取值范围 -24 ~ 21 (dBm)
type
类型number
默认值0
参数说明功率类型,0 表示默认类型
异常:
- 功率等级无效
- 功率类型无效
返回值:
类型number
说明错误码,0 表示成功
函数 power
原型: power ()
获取 BLE 当前发射功率
示例:
import * as bt from 'bt'
const power = bt.power()
console.log('当前功率:', power, 'dBm')返回值:
类型number
说明当前发射功率等级 (dBm)
函数 setRandomMac
原型: setRandomMac (mac:string)
设置 BLE 随机 MAC 地址
示例:
import * as bt from 'bt'
// 设置随机 MAC 地址
bt.setRandomMac('AA:BB:CC:DD:EE:FF')参数:
mac
类型string
参数说明MAC 地址字符串,格式为 "xx:xx:xx:xx:xx:xx"
异常:
- MAC 地址格式无效
- 设置 MAC 地址失败
返回值:
类型undefined
函数 parseAdv central侧
原型: parseAdv (raw:ArrayBuffer)
解析广播数据(Central 角色)
作为 Central 将扫描到的原始广播数据解析为对象格式,方便读取设备名称、UUID 等信息。 支持的字段包括:flag、name、shortName、complete16、more16、complete128、 more128、txPower、service16、service128、msd 等。
示例:
import * as bt from 'bt'
bt.on('scan-res', (device) => {
const adv = bt.parseAdv(device.adv_raw)
// 获取设备名称
if (adv.name) {
const name = new TextDecoder().decode(adv.name)
console.log('设备名称:', name)
}
// 获取 16-bit UUID
if (adv.complete16) {
const uuid = '0x' + Array.from(adv.complete16).map(b => b.toString(16).padStart(2, '0')).join('')
console.log('UUID:', uuid)
}
// 获取制造商数据
if (adv.msd) {
console.log('制造商数据:', adv.msd)
}
})参数:
raw
类型ArrayBuffer
参数说明原始广播数据
返回值:
类型object
说明解析后的广播数据对象,包含 name、flag、complete16 等字段
函数 waitScanning central侧
原型: waitScanning (ms:number=10000)
等待扫描完成(Central 角色)
作为 Central 等待扫描完成,返回一个 Promise,当扫描完成时 resolve。 如果当前没有在扫描,立即 resolve。扫描可能因调用 stopScan() 或达到设定的扫描持续时间而完成。
示例:
import * as bt from 'bt'
bt.startScan()
// 等待最多 10 秒扫描完成
await bt.waitScanning(10000)
console.log('扫描完成')
// 无限等待扫描完成
await bt.waitScanning()参数:
ms
类型number
默认值10000
参数说明超时时间(毫秒),0 表示无限等待
返回值:
类型Promise<undefined>
说明扫描完成时 resolve,超时时 reject
函数 setMTU
原型: setMTU (mtu:number)
设置本地 MTU 大小
设置 BLE 协议栈的本地 MTU (Maximum Transmission Unit) 大小。 默认值为 23 字节,最大可设置为 517 字节。
示例:
import * as bt from 'bt'
// 设置 MTU 为 185 字节
bt.setMTU(185)参数:
mtu
类型number
参数说明MTU 大小,范围 23 ~ 517
异常:
- MTU 大小无效
- 设置 MTU 失败
返回值:
类型undefined
函数 getMTU
原型: getMTU ()
获取当前 MTU 大小
获取当前设置的本地 MTU 大小。
示例:
import * as bt from 'bt'
const mtu = bt.getMTU()
console.log('当前 MTU:', mtu)返回值:
类型number
说明当前 MTU 大小
函数 setScanParam central侧
原型: setScanParam (options:object)
设置 BLE 扫描参数(Central 角色)
在 Central 模式下开始扫描前配置扫描参数,包括扫描类型、间隔、窗口等。
示例:
import * as bt from 'bt'
bt.setScanParam({
scan_type: 0, // 0: 被动扫描, 1: 主动扫描
own_addr_type: 0, // 0: 公共地址, 1: 随机地址
scan_filter_policy: 0, // 0: 接受所有, 1: 只接受白名单
scan_interval: 0x50, // 扫描间隔 (0x0004 ~ 0x4000)
scan_window: 0x40, // 扫描窗口 (0x0004 ~ 0x4000)
scan_duplicate: 0 // 0: 不重复, 1: 重复
})参数:
options
类型object (详见下方类型定义)
参数说明扫描参数对象
options 类型定义:
{ scan_type?: number, // 扫描类型:0 被动扫描,1 主动扫描,默认 0 own_addr_type?: number, // 自身地址类型:0 公共地址,1 随机地址,默认 0 scan_filter_policy?: number, // 扫描过滤策略,默认 0 scan_interval?: number, // 扫描间隔,默认 0x50 scan_window?: number, // 扫描窗口,默认 0x40 scan_duplicate?: number // 重复扫描策略,默认 0 }
异常:
- 设置扫描参数失败
- BLE 4.2 不支持
返回值:
类型undefined
函数 startScan central侧
原型: startScan (duration:number=4294967295)
开始扫描 BLE 设备(Central 角色)
作为 Central 开始扫描周围的 BLE 设备,扫描结果通过 'scan-res' 事件返回。
示例:
import * as bt from 'bt'
// 监听扫描结果
bt.on('scan-res', (device) => {
console.log('发现设备:', device.addr, 'RSSI:', device.rssi)
})
// 开始扫描,持续 10 秒
bt.startScan(10)
// 无限扫描
bt.startScan()参数:
duration
类型number
默认值4294967295
参数说明扫描持续时间(秒),默认为无限
异常:
- 开始扫描失败
- BLE 4.2 不支持
返回值:
类型undefined
函数 stopScan central侧
原型: stopScan ()
停止扫描 BLE 设备(Central 角色)
作为 Central 停止扫描周围的 BLE 设备。
示例:
import * as bt from 'bt'
bt.stopScan()异常:
- BLE 4.2 不支持
返回值:
类型boolean
说明是否成功停止
函数 isScanning central侧
原型: isScanning ()
检查是否正在扫描(Central 角色)
检查 Central 是否正在扫描 BLE 设备。
示例:
import * as bt from 'bt'
if (bt.isScanning()) {
console.log('正在扫描中...')
}返回值:
类型boolean
说明是否正在扫描
函数 connect central侧
原型: connect (addr:string)
连接到 BLE 设备(Central 角色)
作为 Central 连接到指定的 BLE 设备。
示例:
import * as bt from 'bt'
// 连接到指定 MAC 地址的设备
bt.connect('AA:BB:CC:DD:EE:FF')
// 使用 JS 侧封装的 Promise API
const peer = await bt.central.connect('AA:BB:CC:DD:EE:FF', 5000)参数:
addr
类型string
参数说明目标设备的 MAC 地址,格式为 "xx:xx:xx:xx:xx:xx"
异常:
- 未初始化 Central 模式
- MAC 地址格式无效
- 连接失败
返回值:
类型undefined
函数 disconnect central侧
原型: disconnect (conn_id:number)
断开与 BLE 设备的连接(Central 角色)
作为 Central 断开与指定 BLE 设备的连接。
示例:
import * as bt from 'bt'
// 断开指定连接 ID 的设备
bt.disconnect(connId)参数:
conn_id
类型number
参数说明连接 ID
异常:
- 未初始化 Central 模式
- 断开连接失败
返回值:
类型undefined
函数 requestMTU central侧
原型: requestMTU (conn_id:number)
请求更新 MTU (Maximum Transmission Unit)(Central 角色)
作为 Central 向连接的设备请求更新 MTU 大小。
示例:
import * as bt from 'bt'
bt.requestMTU(connId)
// 等待 MTU 更新完成
bt.once('cfg-mtu', (status, connId, mtu) => {
console.log('MTU 更新为:', mtu)
})参数:
conn_id
类型number
参数说明连接 ID
异常:
- 未初始化 Central 模式
返回值:
类型undefined
函数 search central侧
原型: search (conn_id:number)
搜索 BLE 设备的服务和特征(Central 角色)
作为 Central 在已连接的设备上搜索所有 GATT 服务和特征。 搜索结果通过 'search-res' 和 'search-cmpl' 事件返回。
示例:
import * as bt from 'bt'
bt.on('search-res', (connId, service) => {
console.log('发现服务:', service.uuid)
console.log('特征列表:', service.chars)
})
bt.on('search-cmpl', (status, connId) => {
console.log('搜索完成')
})
bt.search(connId)参数:
conn_id
类型number
参数说明连接 ID
异常:
- 未初始化 Central 模式
返回值:
类型undefined
函数 read central侧
原型: read (conn_id:number, handle:number)
读取特征值(Central 角色)
作为 Central 从已连接设备的指定特征读取数据。 读取结果通过 'read-char' 事件返回。
示例:
import * as bt from 'bt'
bt.on('read-char', (status, handle, data) => {
if (status === 0) {
console.log('读取成功:', data)
}
})
bt.read(connId, charHandle)参数:
conn_id
类型number
参数说明连接 ID
handle
类型number
参数说明特征句柄
异常:
- 未初始化 Central 模式
- 读取失败
返回值:
类型undefined
函数 write central侧
原型: write (conn_id:number, handle:number, data:ArrayBuffer, rsp:boolean=false)
写入特征值(Central 角色)
作为 Central 向已连接设备的指定特征写入数据。 写入结果通过 'write-char' 事件返回。
示例:
import * as bt from 'bt'
bt.on('write-char', (status, handle, offset) => {
if (status === 0) {
console.log('写入成功')
}
})
// 写入数据(不需要响应)
bt.write(connId, handle, new Uint8Array([0x01, 0x02]))
// 写入数据(需要响应)
bt.write(connId, handle, new Uint8Array([0x01, 0x02]), true)参数:
conn_id
类型number
参数说明连接 ID
handle
类型number
参数说明特征句柄
data
类型ArrayBuffer
参数说明要写入的数据
rsp
类型boolean
默认值false
参数说明是否需要响应
异常:
- 未初始化 Central 模式
- 数据格式无效
- 写入失败
返回值:
类型undefined
函数 subscribe central侧
原型: subscribe (conn_id:number, handle:number, type:number=1)
订阅特征值通知(Central 角色)
作为 Central 订阅指定特征的通知或指示。订阅成功后,设备会主动推送数据变化。 订阅结果通过 'write-desc' 事件返回。
示例:
import * as bt from 'bt'
bt.on('write-desc', (status, handle, offset) => {
if (status === 0) {
console.log('订阅成功')
}
})
// 订阅通知 (type=1)
bt.subscribe(connId, cccdHandle, 1)
// 订阅指示 (type=2)
bt.subscribe(connId, cccdHandle, 2)参数:
conn_id
类型number
参数说明连接 ID
handle
类型number
参数说明CCCD (Client Characteristic Configuration Descriptor) 句柄
type
类型number
默认值1
参数说明订阅类型:1 通知 (Notification),2 指示 (Indication)
异常:
- 未初始化 Central 模式
- 订阅类型无效
- 订阅失败
返回值:
类型undefined
函数 setAdvName peripheral侧
原型: setAdvName (name:string)
设置广播设备名称(Peripheral 角色)
作为 Peripheral 设置 BLE 设备在广播时显示的名称。
示例:
import * as bt from 'bt'
bt.peripheral.init()
bt.setAdvName('MyBLEDevice')
bt.startAdv()参数:
name
类型string
参数说明设备名称
异常:
- 未初始化 Peripheral 模式
- 设置名称失败
返回值:
类型undefined
函数 setAdvData peripheral侧
原型: setAdvData (data:ArrayBuffer)
设置原始广播数据(Peripheral 角色)
作为 Peripheral 设置 BLE 广播的原始数据包内容。
示例:
import * as bt from 'bt'
// 设置自定义广播数据
const advData = new Uint8Array([
0x02, 0x01, 0x06, // 广播标志
0x03, 0x03, 0xAA, 0xFE // 16-bit UUID
])
bt.setAdvData(advData.buffer)参数:
data
类型ArrayBuffer
参数说明原始广播数据
异常:
- 未初始化 Peripheral 模式
- 设置广播数据失败
返回值:
类型undefined
函数 startAdv peripheral侧
原型: startAdv (options:object)
开始 BLE 广播(Peripheral 角色)
作为 Peripheral 开始发送 BLE 广播包,让其他设备可以发现并连接。
示例:
import * as bt from 'bt'
// 使用默认参数开始广播
bt.startAdv()
// 自定义广播参数
bt.startAdv({
min: 0xA0, // 最小广播间隔
max: 0xB0, // 最大广播间隔
type: 0, // 广播类型
own_addr_type: 0, // 自身地址类型
channel_map: 0x07, // 广播通道映射
adv_filter_policy: 0 // 广播过滤策略
})参数:
options
类型object (详见下方类型定义)
参数说明可选的广播参数
options 类型定义:
{ min?: number, // 最小广播间隔,默认 0xA0 max?: number, // 最大广播间隔,默认 0xB0 type?: number, // 广播类型,默认 0 own_addr_type?: number, // 自身地址类型,默认 0 channel_map?: number, // 广播通道映射,默认 0x07 adv_filter_policy?: number // 广播过滤策略,默认 0 }
异常:
- 未初始化 Peripheral 模式
- 开始广播失败
返回值:
类型undefined
函数 stopAdv peripheral侧
原型: stopAdv ()
停止 BLE 广播(Peripheral 角色)
作为 Peripheral 停止发送 BLE 广播包。
示例:
import * as bt from 'bt'
bt.stopAdv()异常:
- 未初始化 Peripheral 模式
- 停止广播失败
返回值:
类型undefined
函数 addService peripheral侧
原型: addService (uuid:string, num_handles:number)
添加 GATT 服务(Peripheral 角色)
作为 Peripheral 添加一个 GATT 服务。服务创建成功后会自动启动。
示例:
import * as bt from 'bt'
// 添加一个心率服务 (0x180D)
const serviceHandle = bt.addService('180D', 10)
console.log('服务句柄:', serviceHandle)参数:
uuid
类型string
参数说明服务的 UUID(16位、32位或128位)
num_handles
类型number
参数说明服务的句柄数量
异常:
- 未初始化 Peripheral 模式
- UUID 格式无效
- 创建服务失败
- 服务创建超时
返回值:
类型number
说明服务句柄
函数 addChar peripheral侧
原型: addChar (service_handle:number, uuid:string, perm:string|Array)
添加 GATT 特征(Peripheral 角色)
作为 Peripheral 在指定服务中添加一个 GATT 特征。
示例:
import * as bt from 'bt'
// 添加一个可读写的特征
const charHandle = bt.addChar(serviceHandle, '2A37', 'read,write,notify')
// 使用数组指定权限
const charHandle = bt.addChar(serviceHandle, '2A37', ['read', 'write', 'notify'])参数:
service_handle
类型number
参数说明服务句柄
uuid
类型string
参数说明特征的 UUID
perm
类型string, Array
参数说明权限,可以是字符串(如 "read,write")或数组(如 ["read", "write"])
- read: 可读
- write: 可写(需要响应)
- writeNR: 可写(不需要响应)
- notify: 支持通知
- indicate: 支持指示
异常:
- 未初始化 Peripheral 模式
- UUID 格式无效
- 权限参数无效
- 添加特征失败
- 添加特征超时
返回值:
类型number
说明特征句柄
函数 setCharValue peripheral侧
原型: setCharValue (char_handle:number, value:string|ArrayBuffer|number)
设置特征值(Peripheral 角色)
作为 Peripheral 设置指定特征的本地值。当 Central 读取该特征时,会返回此值。
示例:
import * as bt from 'bt'
// 设置字符串值
bt.setCharValue(charHandle, 'hello world')
// 设置二进制数据
bt.setCharValue(charHandle, new Uint8Array([0x01, 0x02, 0x03]).buffer)
// 设置数字值(4字节小端序)
bt.setCharValue(charHandle, 12345)参数:
char_handle
类型number
参数说明特征句柄
value
类型string, ArrayBuffer, number
参数说明要设置的值
异常:
- 未初始化 Peripheral 模式
- 特征句柄无效
- 值类型无效
- 设置值失败
返回值:
类型undefined
函数 sendNotify peripheral侧
原型: sendNotify (char_handle:number, data:string|ArrayBuffer, is_indication:boolean=false, conn_id:number)
发送通知或指示(Peripheral 角色)
作为 Peripheral 向已连接的 Central 设备发送特征值通知或指示。 如果数据长度超过 MTU,会自动分包发送。
示例:
import * as bt from 'bt'
// 发送通知
bt.sendNotify(charHandle, 'data updated')
// 发送指示(需要确认)
bt.sendNotify(charHandle, 'important data', true)
// 发送到指定连接
bt.sendNotify(charHandle, 'data', false, connId)参数:
char_handle
类型number
参数说明特征句柄
data
类型string, ArrayBuffer
参数说明要发送的数据
is_indication
类型boolean
默认值false
参数说明是否为指示(需要确认)
conn_id
类型number
参数说明连接 ID(可选,默认使用最后连接的 ID)
异常:
- 未初始化 Peripheral 模式
- 特征句柄无效
- 没有设备连接
- 数据类型无效
- 发送失败
返回值:
类型undefined
