Jul-13-2021, 02:35 PM
(This post was last modified: Jul-13-2021, 04:18 PM by deanhystad.)
The read_status command has to read 5 bytes to get 3 status bytes. In the code below I added a check for the start of message character (often referred to as a sentinel) and a checsum check.
"""Sends a message via serial & receives back information via serial.""" import serial import time PLAYING_DONE = bytearray([0, 0, 0]) def write_command(port, command): """Write command to serial port""" command = [170] + command # Command packet starts with 0xAA command.append(sum(command) % 256) # Append checksum print(command) port.write(bytearray(command)) def read_status(port): """Read status? Returns 3L bytearray""" write_command(port, [1, 0]) bytes = port.read(5) print('Reply ', bytes) if bytes is None: raise ValueError('Read timeout') if bytes[0] != 0xAA: raise ValueError('Serial sentinel error') if bytes[4] != (sum(bytes[:-1]) % 256): raise ValueError('Serial read checksum error') return bytes[1:-1] def play_track(port, track_info): """Start playing track. Track is??""" write_command(port, [7] + track_info) with serial.Serial( 'COM3:', baudrate=9600, parity=serial.PARITY_NONE, stopbits=serial.STOPBITS_ONE, bytesize=serial.EIGHTBITS, timeout=1) as ser: # Start of serial context play_track(ser, [2, 0, 4]) # Track info? playing = None while playing != PLAYING_DONE: time.sleep(1) playing = read_status(ser) print(f'Status = {playing}') # end of serial context print("I am done")To prevent leaving the serial port open the code uses a context manager. "with serial.Serial(...)" creates a context for the serial port. When the program exits this context (the indented instructions below the "with") the serial port is automatically closed. It doesn't matter if the context exits because the program is done using the serial port or if there is an exception.