import PyQt5.Qt as qt import argparse import serial import time import os class MainWindow(qt.QMainWindow): def __init__(self, baud, port=None): ''' Initialize UI. baud (int) -- serial baud rate port (str|None) -- serial port str name; if None, will try to auto-find ''' super().__init__() self.init_serial(baud, port) self.setupUi() self.timer = qt.QTimer() self.timer.timeout.connect(self.read_serial) self.timer.start(10); def setupUi(self): self.center_widget = qt.QWidget(parent=self) self.edit_input = qt.QLineEdit() self.edit_input.returnPressed.connect(self.write_serial) self.edit_output = qt.QTextEdit() layout = qt.QVBoxLayout() layout.addWidget(self.edit_input) layout.addWidget(self.edit_output) self.center_widget.setLayout(layout) self.setCentralWidget(self.center_widget) self.status_bar = qt.QStatusBar() self.setStatusBar(self.status_bar) self.setFixedWidth(500) self.setGeometry(700, 200, 800, 600) def init_serial(self, baud, port=None): ''' Attempt to create a PySerial connection. Port is either argparsed or the auto-find get_port() result Baud is argparse mandatory ''' try: port = port or self.get_serial_port() self.serial = serial.Serial(port, baud, timeout=0.1) except Exception as e: print("Unable to initiate serial monitoring at '{}'".format(port)) time.sleep(0.1) print(self.serial) def get_serial_port(self): try: print('Trying to find ttyUSB|ttyACM port automatically..') ports = [x for x in os.listdir("/dev") if x.startswith("ttyUSB") or x.startswith("ttyACM")] if ports: print('Got: {}'.format(' | '.join(ports))) return '/dev/' + ports[0] else: raise Exception except Exception as e: print("Error: Unable to find a ttyUSB/ttyACM serial port") raise SystemExit(1) def read_serial(self): if self.serial.in_waiting: raw = self.serial.readall() print(raw) self.edit_output.append(raw.decode('ASCII')[:-2]) def write_serial(self): self.serial.write(bytes(self.edit_input.text(), encoding='UTF-8')) self.edit_input.clear() def keyPressEvent(self, event): if event.key() == qt.Qt.Key_Escape: self.close() @classmethod def run(cls, baud, port=None): app = qt.QApplication([]) window = cls(baud, port) window.show() app.exec_() if __name__ == '__main__': parser = argparse.ArgumentParser( description='''\ Utility for monitoring serial port in a Arduino IDE like manner''') parser.add_argument('-p', '--port') parser.add_argument('-b', '--baud', required=True) args = vars(parser.parse_args()) MainWindow.run(**args)