Goodday程序员,
我正在研究Raspberry Pi 3B +与多个蓝牙设备之间的连接,目前每个Pi最多5个。我能够建立连接,可以与设备进行所有交互,但是在设备失去连接较长时间后,很难重新连接。请借给我您很大的帮助,并协助我制作防弹脚本,该脚本始终有效地连接设备。
一些信息:
每个设备有3个线程运行,即看门狗,读取和写入。看门狗大约每5秒钟向写队列添加一条伪消息(通过写线程发送到设备),如果它做出反应(使用错误的命令响应),我知道它仍然存在。如果它在30秒钟内没有反应,我知道它已断开连接,我必须尝试重新连接。我有一个指示connectionstatus(connectionAlive)的变量,可以是0、1或2。0是不活动的,1是重新连接的,2是连接的。仅当connectionAlive> 0时,读和写线程才处于活动状态。 问题在于,当设备通过待机或关闭为电池充电而失去连接时。读写线程非常简单,因此我认为重新连接的算法就是问题所在。我在下面添加了看门狗代码:
def Watchdog(self):
logging.info('Start watchdog thread for: {}'.format(self.tool_id))
while(True):
if self.connectionAlive == 0:
self.ChangeAlive(1)
time.sleep(0.2)
if self.wq.qsize() < 3:
self.wq.put(['ping', ''])
time.sleep(0.5)
#if last alive longer than 20 ticks
if (time.time() - self.last_alive) > 30: #or self.errorQ.qsize() > 0
last_tick = time.time() - self.last_alive
#if it was alive, tell thread its dead.
if self.connectionAlive == 2 and self.com != False:
logging.error('Tool {} is taking longer to respond'.format(self.tool_id))
self.ChangeAlive(0)
if self.com != False:
try:
self.com.close()
time.sleep(0.1)
except:
#com wasnt alive (never connected since thread started)
pass
self.connectionTryCount += 1
try:
self.com = serial.Serial(port=self.comport, baudrate=9600, timeout=5, write_timeout=5)
#time.sleep(3)
except:
if self.connectionTryCount < 2:
logging.error('Tool {} is unable to connect!'.format(self.tool_id)) #com port not available
#time.sleep(5)
else:
if self.connectionTryCount > 0:
logging.info('Tool {} connected after {} tries'.format(self.tool_id, self.connectionTryCount))
self.connectionTryCount = 0
if self.connectionAlive != 2:
self.ChangeAlive(2)
while self.errorQ.qsize() > 0:
self.errorQ.get()
time.sleep(0.05)
time.sleep(4)
我认为线程休眠存在问题,并且以某种方式使连接窗口和读取“活动”消息的窗口过小而无法保持连接,结果导致断开连接的速度过快而无法尝试重新连接。读线程的睡眠为0.1,写线程的睡眠为0.05。
编辑:蓝牙设备已连接至需要向其发送参数的测量设备。在蓝牙部分仍处于连接状态时,测量设备可以处于待机状态,但这意味着该设备尚未运行并且尚未准备好接收参数,该设备没有内置队列。
我的脚本编写不佳还是从一开始就注定要使用PySerial或Pi?
任何意见或建议都将不胜感激!
答案 0 :(得分:0)
rfcomm是BlueZ开发人员的8 tools that has been deprecated之一,因此我建议您不要在rc.local中使用rfcomm。
在Linux上,可以使用标准Python套接字库建立蓝牙串行连接,如本博客中所述:http://blog.kevindoran.co/bluetooth-programming-with-python-3/
Bluedot library中还有一些功能可能会有所帮助。除了文档外,还有一些examples。
根据脚本的作用,您可能需要考虑使用systemd在启动时运行程序。我发现以下博客是有用的参考:https://blog.usedbytes.com/2019/11/run-at-startup-without-rc.local/