1

I am trying to read from two serial ports at once. Each connected device spits out a line of data. I read the data from each port as a list and then concatenate the list and print it out as one line.

If I read each port individually, the data updates fine. But the second I attempt to read from both, it lags up and the data stops changing in the print output. The timestamp updates fine, but the data itself is what starts to lag.

Below is my code, should I be doing some sort of threading? I am reading from an Arduino and a Teensy.

import serial
import time

serA = serial.Serial('/dev/arduino', 230400)
serT = serial.Serial('/dev/teensy', 9600)

while 1 :
        timestamp = "%f" % time.time()
        print(timestamp)
        arduino = serA.readline().rstrip('\n')
        data_listA = arduino.split('$')
        teensy = serT.readline().rstrip('\n')
        data_listT = teensy.split('$')       
        data_list = data_listA + data_listT
        print(data_list)
BadProgrammer
  • 89
  • 1
  • 2
  • 12
  • I suspect but am not certain that it is slow because you are reading one serial port at a time and each has to wait for the other to finish before starting. Threading is likely your best option. – James Aug 09 '16 at 23:29
  • Thanks for the feedback! This is my first ever python code. Can you provide a reference for threading? – BadProgrammer Aug 09 '16 at 23:32

2 Answers2

1

just check to see if your serial port has bytes to read before you try to read it ...

while 1 :
    timestamp = "%f" % time.time()
    print(timestamp)
    if serA.inWaiting(): # only read if there is something waiting to be read
        arduino = serA.readline().rstrip('\n')
        data_listA = arduino.split('$')
        print("GOT ARDUINO:",data_listA)
    if serB.inWaiting():
        teensy = serT.readline().rstrip('\n')
        data_listT = teensy.split('$')         
        print("GOT TEENSY:",data_listT)
Joran Beasley
  • 110,522
  • 12
  • 160
  • 179
  • It prints at a really fast rate. Both ports have data at a kHz rate. I don't have the devices on me so I can't try this out right now, but I will try tomorrow morning. Is it possible that bytes aren't available even at that fast of a rate? – BadProgrammer Aug 09 '16 at 23:40
  • Joran's slick solution will print timestamp each time through the loop, even if neither port has data. If you want a "service interval" you would have to nest that all in with a check of whether the current time is more than your chosen interval after the previous time. – beroe Aug 09 '16 at 23:59
1

Using inwaiting() unfortunately did not work for me. I ended up having to use threading. A basic example for people who might encounter my problem is shown below.

import serial
import Queue
import threading

queue = Queue.Queue(1000)

serA = serial.Serial('/dev/arduino', 230400)
serT = serial.Serial('/dev/teensy', 9600)

def serial_read(s):
    while 1:
        line = s.readline()
        queue.put(line)

threadA = threading.Thread(target=serial_read, args=(serA,),).start()
threadT = threading.Thread(target=serial_read, args=(serT,),).start()

while 1:
    line = queue.get(True, 1)
    print line

I based my code on the last answer from this question.

Community
  • 1
  • 1
BadProgrammer
  • 89
  • 1
  • 2
  • 12