Menu

#52 Serial port read returns nothing

open
nobody
None
5
2014-09-29
2011-12-26
larytet
No

Hey,

I have code which opens, reads and writes serial device. In my case this is dual port USB-RS232 FTDI (0x0403, 0x6010)
I disconnect the cable (pull it out) and restart the script. I plug the cable back in. I can not read the device. Call read(3) returns empty strings and probably timeouts.

After some playing with libusb itself including call to detackKernelModule I have discovered a workaround "rmmod ftdi_sio;rmmod usbserial". Is there any way to reset/bring down the device/USB bus directly from Python?

Thank you.

Discussion

  • larytet

    larytet - 2011-12-27

    Another workaround is to connect minicom to the port, get out of the minicom, start the script. Minicom somehow restarts the interface (without sudo so it can not be rmmod).

     
  • larytet

    larytet - 2011-12-28

    The trick minicom does is open the port at rate 0, close the port and reopen it at the correct rate. Here is Python

    # I am going to set the I/O speed to zero for one second and after that restore
    # the configured speed. This is the trick minicom does
    def __reset_tty(self, tty):
    try:
    isOpen = tty.isOpen();
    rateOrig = tty.getBaudrate();
    if (isOpen): # if open close first - I can not (?) set rate for the opened I/O in Python
    tty.close();

    tty.setBaudrate(0)
    tty.open();
    time.sleep(0.4); # minicom waits 1s
    tty.close();

    tty.setBaudrate(rateOrig) # i am going to leave the serial in the original rate and state
    if (isOpen):
    tty.open();
    except Exception:
    print "Failed to toggle baud rate for the I/O"

     
  • Chris Liechti

    Chris Liechti - 2011-12-28

    1) I think I've also experienced problems with multiple FTDI devices, reopening and older kernels (around 2.6.18). maybe a newer Kernel fixes this.

    2) an other issue is plugging out a device that is currently open. the kernel keeps the tty device unless it is closed. older pySerial versions kept looping in the read function. this situation should be improved in pySerial 2.6

    in case of 2) the device gets a new tty assigned when plugged in again while the old one is still in use. to avoid that, the port has to be closed before the device is plugged in.

    3) I've also seen that some CDC/ACM devices cause problems (I/O error on open) if the device sends data as soon as it is plugged in (before the port is opened). a workaround there, is to not send data unless the PC sends a command (if you have the software of the device under control...)

     
  • Chris Liechti

    Chris Liechti - 2011-12-28
    • status: open --> pending
     
  • larytet

    larytet - 2012-01-12
    • status: pending --> open
     
  • larytet

    larytet - 2012-01-12

    There is another problem with hot plug out at least in Linux.

    I have a login in the script which discovers that the serial device is not connected anymore - no response from the device. It happens, when device goes power down. At this point I call to close() for the TTY. Periodically (~0.5s) I try to open() the device. Linux always choose another TTY device.

    Yet another problem is that after lot of close/open cycles (~2K cycles) open() always fails even if TTY device exists and working. Restart of the script solves the problem. Does python run out of file descriptors?

     
  • larytet

    larytet - 2012-01-15

    This is an exception I get after multiple open/close cycles:

    File "/usr/lib/python2.6/dist-packages/serial/serialutil.py", line 166, in __init__
    File "/usr/lib/python2.6/dist-packages/serial/serialposix.py", line 175, in open
    SerialException: could not open port /dev/ttyUSB0: [Errno 24] Too many open files: '/dev/ttyUSB0'

     

Log in to post a comment.