如何检查设备是否已连接Pyserial

时间:2014-01-10 17:30:27

标签: python arduino pyserial

我通过USB端口连接我的Arduino并使用PySerial模块向其发送数据。首先,我可以使用以下代码检查设备是否已连接:

try:
    ser = serial.Serial("COM3", 9600)
except serial.serialutil.SerialException:
    print "Arduino not connected"

现在我要做的是定期检查Arduino是否仍然连接到计算机。我尝试了ser.isOpen()但是即使Arduino断开连接也会返回true。我还想知道如何重新连接设备。我的意思是一旦断开设备,程序就无法再向Arduino发送任何数据。

6 个答案:

答案 0 :(得分:5)

您可以设置超时。

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'

答案 1 :(得分:3)

大多数答案提出了两种方法:

  
      
  1. 在代码的某些方面,通过串口发送某种消息以检查您的设备是否还活着
  2.   
  3. 启动一个单独的线程并通过打开通信来持续检查设备是否处于活动状态
  4.   

第一个解决方案的问题是你总是检查连接,但只检查一些特定点:这个解决方案不是很优雅,如果写得不好甚至可能无法正常工作

第二个解决方案解决了第一个解决方案的问题,但引入了一个新问题:在线程循环中检查连接或最差发送消息将导致问题甚至可能中断与其他功能的设备连接。

允许您在不垄断通信的情况下不断检查连接的解决方案涉及读取现有COM:

declare @str varchar(100) = 'kick0my123ass';

with cte as (
    select 1 [id], stuff(@str,PATINDEX('%[0-9]%', @str),1,'') [col]
    union all
    select [id] + 1, stuff([col],PATINDEX('%[0-9]%', [col]),1,'') from cte
    where col like '%[0-9]%'
)
--this will give you number of digits in string
select top 1 id from cte order by id desc

输出:

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)

这样,如果arduino仍然连接,你将检查每0.1秒,当arduino断开或所有其他活动结束时,线程将结束

答案 2 :(得分:1)

例如检测ttyUSB0:

import os

x=os.system("ls /dev/ttyUSB0")

if x==0:
    print "connected"
else:
    print "disconnected"

答案 3 :(得分:1)

不幸的是,我能找到的最好方法是尝试一些沟通,看看它是否失败。一种非常安全的方式是:

try:
   ser.inWaiting()
except:
   print "Lost connection!"

您可能仍希望在连接丢失后关闭与ser.close()的连接,尽管您可能还需要将其放在“try:except”块中。

答案 4 :(得分:0)

我建议使用python线程类来实现串行连接,在运行方法中将你的while循环设置为最后用于kill iy的var,用于存储数据的第二个public var如果在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

答案 5 :(得分:0)

 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()