线程蓝牙通信树莓派(Python 3)

时间:2021-01-10 01:00:56

标签: python python-3.x multithreading bluetooth raspberry-pi

我的问题是,我如何在我的程序中实现线程,在那里我有与 Rpi3 的通信 BLE。

我的程序运行良好,但响应速度太慢。 请帮忙解决这个问题。谢谢。

BMS_reading:

import gatt
import sys
import time
import threading

class AnyDevice(gatt.Device):

    def write(self, characteristic):
        self.response=bytearray()
        self.bms_write_characteristic.write_value(bytes([0xDD,0xA5,0x03,0x00,0xFF,0xFD,0x77]));

    def services_resolved(self):
        super().services_resolved() 
        device_information_service = next(
            s for s in self.services
            if s.uuid == '0000ff00-0000-1000-8000-00805f9b34fb')

        self.bms_read_characteristic = next(
            c for c in device_information_service.characteristics
            if c.uuid == '0000ff01-0000-1000-8000-00805f9b34fb')
            
        self.bms_write_characteristic = next(
            c for c in device_information_service.characteristics
            if c.uuid == '0000ff02-0000-1000-8000-00805f9b34fb')
            
        self.bms_read_characteristic.enable_notifications()
        self.write(self.bms_read_characteristic)

    def characteristic_value_updated(self, characteristic, value):
        self.value=value
        def write(): 
            self.response+=self.value
            if (self.response.endswith(b'w')):
                self.response=self.response[4:]
                self.SoC=int.from_bytes(self.response[19:20], byteorder = 'big')
                self.manager.stop()
        write()

 
#reading loop (I want add threading and read info "SoC")
while True:
    address="A4:C1:38:A0:59:EB"
    manager = gatt.DeviceManager(adapter_name='hci0')
    device = AnyDevice(mac_address=address, manager=manager)
    device.connect()
    manager.run()
    print("Capacity is: "+str(device.SoC)+"%")

TERMINAL <<< Capacity is: 76% 
#long delay which i dont want
<<< Capacity is: 76% 

我不知道我该怎么做。 当我让线程一直循环时,通信没有时间做出反应并打印错误的数字或错误。

请帮忙。

--------------------已编辑--程序--为--通知------更新-----

import gatt
import json
import sys
#from gi.repository import GLib

manager = gatt.DeviceManager(adapter_name='hci0')
class AnyDevice(gatt.Device):
    def connect_succeeded(self):
        super().connect_succeeded()
        print("[%s] Připojeno" % (self.mac_address))

    def connect_failed(self, error):
        super().connect_failed(error)
        print("[%s] Connection failed: %s" % (self.mac_address, str(error)))

    def disconnect_succeeded(self):
        super().disconnect_succeeded()
        print("[%s] Disconnected" % (self.mac_address))
        self.manager.stop()

    def services_resolved(self):
        super().services_resolved()

        device_information_service = next(
            s for s in self.services
            if s.uuid == '0000ff00-0000-1000-8000-00805f9b34fb')

        self.bms_read_characteristic = next(
            c for c in device_information_service.characteristics
            if c.uuid == '0000ff01-0000-1000-8000-00805f9b34fb')

        self.bms_write_characteristic = next(
            c for c in device_information_service.characteristics
            if c.uuid == '0000ff02-0000-1000-8000-00805f9b34fb')

        print("BMS found")
        self.bms_read_characteristic.enable_notifications()
        

    def characteristic_enable_notifications_succeeded(self, characteristic):
        super().characteristic_enable_notifications_succeeded(characteristic)
        print("BMS request generic data")
        self.response=bytearray()
        self.bms_write_characteristic.write_value(bytes([0xDD,0xA5,0x03,0x00,0xFF,0xFD,0x77]));

    def characteristic_enable_notifications_failed(self, characteristic, error):
        super.characteristic_enable_notifications_failed(characteristic, error)
        print("BMS notification failed:",error)

    def characteristic_value_updated(self, characteristic, value):
        self.response+=value
        if (self.response.endswith(b'w')):
            self.response=self.response[4:]
            temperature= (int.from_bytes(self.response[23+1*2:1*2+25],'big')-2731)/10
            print("Temperature is: "+str(temperature) + " C")
         

    def characteristic_write_value_failed(self, characteristic, error):
        print("BMS write failed:",error)

device = AnyDevice(mac_address="A4:C1:38:A0:59:EB", manager=manager)
device.connect()
manager.run()

终端打印,即使值改变并且管理器正在运行:

>>>BMS found
>>>BMS request generic data
>>>Temperature is: 19 C
#there program get stuck even if value is changing

谢谢,我编辑了带有通知的程序,如您所见,它支持它。

但是我在这里有一个问题,即使值(温度)发生变化并且 manager.run() 中的值(温度)发生变化,即使我加热设备,终端也只会向我发送一个值而不会执行其他任何操作。当我重新启动程序时,值再次改变,只剩下一个。请问我的代码写对了吗?

非常感谢您的时间,先生。

1 个答案:

答案 0 :(得分:0)

我假设您使用的是 gatt-python 库。

manager.run() 开始事件循环,因此您不需要在代码中包含 while 循环。

如果温度特性支持通知,那么 turning them on 将是读取值变化时最有效的方式。

如果设备没有通知,则建议创建定时事件以您需要的频率读取温度。 timeout_add_seconds 的文档并不总是最容易理解,但导入是:

from gi.repository import GLib

然后就在您运行事件循环调用之前:

GLib.timeout_add_seconds(2, my_callback_to_read_temperature)

我希望 gi.repository 已经安装在 RPi 上,但如果您需要安装说明,那么它们位于:https://pygobject.readthedocs.io/en/latest/getting_started.html#ubuntu-getting-started