提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录
- 一、服务和特性
- 二、数据收发
- 三、UUID
一、服务和特性
service、characteristic
下面的图是蓝牙协议的整体架构,
1.物理层:负责无线电波的收发和信号链路的管理
2.协议层:主要实现蓝牙协议栈
3.应用层:根据业务需求实现不同的程序,比如电池电量,温度计,hid键值,
基本要改的都在应用层,协议和物理很多都固定,都在芯片厂那里改
其中HCI是主机与控制器之间的通信接口,很多时候找bug会在这里捉。
我现在使用手机连接一个蓝牙鼠标,然后使用lightblue app进行查看它的服务和特性,这里只展示了部分
蓝牙设备应用层是通过特性和服务来实现的,
一个蓝牙设备可以有很多服务,一个服务又又很多的特性,每个特性又有读写,通知等权限。
每一个服务和特性都有一个uuid
uuid是蓝牙组织用于定义的,用于区分各个服务和特性的标识符,总长度是128bit;
其中,蓝牙组织允许用户使用16bit的uuid 与该基地址拼接,形成128bit的uuid,比如,使用16bit的uuid是2a37,
128bit就是00002a37 - 0000 - 1000 - 8000 - 00805f9b34fb
通过程序代码构建一个蓝牙应用设备,所要求的服务和特性
假如程序的要求是:
有一个服务其中uuid是9011,服务中有两个特性,特性A的uuid是9012,访问权限是可读,可写,特性B的uuid是9013,访问权限是可读,可通知
分3步写:
1.
#创建要使用的UUID
SERVER_1_UUID = ubluetooth.UUID(0x9011)
CHAR_A_UUID = ubluetooth.UUID(0x9012)
CHAR_B_UUID = ubluetooth.UUID(0x9013)
#创建特性并设置特性的读写权限
CHAR_A = (CHAR_A_UUID, ubluetooth.FLAG_READ | ubluetooth.FLAG_WRITE, )
CHAR_B = (CHAR_B_UUID, ubluetooth.FLAG_READ | ubluetooth.FLAG_NOTIFY, )
SERVER_1 = (SERVER_1_UUID, (CHAR_A , CHAR_B, ) , ) #把特性A和特性B放入服务1
SERVICES = (SERVER_1, ) #把服务1放入服务集和中
((char_a, char_b), ) = ble.gatts_register_services(SERVICES) #注册服务到gatts
可将其放入上一个程序进行实验
二、数据收发
数据的收发都要依托上面服务中的特性这些数据点,其中他们的权限共有5种,分别是读,写,写但是无应答,通知,标示
其中,这些权限都有什么区别呢
通过手机和从设备来解释
1.读,手机读去从机某个特性的值
2.写,手机修改设备中某个特性的值
3.写但无应答,。。
4.通知,是设备里面的数据发生变化之后,通知手机来取数据
5.标示,跟通知类似,但是须有手机收到后回应
案例:
from machine import Pin
from time import sleep_ms
import ubluetooth #导入BLE功能模块ble = ubluetooth.BLE() #创建BLE设备
ble.active(True) #打开BLE#创建要使用的UUID
SERVER_1_UUID = ubluetooth.UUID(0x9011)
CHAR_A_UUID = ubluetooth.UUID(0x9012)
CHAR_B_UUID = ubluetooth.UUID(0x9013)#创建特性并设置特性的读写权限
CHAR_A = (CHAR_A_UUID, ubluetooth.FLAG_READ | ubluetooth.FLAG_WRITE | ubluetooth.FLAG_NOTIFY, )
CHAR_B = (CHAR_B_UUID, ubluetooth.FLAG_READ | ubluetooth.FLAG_NOTIFY, )SERVER_1 = (SERVER_1_UUID, (CHAR_A , CHAR_B, ) , ) #把特性A和特性B放入服务1
SERVICES = (SERVER_1, ) #把服务1放入服务集和中
((char_a, char_b), ) = ble.gatts_register_services(SERVICES) #注册服务到gatts#设置BLE广播数据并开始广播
ble.gap_advertise(100, adv_data = b'\x02\x01\x06\x03\x09\x41\x42')def ble_irq(event, data): # 蓝牙中断函数if event == 1: #蓝牙已连接print("BLE 连接成功")elif event == 2: #蓝牙断开连接print("BLE 断开连接")ble.gap_advertise(100, adv_data = b'\x02\x01\x06\x03\x09\x41\x42')elif event == 3: #收到数据 ,当收到write请求时触发该事件onn_handle, char_handle = data #判断是来自那个特性的消息buffer = ble.gatts_read(char_handle) #读取接收到的消息print(char_handle, buffer) #打印消息内容ble.gatts_notify(0, char_handle, 'Hello') #回复Hello#这里是设备收到通知,就回复手机hello (手机要打开对设备的监听)ble.irq(ble_irq)
三、UUID
蓝牙组织定义好的一些UUID,比如电量服务-0x180F
16bit uuid文档