【问题标题】:Connecting to a Bluetooth smart/LE weight scale with bluez/bluetoothctl/gatttool使用 bluez/bluetoothctl/gatttool 连接到蓝牙智能/LE 体重秤
【发布时间】:2016-03-20 04:20:15
【问题描述】:

我想做的事:

我想将我的 Raspberry Pi 2 连接到蓝牙智能体重秤 (Medisana BS440) 并接收我的数据。

我所知道的:

只有一个有趣的主服务具有 5 个特征:

 - handle: 0x001a
     -  properties: 0x20 (Indication), char value handle: 0x1b uuid:00008a21-0000-1000-8000-00805f9b34fb
 - handle: 0x001d
     -  properties: 0x20 (Indication), char value handle: 0x1e uuid:00008a22-0000-1000-8000-00805f9b34fb
 - handle: 0x0020
     -  properties: 0x02 (Read-Only),  char value handle: 0x21 uuid:00008a20-00..
 - handle: 0x0022
     -  properties: 0x08 (Write-Only), char value handle: 0x23 uuid:00008a81-00..
 - handle: 0x0024
     -  properties: 0x20 (Indication), char value handle: 0x25 uuid:00008a82-00..

我使用我的 Android 手机的 HCI-Snoop-Developer-Funktion 来查看相应的应用程序如何与我的体重秤通信。

  1. 写入 0200 -> 0x1f(启用指示 0x1d)
  2. 读取 0x21 -> 0x21(值:37fb)
  3. 写入 0200 -> 0x1c(启用指示 0x1a)
  4. 写入 0200 -> 0x26(启用指示 0x24)
  5. write 02a31e2c0b -> 0x23(我在这里不完全理解,但我知道你是否取 02 之后的字节(a3 1e 2c 0b -> 0b 2c 1e a3 -> 这是当前的 Unix 时间戳,但对于年份?1975?)

在第 4 步之后。有第一个指示(句柄 0x25)给我存储的我的个人数据(我的身高、性别、年龄等)

在第 5 步之后。有一些指示(句柄 0x1b 和句柄 0x1e)应该传输我的测量数据。 (此时不分析十六进制值)

我做了什么:

我在我的 raspi (kernel 4.1.13) 上安装了 bluez.5.32,并使用 gatttool 执行了步骤 1 - 5,并且在步骤 5 之前一切正常。我不't get any Indication-messages from handle 0x1b and 0x1e) 在第 5 步之后没有任何反应。

gatttool -t random -b DE:70:4A:XX:XX:XX -I
char-write-cmd 0x1f 0200
char-read-hnd 0x21 (37fb)
char-write-cmd 0x1c 0200
char-write-cmd 0x26 0200
char-write-cmd 0x23 0000000000

(我什至用 unix-timestamp-for 1975 来做这件事.. 没有成功)

数十亿小时后,我在我的 raspi 上运行 bluetoothctl(存在 dbus 问题),我尝试使用 bluetoothctl。我启用了所有指示并将 0000000000 写入 hnd=0x23。切换到处理 0x1a 并且它起作用了!我收到许多应该是我正在搜索的数据的十六进制值。

那么问题出在哪里? 我想将 gatttool 用于我的目的,或者至少我想了解,为什么它不能用 gatttool 解决

当我使用bluetoothctl时,我只能选择并观看一个属性,并且在收到数据后,我的体重秤会自动断开与我的树莓派的连接。因此,当我选择特征 0x1a 时,我看不到特征 0x01d 的指示消息,反之亦然。

当我使用 gatttool 或使用 bluetoothctl 时,我的 Pi 和我的 Scale 之间是否存在其他连接?或者它们与我的体重秤沟通的方式有什么不同?

【问题讨论】:

    标签: bluetooth bluetooth-lowenergy bluez


    【解决方案1】:

    好的.. 我自己解决了这个问题.. 我需要做的就是将 ,,char-write-cmd" 更改为 ,,char-write-req".. 在我的 Android-Hci 的日志文件中-窥探它总是一个写请求。不知道为什么一直没认出来……

    如果有人像我一样对 bluez/bluetoothd/bluetoothctl & dbus 有同样的问题 (要在 bluetoothctl 中使用命令“list-attributes”、“select”、“write”,您必须在实验模式下执行 bluetoothd,例如“bluetoothd -n -E”,但每次我这样做时都会收到一些错误消息,例如“ D-Bus:名称已在使用中”或类似“d'bus setup failed: connection is not allowed to own the service due to security...”(不记得确切的错误消息))

    我做了什么:

    • 使用 ./configure [...] --enable-experimental 安装 bluez(阅读自述文件)

    • sudo nano /etc/dbus-1/system.d/bluetooth.conf

      --> 复制以 >policy user="root"> 开头的整个块,并将其粘贴到该块下方。然后我在两个块之一中将“root”更改为“pi”

    如果有人想知道此量表如何提供测量结果,请查看此链接: A little Game/Quiz: Do you see my values? (Interpreting Hex-Values)

    【讨论】:

    【解决方案2】:

    在测量重量等后,秤似乎可以连接很短的时间我在 bash 脚本中使用了 gatttool 的非交互模式,如下所示:

    gatttool -t random -b F1:37:57:XX:XX:XX --char-write --handle 0x001f -n 0200
    gatttool -t random -b F1:37:57:XX:XX:XX --char-read --handle 0x0021
    gatttool -t random -b F1:37:57:XX:XX:XX --char-write --handle 0x001c -n 0200
    gatttool -t random -b F1:37:57:XX:XX:XX --char-write --handle 0x0026 -n 0200
    gatttool -t random -b F1:37:57:XX:XX:XX --char-write-req --handle 0x0023 -n 0000000000 --listen
    

    信息取自 Pratik Sinha here。 要显示响应,需要明确给出 --listen ,然后接收大约 25 行数据(交替 1b 和 1e 响应)。 感谢您的信息,为我节省了几天的工作时间!

    新年快乐!

    编辑:

    使用 Python 和 pygatt module 可以归结为:

    import pygatt.backends
    from binascii import hexlify
    
    def printIndication(handle, value):
        print('Indication received {} : {}'.format(hex(handle), hexlify(str(value))))
    
    adapter = pygatt.backends.GATTToolBackend()
    adapter.start()
    # wait for someone to step on the scale
    while True:  
        try:
            device = adapter.connect('f1:37:57:xx:xx:xx', 5, 'random')
            break
        except pygatt.exceptions.NotConnectedError:
            print('Waiting...')
    device.subscribe('00008a22-0000-1000-8000-00805f9b34fb', callback = printIndication, indication = True)
    device.subscribe('00008a21-0000-1000-8000-00805f9b34fb', callback = printIndication, indication = True)
    device.subscribe('00008a82-0000-1000-8000-00805f9b34fb', callback = printIndication, indication = True)
    try:
        device.char_write_handle(0x23, [02,00,00,00,00], True)
    except pygatt.exceptions.NotificationTimeout:
        pass
    device.disconnect()
    adapter.stop()
    

    注意事项:

    • 根据我的经验,读取句柄 0x21 毫无用处
    • 写入句柄 0x23 和 02 后跟 unix 时间戳可同步刻度的 RTC
    • 使用多字节修改的 pygatt(拉 34)能够在一个指示中接收多个字节
    • 虽然写入 0x23 不会产生任何通知,但需要等待通知才能接收 0x1b 和 0x1e 指示。收到最后一个指示时,会收到 NotificationTimeout 异常。

    【讨论】:

    • 也只是想添加这些信息,但你的速度更快。我在答案中添加了一个链接(关于 stackoverflow 的另一个问题)。在这篇文章中,我寻求帮助,因为我不知道如何解释 0x1b 和 0x1e 提供的十六进制值。 (后来由我自己解决)可能对你和其他人都很有趣。您是否也使用过 Medisana BS440?
    • 是的,我也使用 BS440,您的其他帖子也有很大帮助!我只是不明白为什么需要等待通知开始接收指示(实际上是您最初遇到的问题)。无论如何..,这行得通。另一件事是,当测量人 x 时,它只会传输该人最近 30 次存储的结果。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-22
    • 1970-01-01
    • 2016-01-04
    • 2013-05-16
    • 2015-06-08
    • 2018-11-27
    • 1970-01-01
    相关资源
    最近更新 更多