0
votes

I have a python program that is trying to read 14 bytes from a serial port that are arriving very slowly. I want want to capture all of the bytes in a bytearray[14]. I understand there are new byte array features in python 3.0, but I'm only running python 2.6.6. Upgrading may have unexpected consequences so I have to stick with 2.6.6.

Data only intermittently flows over the serial port. I get one message on the port maybe every 2 minutes or so. This data flows very slowly. The problem I am seeing is that my code does not relaibly read the data one byte at a time. I want to frame this data at exactly 14 bytes, then process the data and start fresh with a new 14 bytes.

Am I taking the wrong approach here? Advice?

    ser = serial.Serial('/dev/ttyUSB1', 1200, timeout=0)
    ser.open()
    print "connected to: " + ser.portstr
    count=0
    while True:
        line =ser.readline(size=14) # should block, not take anything less than 14 bytes
        if line:
            # Here I want to process 14 bytes worth of data and have
            # the data be consistent.
            print "line(" + str(count) + ")=" + line
            count=count+1
    ser.close()

Here's what I'm expecting: line(1)=� 0~ 888.ABC� /ends in carriage return

----------begin output------

line(0)=0
line(1)=~ ??1. ABC �    # here get some multiple bytes and stuff gets out of synch

�ine(2)=
line(3)=0
line(4)=~
line(5)= 
line(6)=8
line(7)=8
line(8)=8
line(9)=.
line(10)= 
line(11)=A
line(12)=B
line(13)=C
line(14)= 
line(15)=�
line(16)=

#...
line(48)=
line(49)=�
line(50)=0
line(51)=~
line(52)= 
line(53)=8
line(54)=8
line(55)=8
line(56)=.
line(57)= 
line(58)=A
line(59)=B
line(60)=C
line(61)= 
line(62)=�
line(63)=

line(64)=

----------end output------

3

3 Answers

4
votes

The API documentation for PySerial says readline() reads until \n, or until size is reached. However, the read() function says it will block until size is reached. Both of these functions say they will return early if a timeout is set.

Possible values for the parameter timeout:

timeout = None: wait forever
timeout = 0: non-blocking mode (return immediately on read)
timeout = x: set timeout to x seconds (float allowed)

Maybe try timeout=None instead of timeout=0

2
votes

Try this:

ser = Serial('/dev/ttyUSB1', 1200, timeout=0)
print "connected to: " + ser.portstr
count=0
while True:
     for line in ser.readlines()   
          print "line(" + str(count) + ")=" + line
          count=count+1

ser.close()   

You might also be interested in the line.strip() function if you haven't used it. Also, emphasis on the s in ser.readlines(), different from .readline().

-1
votes

Change the baudrate.

ser = serial.Serial('/dev/ttyUSB1', 9600, timeout=0)

to a compatible baudrate.

For getting 14 byte data :

data = ser.read(size=14)