import sys
import time
# ----------------------
# Line polling function
# ----------------------
def poll_line(buffer, handler, ignore_next_terminator_flag):
"""
Poll a single byte from USB and handle line input.
Args:
buffer (bytearray): accumulated bytes so far
handler (function): function to call when a line is complete
ignore_next_terminator_flag (list of bool): mutable flag for paired terminator
"""
try:
b = sys.stdin.buffer.read(1) # read 1 byte at a time
except OSError:
# USB not connected
return
if b is None or len(b) == 0:
return # no data available
c = b[0]
# Ignore second terminator if flag is set
if ignore_next_terminator_flag[0]:
if c == 10 or c == 13: # LF or CR
ignore_next_terminator_flag[0] = False
return
else:
ignore_next_terminator_flag[0] = False # resume normal data
# Check for line terminator
if c == 10 or c == 13: # LF or CR
line_str = buffer.decode('utf-8')
handler(line_str) # handle the line
buffer[:] = b'' # clear buffer safely
ignore_next_terminator_flag[0] = True
else:
buffer.append(c) # accumulate normal byte
# ----------------------
# Example line handler
# ----------------------
def handle_input(line: str):
"""
Called when a full line is received.
Displays the line and returns cursor to left.
"""
# Display line and return cursor to left (CR)
sys.stdout.buffer.write(line.encode('utf-8') + b'\n\r')
# sys.stdout.buffer.flush() <-- removed, not needed
# ----------------------
# Main loop
# ----------------------
buffer = bytearray()
ignore_next_terminator_flag = [False] # mutable flag
while True:
poll_line(buffer, handle_input, ignore_next_terminator_flag)
time.sleep_ms(10) # avoid busy-loop