import minimalmodbus import time import traceback import argparse import serial.tools.list_ports from src.hardware import Hardware from src.logic import loop def get_first_available_com_port(): ports = list(serial.tools.list_ports.comports()) return ports[0].device if ports else 'COM3' def main(): parser = argparse.ArgumentParser(description='UNO Relay Modbus Controller') parser.add_argument('--com_port', type=str, default=get_first_available_com_port(), help='COM port for the Modbus connection') parser.add_argument('--slave_id', type=int, default=1, help='Slave ID for the Modbus device') parser.add_argument('--cycle_time', type=float, default=0.01, help='Cycle time in seconds for the main loop') args = parser.parse_args() com_port = args.com_port slave_id = args.slave_id cycle_time = args.cycle_time while True: try: instrument = minimalmodbus.Instrument(com_port, slave_id) instrument.serial.baudrate = 9600 instrument.serial.bytesize = 8 instrument.serial.parity = minimalmodbus.serial.PARITY_NONE instrument.serial.stopbits = 1 instrument.serial.timeout = 1 time.sleep(3) hardware = Hardware(instrument) while True: start_time = time.time() hardware.update() loop(hardware) execution_time = time.time() - start_time if execution_time > cycle_time: print(f"Warning: Loop execution time ({execution_time:.4f}s) exceeded cycle time ({cycle_time:.4f}s)") sleep_time = max(0, cycle_time - execution_time) time.sleep(sleep_time) except KeyboardInterrupt: print("Stopped by user") break except Exception as e: print(f"Error: {e}") print(traceback.format_exc()) time.sleep(5) if __name__ == "__main__": main()