北京合众恒跃科技有限公司
直播中

jf_50393217

5年用户 227经验值
擅长:可编程逻辑 嵌入式技术
私信 关注

【HZ-T536开发板免费体验】4、使用蓝牙模块读取小米温湿度计的数据

虽然设备上没有蓝牙模块,我们依旧可以通过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

这里面有非常多的设备类型,可以学习不同的设备的数据包和设备、数据类型结构

运行测试,可以看到,能准确获取到小米温湿度传感器的数据:
image.png

更多回帖

发帖
×
20
完善资料,
赚取积分