#!/usr/bin/env python3 # Serial monitor for ESP32. Optionally pulses RTS/DTR to reset the device # so we capture boot output. Prefixes each line with elapsed seconds. import serial, sys, time, argparse def main(): ap = argparse.ArgumentParser() ap.add_argument("--port", default="/dev/ttyUSB0") ap.add_argument("--baud", type=int, default=115200) ap.add_argument("--seconds", type=int, default=20) ap.add_argument("--reset", action="store_true", help="Pulse RTS/DTR to reset the ESP32 before reading") ap.add_argument("--timestamp", action="store_true", help="Prefix each line with elapsed seconds since boot") args = ap.parse_args() try: s = serial.Serial(args.port, args.baud, timeout=0.2, rtscts=False, dsrdtr=False) except Exception as e: print(f"[open-fail] {e}", flush=True) sys.exit(2) if args.reset: s.setDTR(False) s.setRTS(True) time.sleep(0.1) s.setRTS(False) s.reset_input_buffer() t0 = time.time() end = t0 + args.seconds buf = b"" while time.time() < end: chunk = s.read(512) if chunk: buf += chunk while b"\n" in buf: line, buf = buf.split(b"\n", 1) text = line.decode("utf-8", errors="replace").rstrip("\r") if args.timestamp: sys.stdout.write(f"[{time.time()-t0:5.1f}s] {text}\n") else: sys.stdout.write(text + "\n") sys.stdout.flush() if buf: text = buf.decode("utf-8", errors="replace") if args.timestamp: sys.stdout.write(f"[{time.time()-t0:5.1f}s] {text}\n") else: sys.stdout.write(text) sys.stdout.flush() s.close() if __name__ == "__main__": main()