你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

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

[复制链接]
ziziran 发布时间:2020-5-23 16:48
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可以直接连接,自己的却不行?
我相信,在后面一步一步的代码解析,就会解释这些现象。





收藏 评论0 发布时间:2020-5-23 16:48

举报

0个回答

所属标签

STM32团队

意法半导体微控制器和微处理器拥有广泛的产品线,包含低成本的8位单片机和基于ARM® Cortex®-M0、M0+、M3、M4、M33、M7及A7内核并具备丰富外设选择的32位微控制器及微处理器


最新内容

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
微信公众号二维码 微信公众号
手机版二维码 手机版