class PWMDriver(): def __init__(self, positions : list[tuple[float, float, float]], gcode_size : tuple[float, float], port : str, baudrate : int = 115200) -> None: self.positions = positions self.gcode_size = gcode_size self.port = port self.baudrate = baudrate self._init_pwm() def _init_pwm(self) -> None: from serial import Serial self.serial = Serial(self.port, self.baudrate) def _send_position(self, pos : tuple[float, float, float]) -> None: x, y, z = pos # Convert coordinates to PWM values precision = ((2 ** 16) - 1) pwm_x : int = int(x / self.gcode_size[0] * precision) pwm_y : int = int(y / self.gcode_size[1] * precision) pen : int = 1 if z < 0 else 0 # Send PWM values to the serial port print(f"Sending PWM values: X={pwm_x:<5}, Y={pwm_y:<5}, Pen={pen}") self.serial.write(f"{pwm_x},{pwm_y},{pen}\n".encode()) def _position_reached(self) -> bool: # Check if the position has been reached return self.serial.readline().decode().strip() == "OK" def _wait_for_position(self) -> None: # Wait until the position is reached while not self._position_reached(): pass def run(self) -> None: for pos in self.positions: self._send_position(pos) self._wait_for_position() print("All positions sent successfully.")