master
# 简介
BLE master,蓝牙主模式,可以扫描周围的蓝牙信号,并主动与蓝牙设备建立连接,被连接的设备则为蓝牙从模式
# API说明
以下API是模块BLE主模式用到的接口,其余接口及具体接口参数说明和用法请到API说明章节和demo内查看并学习
| API接口 | 描述 |
| ------------------------- | -------------------------------------- |
| btcore.open() | 打开蓝牙 |
| btcore.close() | 关闭蓝牙 |
| btcore.state() | 查询蓝牙状态(开启或者关闭)|
| btcore.connect() | 蓝牙建立连接 |
| btcore.disconnect() | 蓝牙主动断开连接 |
| btcore.scan() | 蓝牙广播开关 |
| btcore.setscanparam() | 设置蓝牙扫描参数 |
| btcore.findservice() | 蓝牙发现服务 |
| btcore.findcharacteristic() | 蓝牙发现服务内的特征 |
| btcore.opennotification() | 蓝牙打开通知 |
| btcore.closenotification() | 蓝牙关闭通知 |
| btcore.send() | 写数据 |
| btcore.recv() | 读数据 |
| btcore.getaddr() | 获取本机蓝牙MAC地址 |
BLE从设备模式用到的蓝牙消息
| API接口 | 描述 |
| ------------------------- | -------------------------------------- |
| MSG_OPEN_CNF | 蓝牙打开成功 |
| MSG_CLOSE_CNF | 蓝牙关闭成功 |
| MSG_BLE_CONNECT_CNF | 蓝牙主模式连接 |
| MSG_BLE_DISCONNECT_CNF | 蓝牙主模式断开连接 |
| MSG_BLE_DATA_IND | 数据接收 |
| MSG_BLE_SCAN_CNF | 蓝牙扫描打开 |
| MSG_BLE_SCAN_IND | 扫描广播包/响应包数据 |
| MSG_BLE_FIND_CHARACTERISTIC_IND | 发现服务包含的特征 |
| MSG_BLE_FIND_SERVICE_IND | 发现蓝牙包含的服务的uuid |
| MSG_BLE_FIND_CHARACTERISTIC_UUID_IND | 发现蓝牙特征的uuid |
> 详细的API介绍见[btcore API章节](https://doc.openluat.com/wiki/21?wiki_page_id=2244)
## 实现流程
- 注册蓝牙消息回调函数
通过rtos.on() 注册蓝牙消息回调函数
- 打开蓝牙
使用btcore.open(1)打开蓝牙主模式
- 设置扫描参数
使用btcore.setscanparam()设置扫描参数
- 开启扫描
使用btcore.scan(1)开启扫描
- 收集蓝牙扫描到的参数
包括广播包/响应包、蓝牙地址、地址类型、信号强度、厂商数据
用户可以自定义变量来保存想要连接的扫描到的蓝牙数据
- 关闭扫描
btcore.scan(0)
- 连接蓝牙
使用btcore.connect()来连接蓝牙
- 连接成功后就可以进行数据的收发
- 收数据 btcore.recv()来读取数据
- 发数据 btcore.send()来发送数据
## 示例
以\script_LuaTask_V2.3.9\demo\bluetooth\master.lua作为基础进行修改。首先使用rtos.on()注册蓝牙消息的回调处理函数。
**初始化注册蓝牙消息回调函数**
```lua
local function init()
rtos.on(rtos.MSG_BLUETOOTH, function(msg)
if msg.event == btcore.MSG_OPEN_CNF then
sys.publish("BT_OPEN", msg.result) --蓝牙打开成功
elseif msg.event == btcore.MSG_CLOSE_CNF then
log.info("bt", "ble close") --蓝牙关闭成功
elseif msg.event == btcore.MSG_BLE_CONNECT_CNF then
sys.publish("BT_CONNECT_IND", {["handle"] = msg.handle, ["result"] = msg.result}) --蓝牙连接成功
elseif msg.event == btcore.MSG_BLE_DISCONNECT_CNF then
log.info("bt", "ble disconnect") --蓝牙断开连接
elseif msg.event == btcore.MSG_BLE_DATA_IND then
sys.publish("BT_DATA_IND", {["data"] = msg.data, ["uuid"] = msg.uuid, ["len"] = msg.len}) --接收到的数据内容
elseif msg.event == btcore.MSG_BLE_SCAN_CNF then
sys.publish("BT_SCAN_CNF", msg.result) --打开扫描成功
elseif msg.event == btcore.MSG_BLE_SCAN_IND then
sys.publish("BT_SCAN_IND", {["name"] = msg.name, ["addr_type"] = msg.addr_type, ["addr"] = msg.addr, ["manu_data"] = msg.manu_data,
["raw_data"] = msg.raw_data, ["raw_len"] = msg.raw_len, ["rssi"] = msg.rssi}) --接收到扫描广播包数据
elseif msg.event == btcore.MSG_BLE_FIND_CHARACTERISTIC_IND then
sys.publish("BT_FIND_CHARACTERISTIC_IND", msg.result) --发现服务包含的特征
elseif msg.event == btcore.MSG_BLE_FIND_SERVICE_IND then
log.info("bt", "find service uuid",msg.uuid) --发现蓝牙包含的16bit uuid
if msg.uuid == 0x1800 then --根据想要的uuid修改
sys.publish("BT_FIND_SERVICE_IND", msg.result)
end
elseif msg.event == btcore.MSG_BLE_FIND_CHARACTERISTIC_UUID_IND then
uuid_c = msg.uuid
log.info("bt", "find characteristic uuid", msg.uuid, type(msg.uuid)) --发现到服务内包含的特征uuid
end
end)
end
```
**打开蓝牙**
```lua
local function poweron()
log.info("bt", "poweron")
btcore.open(1) --打开蓝牙主模式
_, result = sys.waitUntil("BT_OPEN", 5000) --等待蓝牙打开成功
if result ~= 0 then --5秒超时没收到蓝牙打开成功的消息,则返回失败
return false
end
end
```
**设置扫描参数,开启扫描,收集扫描到的蓝牙信息**
```lua
local function scan()
--btcore.setscanparam(1,48,6,0,0)--扫描参数设置(扫描类型,扫描间隔,扫描窗口,扫描过滤测量,本地地址类型)
--如果不设置扫描参数,则使用默认的值
btcore.scan(1) --开启扫描
_, result = sys.waitUntil("BT_SCAN_CNF", 50000) --等待扫描打开成功
if result ~= 0 then
return false
end
while true do --循环等待扫描到的蓝牙信息
_, bt_device = sys.waitUntil("BT_SCAN_IND") --等待扫描回复数据
--蓝牙信息包括以下几种:蓝牙名称、蓝牙信号强度、地址种类(Public Device Address、Random Device Address),蓝牙mac地址、厂商数据、广播包/响应包数据
log.info("bt", "scan result")
log.info("bt.scan_name", bt_device.name) --蓝牙名称
log.info("bt.rssi", bt_device.rssi) --蓝牙信号强度
log.info("bt.addr_type", bt_device.addr_type) --地址种类
log.info("bt.scan_addr", bt_device.addr) --蓝牙地址
if bt_device.manu_data ~= nil then --厂商数据可能为空
log.info("bt.manu_data", string.toHex(bt_device.manu_data)) --厂商数据
end
log.info("bt.raw_len", bt_device.raw_len)
if bt_device.raw_data ~= nil then
log.info("bt.raw_data", string.toHex(bt_device.raw_data)) --广播包原始数据
end
--蓝牙连接 根据设备蓝牙广播数据协议解析广播原始数据(bt_device.raw_data)
if (bt_device.name == "TESTBLE") then --连接的蓝牙名称根据要连接的蓝牙设备修改
name = bt_device.name --蓝牙名称
addr_type = bt_device.addr_type --地址类型
addr = bt_device.addr --蓝牙地址
manu_data = bt_device.manu_data --厂商数据
adv_data = bt_device.raw_data -- 广播包数据 根据蓝牙广播包协议解析
btcore.scan(0) --停止扫描
btcore.connect(addr, addr_type) --连接蓝牙,蓝牙mac地址,地址类型
return true
end
end
return true
end
```
**发现服务与特征
```lua
local function find_uuid()
_, bt_connect = sys.waitUntil("BT_CONNECT_IND") --等待连接成功
if bt_connect.result ~= 0 then
return false
end
--链接成功
log.info("bt.connect_handle", bt_connect.handle)--蓝牙连接句柄
log.info("bt", "find all service uuid")
btcore.findservice()--发现所有16bit服务uuid
_, result = sys.waitUntil("BT_FIND_SERVICE_IND") --等待发现uuid
if not result then
return false
end
btcore.findcharacteristic(0xfee0)--发现服务包含的特征,fee0为测试时设置的服务uuid
_, result = sys.waitUntil("BT_FIND_CHARACTERISTIC_IND") --等待发现服务包含的特征成功
if not result then
return false
end
btcore.opennotification(0xfee2); --打开通知 对应特征uuid ,ff01为特征uuid,具有notify属性
log.info("bt.send", "Hello I'm LuatOS-Air BLE")
end
```
**数据传输**
```lua
local function data_trans()
while true do
local data = "123456"
btcore.send(data, 0xfee2, bt_connect.handle) --发送数据(数据 对应特征uuid 连接句柄)
_, bt_recv = sys.waitUntil("BT_DATA_IND") --等待接收到数据
local data = ""
local len = 0
local uuid = ""
while true do
local recvuuid, recvdata, recvlen = btcore.recv(3)
if recvlen == 0 then
break
end
uuid = recvuuid
len = len + recvlen
data = data .. recvdata
end
if len ~= 0 then
log.info("bt.recv_data", data)
log.info("bt.recv_data len", len)
log.info("bt.recv_uuid",string.toHex(uuid))
end
end
end
```
**最后将以上几个功能模块结合起来,就实现了一个简易的蓝牙连接收发数据功能**
```lua
sys.taskInit(
function()
init()
poweron()
scan()
find_uuid()
data_trans()
end
)
```
# 注意事项
使用手机、电脑与模块低功耗蓝牙进行测试时,需要使用专门的低功耗蓝牙调试软件
手机低功耗蓝牙调试软件这里推荐使用nRF Connect
[nRF Connect下载及使用教程](https://hmi.wiki.luatos.com/doc/65042949/e6zPC3k9/sivVjmZk)