import serial import time import struct class InovanceMD520: def __init__(self, port='COM4', baudrate=9600, timeout=1): """ 初始化汇川MD520变频器通信 :param port: 串口名称,Windows为COMx,Linux为/dev/ttyUSBx :param baudrate: 波特率,默认9600 :param timeout: 超时时间,秒 """ self.port = port self.baudrate = baudrate self.timeout = timeout self.ser = None def connect(self): """连接串口""" try: self.ser = serial.Serial( port=self.port, baudrate=self.baudrate, bytesize=serial.EIGHTBITS, parity=serial.PARITY_NONE, stopbits=serial.STOPBITS_ONE, timeout=self.timeout ) print(f"成功连接到串口 {self.port}") return True except serial.SerialException as e: print(f"连接串口失败: {e}") return False def disconnect(self): """断开串口连接""" if self.ser and self.ser.is_open: self.ser.close() print("串口连接已关闭") def calculate_crc(self, data): """ 计算Modbus CRC16校验码 :param data: 字节数据 :return: CRC校验码(低位在前,高位在后) """ crc = 0xFFFF for byte in data: crc ^= byte for _ in range(8): if crc & 0x0001: crc = (crc >> 1) ^ 0xA001 else: crc = crc >> 1 return struct.pack('> 8) & 0xFF, # 寄存器地址高字节 register_addr & 0xFF, # 寄存器地址低字节 (register_count >> 8) & 0xFF, # 寄存器数量高字节 register_count & 0xFF # 寄存器数量低字节 ]) # 计算CRC crc = self.calculate_crc(cmd_data) full_cmd = cmd_data + crc print(f"发送读取指令: {full_cmd.hex().upper()}") try: self.ser.reset_input_buffer() self.ser.write(full_cmd) time.sleep(0.01) # 计算预期响应长度 expected_length = 5 + 2 * register_count # 地址1 + 功能码1 + 字节数1 + 数据2*N + CRC2 response = self.ser.read(expected_length) if len(response) < expected_length: print(f"响应数据长度不足: {len(response)} 字节,期望 {expected_length} 字节") return None print(f"收到响应: {response.hex().upper()}") # 验证CRC received_crc = response[-2:] calculated_crc = self.calculate_crc(response[:-2]) if received_crc != calculated_crc: print("CRC校验失败") return None # 解析数据 data_length = response[2] data_bytes = response[3:3 + data_length] results = [] for i in range(0, len(data_bytes), 2): value = (data_bytes[i] << 8) | data_bytes[i + 1] results.append(value) return results except Exception as e: print(f"通信错误: {e}") return None def main(): # 创建变频器对象 inverter = InovanceMD520(port='COM3', baudrate=9600) # 连接串口 if not inverter.connect(): return try: while True: print("\n" + "=" * 50) print("汇川MD520变频器频率查询") print("=" * 50) # 设置允许频率 frequency = inverter.set_frequency(slave_addr=0x01, frequency=210.0) if frequency is not None: print(f"✅ 设置成功") else: print("❌ 频率设置失败") # 查询运行频率 frequency = inverter.query_frequency(slave_addr=0x01) if frequency is not None: print(f"✅ 当前运行频率: {frequency:.2f} Hz") else: print("❌ 频率查询失败") # 可选:读取其他监控参数 print("\n--- 其他监控参数 ---") # 读取母线电压 (地址1002H) voltage_data = inverter.read_register(0x01, 0x1002) if voltage_data: voltage = voltage_data[0] / 10.0 # 单位0.1V print(f"母线电压: {voltage:.1f} V") # 读取输出电压 (地址1003H) output_voltage_data = inverter.read_register(0x01, 0x1003) if output_voltage_data: output_voltage = output_voltage_data[0] # 单位1V print(f"输出电压: {output_voltage} V") # 读取输出电流 (地址1004H) current_data = inverter.read_register(0x01, 0x1004) if current_data: current = current_data[0] / 100.0 # 单位0.01A print(f"输出电流: {current:.2f} A") # 等待5秒后再次查询 print("\n等待5秒后继续查询...") time.sleep(5) except KeyboardInterrupt: print("\n用户中断查询") finally: # 断开连接 inverter.disconnect() if __name__ == "__main__": main()