Browse Source

Works with multiple devices now.

Plug in a lot of devices and try: "./terminal.py /dev/ttyUSB*"
tags/v1.0
Jim Paris 11 years ago
parent
commit
2065c9ad12
1 changed files with 53 additions and 20 deletions
  1. +53
    -20
      terminal.py

+ 53
- 20
terminal.py View File

@@ -34,7 +34,7 @@ class Color(object):
self.reset = colorama.Style.RESET_ALL self.reset = colorama.Style.RESET_ALL
def code(self, n): def code(self, n):
return self.codes[n % self.total] return self.codes[n % self.total]
color = Color()
g_color = Color()


if os.name == 'nt': if os.name == 'nt':
import msvcrt import msvcrt
@@ -90,19 +90,30 @@ else:
class Miniterm: class Miniterm:
"""Normal interactive terminal""" """Normal interactive terminal"""


def __init__(self, serial, suppress_bytes = None):
self.serial = serial
def __init__(self, serials, suppress_bytes = None):
self.serials = serials
self.suppress_bytes = suppress_bytes or "" self.suppress_bytes = suppress_bytes or ""
self.last_color = ""
self.threads = [] self.threads = []


def start(self): def start(self):
self.alive = True self.alive = True
# serial->console
self.threads.append(threading.Thread(target=self.reader))
# console->serial

# serial->console, all devices
for (n, serial) in enumerate(self.serials):
self.threads.append(threading.Thread(
target = self.reader,
args = (serial, g_color.code(n))
))

# console->serial, just the first device
self.console = Console() self.console = Console()
self.threads.append(threading.Thread(target=self.writer))
# start them
self.threads.append(threading.Thread(
target = self.writer,
args = (self.serials[0],)
))

# start all threads
for thread in self.threads: for thread in self.threads:
thread.daemon = True thread.daemon = True
thread.start() thread.start()
@@ -115,13 +126,16 @@ class Miniterm:
while thread.isAlive(): while thread.isAlive():
thread.join(0.1) thread.join(0.1)


def reader(self):
def reader(self, serial, color):
"""loop and copy serial->console""" """loop and copy serial->console"""
try: try:
while self.alive: while self.alive:
data = self.serial.read(1)
data = serial.read(1)
if not data: if not data:
continue continue
if color != self.last_color:
self.last_color = color
sys.stdout.write(color)
if ((ord(data) >= 32 and ord(data) < 128) or if ((ord(data) >= 32 and ord(data) < 128) or
data == '\r' or data == '\n' or data == '\t'): data == '\r' or data == '\n' or data == '\t'):
sys.stdout.write(data) sys.stdout.write(data)
@@ -133,7 +147,7 @@ class Miniterm:
self.console.cleanup() self.console.cleanup()
os._exit(1) os._exit(1)


def writer(self):
def writer(self, serial):
"""loop and copy console->serial until ^C""" """loop and copy console->serial until ^C"""
try: try:
while self.alive: while self.alive:
@@ -157,20 +171,32 @@ class Miniterm:
# Don't send these bytes # Don't send these bytes
continue continue
else: else:
self.serial.write(c) # send character
serial.write(c) # send character
except Exception as e: except Exception as e:
traceback.print_exc() traceback.print_exc()
self.console.cleanup() self.console.cleanup()
os._exit(1) os._exit(1)


def run(self): def run(self):
saved_timeout = self.serial.timeout
self.serial.timeout = 0.1
# Set all serial port timeouts to 0.1 sec
saved_timeouts = []
for (n, serial) in enumerate(self.serials):
saved_timeouts.append(serial.timeout)
serial.timeout = 0.1

# Handle SIGINT gracefully
signal.signal(signal.SIGINT, lambda *args: self.stop()) signal.signal(signal.SIGINT, lambda *args: self.stop())

# Go
self.start() self.start()
self.join() self.join()

# Restore serial port timeouts
for (n, serial) in enumerate(self.serials):
serial.timeout = saved_timeouts[n]

# Cleanup
print "" print ""
self.serial.timeout = saved_timeout
self.console.cleanup() self.console.cleanup()


if __name__ == "__main__": if __name__ == "__main__":
@@ -195,7 +221,8 @@ if __name__ == "__main__":
args = parser.parse_args() args = parser.parse_args()


devs = [] devs = []
color.setup(len(args.device))
used_nodes = []
g_color.setup(len(args.device))
for (n, device) in enumerate(args.device): for (n, device) in enumerate(args.device):
m = re.search(r"^(.*)@([1-9][0-9]*)$", device) m = re.search(r"^(.*)@([1-9][0-9]*)$", device)
if m is not None: if m is not None:
@@ -204,18 +231,24 @@ if __name__ == "__main__":
else: else:
node = device node = device
baud = args.baudrate baud = args.baudrate
if node in used_nodes:
sys.stderr.write("error: %s already open!\n" % node)
raise SystemExit(1)
try: try:
dev = serial.Serial(node, baud) dev = serial.Serial(node, baud)
except serial.serialutil.SerialException: except serial.serialutil.SerialException:
sys.stderr.write("error opening %s\n" % node) sys.stderr.write("error opening %s\n" % node)
raise SystemExit(1) raise SystemExit(1)
if not args.quiet: if not args.quiet:
print color.code(n) + node + ", " + str(args.baudrate) + " baud"
print (g_color.code(n)
+ node + ", " + str(args.baudrate) + " baud"
+ g_color.reset)
used_nodes.append(node)
devs.append(dev) devs.append(dev)


if not args.quiet: if not args.quiet:
print color.reset + "^C to exit"
print color.reset + "----------"
term = Miniterm(dev)
print "^C to exit"
print "----------"
term = Miniterm(devs)
term.run() term.run()



Loading…
Cancel
Save