简体   繁体   中英

PySerial handle serial.serialutil.SerialException on send

I have an application where I am trying to get debug messages from a microcontroller that I have on a 5 minutes on/10 seconds off power cycle. The microcontroller is connected via USB and uses the Windows usbser.sys driver to connect as a virtual COM device. When the device disconnects and reconnects, if the application (putty, tera term, or my python app) tries to read data, it gets nothing, and if it tries to write, it receives a timeout error and disconnects.

So if I know I can catch the error (attempting to write), how can I actually close the port and reopen it? If I try a simple ser.close() and ser.open() , it never seems to reconnect.

Below is the special send function that tries to write the data and catch the error.

def send(ser, message):
    if ser.isOpen():
        try:
            ser.write(message)
        except serial.serialutil.SerialException:
            # attempt to reconnect?
            # already tried making new serial object
            # which just fails when trying to open
            # check if reconnected?
        else:
            return True
    else:
        return False

Hopefully someone has had experience with this or has thoughts as to things to try, or perhaps even has some insight into COM port handling and control in Windows

You could try to change DTR signal using functions ser.setDTR(False) and ser.setDTR(True) . May be the link will be useful.

Also, you may use commands like ser.getDTR() to check what's going on with the serial interface.

Just realized I never posted an answer for this. Turns out it was an issue with the USB Virtual COM driver that I was unable to resolve, but I was able to come up with this work around.

Note: This question and answer are Windows platform specific .

Microsoft provides a program called devcon.exe . It's the Windows Device Console, kind of a command line version of Device Manager.

Ultimatlely, once I found that I could remove the device and rescan (without unplugging it, so sort of "virtually" unplugging it), I realized I could make a call to this application to remove the specific device for me and then rescan the device structure if I ever detected a disconnect. So here is the python snippet I used to accomplish this in between dumping the serial data. Probably not the cleanest code ever, but this was only for a quick and dirty logging script. Hopefully this can help some of you experience the same issue.

import serial
from subprocess import call
from time import sleep

def remove(ser):
    try:
        ser.close()
    except:
        print "Could not close port"
    call(["devcon.exe","remove","USB\VID_0D59&PID_0005*"])

def rescan():
    call(["devcon.exe","rescan"])
    sleep(30)

def send(ser, message):
    if ser.isOpen():
        try:
            ser.write(message)
        except serial.serialutil.SerialException:
            remove(ser)
            rescan()
            try:
                ser.open()
            except serial.serialutil.SerialException:
                try:
                    remove(ser)
                    rescan()
                except:
                    print 'Could not reconnect'
                    return False
            else:
                print 'Reconnected to %s' % (ser.portstr)
                ser.write(message)
                return True
        else:
            return True

Important notes: attempting to send data to the port and then recieving the exception was the only way to tell that the device had restarted. No amount of open, closing, or checking connections proved succesful with this driver, so this was the best solution that I could come up with at the time.

Also, note the arbitrary 30 second delay in the rescan() function. This was to allow the computer enough time to recognize the device and find the appropriate drivers. The time varies per system and device.

This code snippet is Python 2

Finally, this is probably obvious, but this solution has devcon.exe in the same directory or in the PATH

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM