虽然设备上没有蓝牙模块,我们依旧可以通过USB的星闪模组实现蓝牙ble相关的功能,例如读取小米温湿度计的数据。
首先需要加载对应的模块,这些模块在前面一个章节已经编译好了。
insmod cfg80211.ko
insmod plat_soc.ko
insmod ble_soc.ko
成功加载这些模块后,我们需要在ubuntu系统里安装bluez,也就是最常见的蓝牙调试工具。apt upgrade bluez
安装好工具后,可以先使用工具简单的测试下,例如扫描设备什么的。这里我们就跳过了。
然后,我们需要创建一个虚拟环境,好安装脚本需要的依赖,这里我们考虑使用Python脚本来抓取ble广播数据包,然后解析数据。
先安装虚拟环境所需的依赖。
apt install python3 python3-pip python3-venv
安装完成后,创建一个虚拟环境。python3 -m venv myenv
然后再激活这个环境。source myenv/bin/activate
接下来,安装python的bleak软件包,可以用这个软件可以轻松的操作ble模块,实现一些常见的ble设备功能,如设备发现,连接,读写GATT 特性等等。
pip install bleak
然后就是编写这部分代码了。写好的代码如下:
import asyncio
from bleak import BleakScanner
def parse_broadcast(device, advertisement_data):
# 检查服务数据是否包含目标UUID前缀
if advertisement_data.service_data:
for uuid in advertisement_data.service_data.keys():
# 只处理UUID前缀为"0000fe95"的数据
if uuid.startswith("0000fe95"): # 小米协议UUID前缀
data_bytes = advertisement_data.service_data[uuid]
# 解析温湿度数据(需满足长度和类型条件)
if (
len(data_bytes) >= 18 and data_bytes[11] == 0x0D
): # 温湿度组合包[4]
# 解析小端序数据(字节14-17)
temp = int.from_bytes(data_bytes[14:16], byteorder="little") / 10.0
humi = int.from_bytes(data_bytes[16:18], byteorder="little") / 10.0
# print(f"\n设备地址: {device.address}")
print(f"\n服务UUID: {uuid}, 设备地址: {device.address}")
print(f"温度: {temp}°C, 湿度: {humi}%")
# else:
# print(f"\n收到无效数据包 (长度: {len(data_bytes)})")
# print(f"设备地址: {device.address}")
# hex_data = data_bytes.hex().upper()
# print(f"服务UUID: {uuid}, 数据: {hex_data}")
async def main():
scanner = BleakScanner(detection_callback=parse_broadcast)
await scanner.start()
print("开始监听小米设备广播 (UUID前缀: 0000fe95)...")
await asyncio.sleep(60.0) # 持续监听60秒
await scanner.stop()
print("监听结束")
asyncio.run(main())
这里的代码其实非常的简单,就是开启一个ble监听服务,然后如果接收到数据就进入回调函数parse_broadcast。
这个函数的代码也很简单,检测到UUID前缀为"0000fe95"的数据后,判断数据长度和类型,符合条件的,就解析数据并输出。(github上有很多是连接蓝牙设备,然后读取GATT数据获取,我这里偷懒一下,直接从广播数据包里获取)。
也可以从github类似这个ble项目找到一些相关的资料
https://github.com/custom-components/ble_monitor/tree/master
这里面有非常多的设备类型,可以学习不同的设备的数据包和设备、数据类型结构
运行测试,可以看到,能准确获取到小米温湿度传感器的数据:
更多回帖