如何检查设备是不是已连接 Pyserial
Posted
技术标签:
【中文标题】如何检查设备是不是已连接 Pyserial【英文标题】:How to check if device is connected Pyserial如何检查设备是否已连接 Pyserial 【发布时间】:2014-01-10 17:30:26 【问题描述】:我通过 USB 端口与我的 Arduino 连接,并使用 PySerial 模块向其发送数据。首先,我可以使用以下代码检查设备是否已连接:
try:
ser = serial.Serial("COM3", 9600)
except serial.serialutil.SerialException:
print "Arduino not connected"
现在我要做的是定期检查 Arduino 是否仍连接到计算机。我尝试了ser.isOpen()
,但即使 Arduino 断开连接,它也会返回 true。我也想知道如何重新连接设备。我的意思是一旦你断开设备,程序就不能再向 Arduino 发送任何数据。
【问题讨论】:
【参考方案1】:大多数答案都提出了两种方法:
在代码的某个位置,通过串口发送某种消息以检查您的设备是否仍然存在 启动一个单独的线程,并通过打开一个通信不断检查设备是否处于活动状态
第一个解决方案的问题是您不总是检查连接,而只是检查一些特定点:这个解决方案不是很优雅,如果写得不好甚至可能无法正常工作.
第二种解决方案解决了第一种解决方案的问题,但引入了一个新问题:在线程循环中检查连接,或者最糟糕的是发送消息会导致问题,甚至可能会中断其他功能与设备的连接。
一种允许您在不垄断通信的情况下不断检查连接的解决方案涉及读取现有 COM:
import serial.tools.list_ports
myports = [tuple(p) for p in list(serial.tools.list_ports.comports())]
print myports
输出:
[(u'COM3', u'Arduino Due Programming Port (COM3)', u'some more data...'),
(u'COM6', u'USB Serial Port (COM6)', u'some more data...'),
(u'COM100', u'com0com - serial port emulator (COM100)', u'some more data...')]
然后我们保存包含我们端口的元组:
arduino_port = [port for port in myports if 'COM3' in port ][0]
然后我们创建一个函数来检查这个端口是否仍然存在:
import time
def check_presence(correct_port, interval=0.1):
while True:
myports = [tuple(p) for p in list(serial.tools.list_ports.comports())]
if arduino_port not in myports:
print "Arduino has been disconnected!"
break
time.sleep(interval)
最后,我们将这个函数作为一个守护线程运行:
import threading
port_controller = threading.Thread(target=check_presence, args=(arduino_port, 0.1,))
port_controller.setDaemon(True)
port_controller.start()
这样,您将每 0.1 秒检查一次 arduino 是否仍然连接,当 arduino 断开连接或所有其他活动都结束时,线程将结束
【讨论】:
@JonnyHenly 是的!您发现了复制粘贴错误!已修复,谢谢【参考方案2】:您可以设置超时。
import serial
ser = serial
try:
ser = serial.Serial("COM3", 9600, timeout=10)
while ser.read():
print 'serial open'
print 'serial closed'
ser.close()
except serial.serialutil.SerialException:
print 'exception'
【讨论】:
【参考方案3】:不幸的是,我能找到的最好的方法是尝试一些沟通,看看是否失败。一个相当安全的方法是:
try:
ser.inWaiting()
except:
print "Lost connection!"
在连接丢失后,您可能仍希望使用 ser.close() 关闭连接,尽管您可能还需要将其放在“try:except”块中。
【讨论】:
【参考方案4】:例如检测ttyUSB0:
import os
x=os.system("ls /dev/ttyUSB0")
if x==0:
print "connected"
else:
print "disconnected"
【讨论】:
更好用os.path.exists('/dev/ttyUSB0')
os.path.exists 确实更好。我用 windows(COM3) 和 Ubuntu(ttyACM0) 进行了测试,它运行起来就像一个魅力。【参考方案5】:
import serial
import time
ser = serial.Serial()
ser.braudrate = 115200
ser.port = "/dev/ttyUSB0"
ser.open()
print(ser.name)
if ser.isOpen():
print("serial is open!")
ser.close()
【讨论】:
【参考方案6】:我建议使用python线程类来建立串行连接,在运行方法中放置你的while循环,最后设置一个用于kill iy的var,第二个用于存储数据的公共var if在 main 方法中接收和加载数据.. 很快粘贴一个例子
class Arduino():
def __init__(self,Port='/dev/ttyUSB0',Boud=9600,connState=0):
self.parent=self
self.port=Port
self.boud=Boud
self.connState=connState
self.timeount=1
self.ser=None
self.connect()
def connect(self):
try:
self.ser=serial.Serial(self.port,self.boud,timeout=0.0001)
self.connState=1
return [1,'connect']
except:
self.connState=0
return [0,'no hardware found']
def loadData(self):
self.buffer=self.ser.read(1)
if (self.buffer!=''):
try:
print self.buffer
except Exception, e:
pass
ard=Arduino()
while True:
if ard.connState:
ard.loadData()
else:
print "Arduino not found"
break
然后开始:
import threading
class ThController( threading.Thread ):
# Override Thread's __init__ method to accept the parameters needed:
def __init__( self,parent):
self.parent = parent
threading.Thread.__init__ ( self )
def run ( self ):
while self.parent.ctrlattive:
j=json.loads(data)
self.parent.data=j
【讨论】:
以上是关于如何检查设备是不是已连接 Pyserial的主要内容,如果未能解决你的问题,请参考以下文章