搜索
查看: 1196|回复: 0

[原创] [STM32WB 蓝牙探学] 2 BLE的连接与操作

[复制链接]

该用户从未签到

4

主题

19

帖子

0

蝴蝶豆

中级会员

最后登录
2021-2-17
发表于 2020-5-23 16:48:05 | 显示全部楼层 |阅读模式
0 前言
自己的主要目的是学习BLE相关的知识,以及其具体的应用。因此不会像前一小节那样,组成那么长链路的系统。为最佳的学习BLE,就需要组成最小的闭环回路。

1 最小闭环回路
最小闭环系统,就是STM32WB的开发板和笔记本组成的系统。现在基本的笔记本自带蓝牙。

1

1






2 系统软件环境
在开发板中的软件使用的是:P-NUCLEO-WB55.Nucleo\Applications\BLE\BLE_HeartRate项目工程。
笔记本使用上位机是自己编写的python代码。

2

2


我们将开发板当作外围设备。将笔记本作为中心设备。

3 连接实验
3.1 发现设备
下载好单片机程序,给单片机上电。
在笔记本设置中打开蓝牙,并点击添加蓝牙。

3

3



可以看到我们的设备HRSTM
接下来使用我编写好代码:
import bleak.backends.dotnet.discovery as Discovery
import asyncio
async def run():
    devices = await Discovery.discover()
    for d in devices:
        print(d)
loop = asyncio.get_event_loop()
loop.run_until_complete(run())

在输出窗口可以看到可以被发现了的蓝牙:
B8:7C:6F:47:81:BF: MiKettle
6B:96:A5:AF:06:A7: Apple, Inc. (b'\x10\x05Q\x1c\x82.\xec')
80:E1:26:00:68:7C: HRSTM

我们也可以看到我们的蓝牙应用HRSTM。其中,一个很重要的东西就是设备的ID,这个是我们连接的一个关键,就和电话号码一样,而HRSTM就是持有人的别名。


3.2 连接和发现服务
接下来,我们应用上面的地址,来连接和发现一下HRSTM有哪些服务:
async with BleakClient(address, loop=loop) as client:
    x = await client.is_connected()
    log.info("Connected: {0}".format(x))
        log.info("[Service] {0}: {1}".format(service.uuid, service.description))
        for char in service.characteristics:
            if "read" in char.properties:
                try:
                    value = bytes(await client.read_gatt_char(char.uuid))
                except Exception as e:
                    value = str(e).encode()
            else:
                value = None
log.info(
                "\t[Characteristic] {0}: ({1}) | Name: {2}, Value: {3} ".format(
                    char.uuid, ",".join(char.properties), char.description, value
                )
            )
            for descriptor in char.descriptors:
                value = await client.read_gatt_descriptor(descriptor.handle)
                log.info(
                    "\t\t[Descriptor] {0}: (Handle: {1}) | Value: {2} ".format(
                        descriptor.uuid, descriptor.handle, bytes(value)
                    )
                )

输出的结果:
Connected: True
[Service] 00001801-0000-1000-8000-00805f9b34fb: Generic Attribute Profile
         [Characteristic] 00002a05-0000-1000-8000-00805f9b34fb: (indicate) | Name: , Value: None
                   [Descriptor] 00002902-0000-1000-8000-00805f9b34fb: (Handle: 4) | Value: b'\x02\x00'
[Service] 00001800-0000-1000-8000-00805f9b34fb: Generic Access Profile
         [Characteristic] 00002a00-0000-1000-8000-00805f9b34fb: (read,write-without-response,write,authenticated-signed-writes) | Name: , Value: b'STM32WB'
         [Characteristic] 00002a01-0000-1000-8000-00805f9b34fb: (read,write-without-response,write,authenticated-signed-writes) | Name: , Value: b'@\x03'
         [Characteristic] 00002a04-0000-1000-8000-00805f9b34fb: (read) | Name: , Value: b'\xff\xff\xff\xff\x00\x00\xff\xff'
[Service] 0000180a-0000-1000-8000-00805f9b34fb: Device Information
         [Characteristic] 00002a29-0000-1000-8000-00805f9b34fb: (read) | Name: , Value: b'STM\x00'
[Service] 0000180d-0000-1000-8000-00805f9b34fb: Heart Rate
         [Characteristic] 00002a37-0000-1000-8000-00805f9b34fb: (notify) | Name: , Value: None
                   [Descriptor] 00002902-0000-1000-8000-00805f9b34fb: (Handle: 18) | Value: b'\x00\x00'
         [Characteristic] 00002a38-0000-1000-8000-00805f9b34fb: (read) | Name: , Value: b'\x04'
         [Characteristic] 00002a39-0000-1000-8000-00805f9b34fb: (write) | Name: , Value: None

观察,返回的信息,我们大致可以通过,服务、特性、描述等知道其性能和功能。其中,发现UUID都是单片机中定义好的,在UUID.h 文件目录下:
/* UUIDs for Heart Rate Service */
#define HEART_RATE_SERVICE_UUID                                        (0x180D)
#define CLIENT_CHARACTERISTIC_CONFIG_DESCRIPTOR_UUID                   (0x2902)
#define HEART_RATE_MEASURMENT_UUID                                   (0x2A37)
#define SENSOR_LOCATION_UUID                                           (0x2A38)
#define CONTROL_POINT_UUID                                             (0x2A39)

3.3 通知和获取数据
通过STM的蓝牙软件,发现软件是有数据传递的。

4

4



其采用的方式是通知的方式,我是用了一下程序:

def notification_handler(sender, data):
    # strs=data.hex
    print(f"{sender}: {data}")
    byarray = bytearray(data)
    print(byarray.hex())

async def run(address, loop, debug=False):
    async with BleakClient(address, loop=loop) as client:
        x = await client.is_connected()
        await client.start_notify(CHARACTERISTIC_UUID, notification_handler)
        await asyncio.sleep(5.0, loop=loop)
        await client.stop_notify(CHARACTERISTIC_UUID)
if __name__ == "__main__":
if __name__ == "__main__":
    address = ('80:E1:26:00:68:7C')  #你的地址
    loop = asyncio.get_event_loop()
    loop.run_until_complete(run(address, loop, True))

返回了一下数据:
00002a37-0000-1000-8000-00805f9b34fb: bytearray(b'\x1f7\x00\x14\x00\x00\x04')
1f370014000004
00002a37-0000-1000-8000-00805f9b34fb: bytearray(b'\x1f6\x00\x1e\x00\x00\x04')
1f36001e000004
00002a37-0000-1000-8000-00805f9b34fb: bytearray(b'\x1f4\x00(\x00\x00\x04')
1f340028000004

其中00002a37HEART_RATE_MEASURMENT_UUID ,数据是十六进制的1f36001e000004,其中0x36是心跳,1e是能量消耗,我将能量变化修改为,每次+10,从每次读回的值就可以看到。
HRSAPP_Context.MeasurementvalueChar.EnergyExpended += 10;

4 小结
以上步骤,从发现蓝牙,连接蓝牙,获取蓝牙服务,以及获取数据。其实,实验中还有许多的小问题,比如指示灯的闪烁,为啥STM官方的APP可以直接连接,自己的却不行?
我相信,在后面一步一步的代码解析,就会解释这些现象。





回复

使用道具 举报

您需要登录后才可以回帖 注册/登录

本版积分规则

关闭

站长推荐上一条 /3 下一条

Archiver|手机版|小黑屋|论坛-意法半导体STM32/STM8技术社区

GMT+8, 2024-5-7 23:55 , Processed in 0.181271 second(s), 36 queries .

Powered by Discuz! X3.4

Copyright © 2001-2024, Tencent Cloud.

快速回复 返回顶部 返回列表