How to check if device is connected Pyserial

Asmastas Maz picture Asmastas Maz · Jan 10, 2014 · Viewed 39.5k times · Source

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.

Answer

Gsk picture Gsk · Mar 23, 2018

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