How to check if device is connected Pyserial

2020-06-04 03:08发布

I am connecting with my Arduino through a USB port and sending data to it by using PySerial module. At first I can check if the device is connected by using this code:

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

Now what I want to do is to check periodically if the Arduino is still connected to the computer. I tried ser.isOpen() but this returns true even if the Arduino is disconnected. I would also like to know how to reconnect the device. I mean once you disconnect the device the program can no longer send any data to Arduino.

6条回答
劫难
2楼-- · 2020-06-04 03:23

Most of the answers propose 2 approaches:

  1. In some point of the code, send some sort of message through serial to check if your device is still alive
  2. Start a separate thread and continuously check if the device is alive by opening a communication

The problem with the first solution is that you are not always checking the connection, but only checking in some specific points: this solution isn't very elegant and if badly written could even be not working.

The second solution solves the problem of the first solution, but introduces a new problem: checking the connection, or worst sending a message, in a threaded loop will cause problem or may even interrupt the connection to the device from other functions.

A solution that allows you to constantly check the connection without monopolizing the communication involves the reading of the existing COM:

import serial.tools.list_ports
myports = [tuple(p) for p in list(serial.tools.list_ports.comports())]
print myports

output:

[(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...')]

then we save the tuple that contains our port:

arduino_port = [port for port in myports if 'COM3' in port ][0]

then we create a function that checks if this port is still present:

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)

At last, we run this function as a daemon thread:

import threading
port_controller = threading.Thread(target=check_presence, args=(arduino_port, 0.1,))
port_controller.setDaemon(True)
port_controller.start()

in this way, you'll check each 0.1 secs if the arduino is still connected, and the thread will end when arduino is disconnected or all other activities have ended

查看更多
别忘想泡老子
3楼-- · 2020-06-04 03:25

i suggest to use a python thread class to istantiate a serial connection, in the run methos put your while loop , set an var that you use for kill iy at the end, the second public var that you use for store data if have receive and load data in main method.. soon paste an example

   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

and start with:

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
查看更多
家丑人穷心不美
4楼-- · 2020-06-04 03:30

For example to detect ttyUSB0:

import os

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

if x==0:
    print "connected"
else:
    print "disconnected"
查看更多
走好不送
5楼-- · 2020-06-04 03:34

You can set a timeout.

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'
查看更多
兄弟一词,经得起流年.
6楼-- · 2020-06-04 03:44
 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()
查看更多
叼着烟拽天下
7楼-- · 2020-06-04 03:45

Unfortunately, the best way I can find to do this is to try some communication and see if it fails. A pretty safe way would be:

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

You'll probably still want to close the connection with a ser.close() after the connection is lost, although you may need to place that in a "try:except" block also.

查看更多
登录 后发表回答