PySerial timeout debugging

How do you determine what made PySerial write a timeout? I am having a problem when PySerial starts throwing exceptions Write timeoutafter starting for variable time. It may work fine for several minutes (approximately 200 bytes / s), and then crash.

All handshakes are disabled.

Before the recording timeout, I noticed that there was no more data to output the TX data. After a few seconds, timeouts will begin. If I turn off writeTimeout, then the code will run continuously, without new data sent to the TX output.

I see in pySerial code that it simply passes the recorded data to the call os.write(). What could lead to it being a reliable timeout? What can lead to a timeout, but not provide any data on the output?


The specific information about my application is below:


I send data through the FTDI adapter to the Arduino board (which emulates some speaker servos). I control the rx / tx lines with a logic analyzer, so I can see what it actually does through the FTDI adapter.

I am running Ubuntu 14.04 in a virtual machine.

Code from Dynamixel Controller node for ROS . I am making small changes to debug the problem.

Recording method, with print requests added for debugging:

def __write_serial(self, data):
    print "TX"

    if self.ser is None:
        print "not open"

    self.ser.flushInput()
    self.ser.flushOutput()
    try:
        n = self.ser.write(data)
        print n
    except Exception as e:
        print e

Reading method:

def __read_response(self, servo_id):
    data = []
    print "RX"

    try:
        data.extend(self.ser.read(4))
        print data
        if not data[0:2] == ['\xff', '\xff']: 
            print "RX ERR1"
            raise Exception('Wrong packet prefix %s' % data[0:2])
        data.extend(self.ser.read(ord(data[3])))
        data = array('B', ''.join(data)).tolist() # [int(b2a_hex(byte), 16) for byte in data]
    except Exception, e:
        print "RX ERR2"
        raise DroppedPacketError('Invalid response received from motor %d. %s' % (servo_id, e))

    # verify checksum
    checksum = 255 - sum(data[2:-1]) % 256
    if not checksum == data[-1]: raise ChecksumError(servo_id, data, checksum)

    return data

And the serial port announcement. All acknowledgment is disabled.

def __init__(self, port, baudrate, readback_echo=False):
    """ Constructor takes serial port and baudrate as arguments. """
    try:
        self.serial_mutex = Lock()
        self.ser = None
        self.ser = serial.Serial(port)
        #self.ser.setTimeout(0.015)
        self.ser.setTimeout(0.05)
        self.ser.baudrate = baudrate
        self.ser.xonxoff = False
        self.ser.rtscts = False
        self.ser.dsrdtr = False
        self.ser.writeTimeout = 1
        self.port_name = port
        self.readback_echo = readback_echo
    except SerialOpenError:
       raise SerialOpenError(port, baudrate)

. - ( , ) TX FTDI . :

TX
8
RX
['\xff', '\xff', '\x15', '\x13']
TX
8
RX
[]
RX ERR1
RX ERR2

self.ser.write(data) 8 ( 8- ) , FTDI .

3 ( 200 /) Write timeout.

TX
Write timeout
RX
[]
RX ERR1
RX ERR2

:

  • /
  • TX FTDI,
  • Write timeout

?

+4
source share

All Articles