Как проверить, подключено ли устройство Pyserial

Я подключаюсь к своему Arduino через порт USB и отправляю на него данные с помощью модуля PySerial. Сначала я могу проверить, подключено ли устройство, используя этот код:

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

Теперь я хочу периодически проверять, подключен ли Arduino к компьютеру. Я пробовал ser.isOpen(), но это возвращает истину, даже если Arduino отключен. Еще хотелось бы узнать, как переподключить устройство. Я имею в виду, что как только вы отключите устройство, программа больше не сможет отправлять данные в Arduino.


person Asmastas Maz    schedule 10.01.2014    source источник


Ответы (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'
person mchant    schedule 10.01.2014

В большинстве ответов предлагается 2 подхода:

  1. В какой-то момент кода отправьте какое-то сообщение через последовательный порт, чтобы проверить, живо ли ваше устройство.
  2. Запустите отдельный поток и постоянно проверяйте, живо ли устройство, открывая сообщение

Проблема с первым решением заключается в том, что вы не всегда проверяете соединение, а проверяете только некоторые конкретные моменты: это решение не очень элегантно и, если оно написано плохо, может даже не работать.

Второе решение решает проблему первого решения, но создает новую проблему: проверка соединения или, в худшем случае, отправка сообщения в поточном цикле вызовет проблему или может даже прервать соединение с устройством из других функций.

Решение, позволяющее постоянно проверять соединение без монополизации коммуникации, предполагает чтение существующего 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 будет отключен или все другие действия завершатся

person Gsk    schedule 23.03.2018

К сожалению, лучший способ, который я могу найти, - это попытаться установить связь и посмотреть, не удастся ли это. Довольно безопасный способ:

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

Вы, вероятно, по-прежнему захотите закрыть соединение с помощью ser.close () после того, как соединение будет потеряно, хотя вам может потребоваться также поместить это в блок «try: except».

person Peter    schedule 26.03.2015

Например, чтобы обнаружить ttyUSB0:

import os

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

if x==0:
    print "connected"
else:
    print "disconnected"
person Muhammad Satrio Pakarti    schedule 22.02.2015
comment
Лучше использовать os.path.exists('/dev/ttyUSB0') - person goetzc; 19.09.2015
comment
os.path.exists действительно лучше. Я провел тесты с Windows (COM3) и Ubuntu (ttyACM0), и все прошло отлично. - person Marcos; 11.03.2019

Я предлагаю использовать класс потока Python для создания последовательного соединения, в методах выполнения поместите цикл while, установите переменную, которую вы используете для kill iy в конце, вторую общедоступную переменную, которую вы используете для хранения данных, если получили и загрузить данные в основной метод .. скоро вставьте пример

   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
person archetipo    schedule 10.01.2014