Skip to content

Instantly share code, notes, and snippets.

@RoganDawes
Created March 3, 2016 15:50
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 6 You must be signed in to fork a gist
  • Save RoganDawes/1042a316a9d320d5e2ff to your computer and use it in GitHub Desktop.
Save RoganDawes/1042a316a9d320d5e2ff to your computer and use it in GitHub Desktop.
Simple python script to read two serial ports at the same time. Good for snooping on bidirectional comms!
#!/usr/bin/python3
import serial, time, sys, threading
from colorama import Fore, Style, init as colorama_init
colorama_init()
# lock to serialize console output
lock = threading.Lock()
class Highlight:
def __init__(self, clazz, color):
self.color = color
self.clazz = clazz
def __enter__(self):
print(self.color, end="")
def __exit__(self, type, value, traceback):
if self.clazz == Fore:
print(Fore.RESET, end="")
else:
assert self.clazz == Style
print(Style.RESET_ALL, end="")
sys.stdout.flush()
if len(sys.argv) != 3 and len(sys.argv) != 4:
sys.stderr.write("Usage: %s <baud> <port1> [<port2>]\n" % (sys.argv[0]))
exit(1)
def read_serial(port, baud, color):
ser = serial.Serial()
ser.port = port
ser.baudrate = baud
ser.bytesize = serial.EIGHTBITS #number of bits per bytes
ser.parity = serial.PARITY_NONE #set parity check: no parity
ser.stopbits = serial.STOPBITS_ONE #number of stop bits
#ser.timeout = None #block read
ser.timeout = 0 # non blocking read
ser.xonxoff = False #disable software flow control
ser.rtscts = False #disable hardware (RTS/CTS) flow control
ser.dsrdtr = False #disable hardware (DSR/DTR) flow control
ser.writeTimeout = 2 #timeout for write
try:
ser.open()
except Exception as e:
print("error open serial port: " + str(e))
exit()
if ser.isOpen():
try:
while True:
c = ser.read(size=1024)
with lock:
if len(c) > 0:
print(color)
sys.stdout.buffer.write(c)
ser.close()
except Exception as e1:
print ("error communicating...: " + str(e1))
else:
print("cannot open serial port ")
exit()
# Create two threads as follows
try:
t = threading.Thread(target=read_serial, args=(sys.argv[2], sys.argv[1], Fore.GREEN ))
t.daemon = True # thread dies when main thread (only non-daemon thread) exits.
t.start()
if len(sys.argv) == 4:
t = threading.Thread(target=read_serial, args=(sys.argv[3], sys.argv[1], Fore.RED ))
t.daemon = True # thread dies when main thread (only non-daemon thread) exits.
t.start()
except:
print("Error: unable to start thread")
try:
while True:
pass
except KeyboardInterrupt:
exit()
@meduag
Copy link

meduag commented Jun 5, 2018

Muito obrigado, thanks

@rahul8989
Copy link

when I run this code on spyder IDE . i got this error:

runfile('C:/Users/iit/readserial.py', wdir='C:/Users/iit')
Usage: C:/Users/iit/readserial.py []
Error: unable to start thread

@haniefGit
Copy link

haniefGit commented Jan 18, 2022

line 26 give me error
this line give me error, how to solve thaT?
I want to read COM11, COM15, COM16, COM17 ..

@RoganDawes
Copy link
Author

The script is very simple. It is designed to support reading from either one or two serial ports, no more. If you want to read from 4 different ports at the same time, you would need to duplicate these lines (https://gist.github.com/RoganDawes/1042a316a9d320d5e2ff#file-read_serial-py-L74-L77), incrementing the sys.argv argument, and perhaps choosing a different colour.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment