Wed. Jan 7th, 2026
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

By admin

Leave a Reply

Your email address will not be published. Required fields are marked *