无法通过蓝牙阅读心率服务

发布于 2025-02-05 05:15:33 字数 278 浏览 1 评论 0 原文

我希望创建一个简单的Python脚本,该脚本通过蓝牙读取极地传感器的心率数据。我已经阅读了许多其他帖子,找不到能够成功执行的简单的东西。

我有Polar可穿戴设备的设备MAC地址。我知道要阅读的值(HR 0x180D)的服务。我不太在乎我使用哪个库或服务,但我似乎无法正常工作。

我能够成功地识别极性传感器,但是,我无法弄清楚如何从中读取价值。我已经为手机下载了一个蓝牙扫描仪应用程序,该应用程序能够成功地连接和读取该值,因此我知道它应该很容易做到,并且无法弄清楚如何编写它。

任何帮助都将不胜感激。

I am looking to create a simple python script that reads heart rate data from a Polar sensor over Bluetooth. I have read through a lot of other posts and cannot find something simple that I am able to successfully execute.

I have the device MAC address for the Polar wearable. I know the service UUID for the value I want to read (0x180D for HR). I don't care much about which library or service I use, but I cannot seem to get this to work.

I am able to have my script successfully recognize the Polar sensor, however, I cannot figure out how to read the value from this. I have downloaded a Bluetooth Scanner app for my phone which is able to successfully connect and read the value, so I know it should be easy to do and cannot figure out how to write this up.

Any help would be tremendously appreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

本王不退位尔等都是臣 2025-02-12 05:15:37

如果您查看 bluetooth分配了16位UUIDS号码那么您是正确的 0x180d 是心率服务

”在此处输入图像描述

它将是心率测量特性 0x2A37 它将具有您正在寻找的值:

我没有对此进行测试的设备,也不知道您正在编写代码的平台。

结果,我使用了黯淡的库库是最跨平台库。

该示例还订阅了设备的通知,而不是读取值。这是获取定期更新值的更典型方法。

import asyncio
import bitstruct
import struct

from bleak import BleakClient


HR_MEAS = "00002A37-0000-1000-8000-00805F9B34FB"


async def run(address, debug=False):

    async with BleakClient(address) as client:
        connected = await client.is_connected()
        print("Connected: {0}".format(connected))

        def hr_val_handler(sender, data):
            """Simple notification handler for Heart Rate Measurement."""
            print("HR Measurement raw = {0}: {1}".format(sender, data))
            (rr_int,
             nrg_expnd,
             snsr_cntct_spprtd,
             snsr_detect,
             hr_fmt,
             ) = bitstruct.unpack("p3b1b1b1b1b1<", data)
            if hr_fmt:
                hr_val, = struct.unpack_from("<H", data, 1)
            else:
                hr_val, = struct.unpack_from("<B", data, 1)
            print(f"HR Value: {hr_val}")

        await client.start_notify(HR_MEAS, hr_val_handler)

        while await client.is_connected():
            await asyncio.sleep(1)


if __name__ == "__main__":
    address = ("xx:xx:xx:xx:xx:xx")  # Change to address of device
    loop = asyncio.get_event_loop()
    loop.run_until_complete(run(address))

您可以阅读有关心率度量值的更多信息:

https ://www.bluetooth.com/specifications/specs/gatt-specification-supplement-6/

If you look at the Bluetooth assigned 16-bit UUIDs numbers then you are correct that 0x180D is the Heart Rate service

enter image description here

It will be the Heart Rate Measurement Characteristic 0x2A37 that will have the values you are seeking:

enter image description here

I don't have a device to test this with and I don't know what platform you are writing the code for.

As a result I've used the bleak library as that is the most cross platform library.

The example also subscribes to notifications from the device rather than reads the value. This is a more typical way to get values that are regularly updating.

import asyncio
import bitstruct
import struct

from bleak import BleakClient


HR_MEAS = "00002A37-0000-1000-8000-00805F9B34FB"


async def run(address, debug=False):

    async with BleakClient(address) as client:
        connected = await client.is_connected()
        print("Connected: {0}".format(connected))

        def hr_val_handler(sender, data):
            """Simple notification handler for Heart Rate Measurement."""
            print("HR Measurement raw = {0}: {1}".format(sender, data))
            (rr_int,
             nrg_expnd,
             snsr_cntct_spprtd,
             snsr_detect,
             hr_fmt,
             ) = bitstruct.unpack("p3b1b1b1b1b1<", data)
            if hr_fmt:
                hr_val, = struct.unpack_from("<H", data, 1)
            else:
                hr_val, = struct.unpack_from("<B", data, 1)
            print(f"HR Value: {hr_val}")

        await client.start_notify(HR_MEAS, hr_val_handler)

        while await client.is_connected():
            await asyncio.sleep(1)


if __name__ == "__main__":
    address = ("xx:xx:xx:xx:xx:xx")  # Change to address of device
    loop = asyncio.get_event_loop()
    loop.run_until_complete(run(address))

You can read more about the Heart Rate Measure value is constructed in:

https://www.bluetooth.com/specifications/specs/gatt-specification-supplement-6/

鸠魁 2025-02-12 05:15:37

尽管@ukbaz的代码示例很有用,并且会在某些情况下不小心显示正确的广播人力资源,但解开5个位标志的部分是完全错误的(以错误的位顺序和3位移动)。当我还试图解码其他数据(例如RR间隔)时,我发现了这个问题,其标志总是错误的。

要纠正标志,请像我在下面完成的那样更改bitsstruct.unpack()行。然后,校正的代码是:

import asyncio
import bitstruct
import struct
from bleak import BleakClient

HR_MEAS = "00002A37-0000-1000-8000-00805F9B34FB"

async def run(address):

    async with BleakClient(address) as client:
        connected = await client.is_connected()
        print("Connected: {0}".format(connected))

        def hr_val_handler(sender, data):
            """Simple notification handler for Heart Rate Measurement."""
            (unused, rr_int, nrg_expnd, snsr_cntct_spprtd, snsr_detect, hr_fmt) \
                = bitstruct.unpack("b3b1b1b1b1b1", data)
            if hr_fmt:
                hr_val, = struct.unpack_from("<H", data, 1)  # uint16
            else:
                hr_val, = struct.unpack_from("<B", data, 1)  # uint8
            print("HR: {0:3} bpm. Complete raw data: {1} ".format(hr_val, data.hex(sep=':')))

        await client.start_notify(HR_MEAS, hr_val_handler)

        while await client.is_connected():
            await asyncio.sleep(1)


if __name__ == "__main__":
    address = ("xx:xx:xx:xx:xx:xx")  # Change to address of device
    loop = asyncio.get_event_loop()
    loop.run_until_complete(run(address))

Although the code example from @ukBaz is useful and will accidentally show the correct broadcast HR in some cases, the part that unpacks the 5 bit flags is completely wrong (in wrong bit order and shifted by 3 bits). I discovered the problem when I was also trying to decode the other data such as R-R intervals and its flag was always wrong.

To correct the flags, change the bitstruct.unpack() lines as I've done below. The corrected code then is:

import asyncio
import bitstruct
import struct
from bleak import BleakClient

HR_MEAS = "00002A37-0000-1000-8000-00805F9B34FB"

async def run(address):

    async with BleakClient(address) as client:
        connected = await client.is_connected()
        print("Connected: {0}".format(connected))

        def hr_val_handler(sender, data):
            """Simple notification handler for Heart Rate Measurement."""
            (unused, rr_int, nrg_expnd, snsr_cntct_spprtd, snsr_detect, hr_fmt) \
                = bitstruct.unpack("b3b1b1b1b1b1", data)
            if hr_fmt:
                hr_val, = struct.unpack_from("<H", data, 1)  # uint16
            else:
                hr_val, = struct.unpack_from("<B", data, 1)  # uint8
            print("HR: {0:3} bpm. Complete raw data: {1} ".format(hr_val, data.hex(sep=':')))

        await client.start_notify(HR_MEAS, hr_val_handler)

        while await client.is_connected():
            await asyncio.sleep(1)


if __name__ == "__main__":
    address = ("xx:xx:xx:xx:xx:xx")  # Change to address of device
    loop = asyncio.get_event_loop()
    loop.run_until_complete(run(address))
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文