如何获取USB转串口适配器另一端设备的VID/PID及识别特定串口设备?
解决串口转USB连接称重秤无响应及设备识别问题
一、先搞定称重秤无响应的核心问题
硬件与参数排查
- 串口线类型:别用直连线!大部分称重秤和PL2303适配器都是DTE设备,必须用**交叉串口线(Null Modem)**才能建立双向通信。
- 严格匹配串口参数:每个品牌秤的默认参数不一样,错一个都不行:
- Sartorius Entris:波特率9600,数据位8,停止位1,无校验,无流控
- Mettler Toledo Excellence Plus:波特率通常是9600或19200,数据位7/8,停止位1,校验奇偶/无(务必查对应型号手册)
- PySerial初始化示例:
import serial ser = serial.Serial( port='COM3', # 替换成你的适配器COM口 baudrate=9600, parity=serial.PARITY_NONE, stopbits=serial.STOPBITS_ONE, bytesize=serial.EIGHTBITS, timeout=2 )
- 更新PL2303驱动:Windows10自带的PL2303驱动经常出问题,去Prolific官网装最新的正式版驱动,避免通信丢包。
通信验证步骤
- 先脱离Python,用串口调试工具(比如SSCOM)手动测试:
- Sartorius一般发
?\r\n或W\r\n(看手册) - Mettler Toledo发
SI\r\n或P\r\n - 如果调试工具也收不到响应,优先换串口线、USB口、适配器;如果调试工具有响应,再查代码问题:
- 确认指令的结束符(
\r/\n/\r\n)是否正确,秤只认符合格式的指令 - 读取数据时用
ser.readline()或指定字节数读取,超时时间别设太短(至少2秒)
- 确认指令的结束符(
- Sartorius一般发
二、用Python识别特定厂商的称重秤(区分其他串口设备)
串口设备本身没有USB VID/PID,所以只能先通过适配器的VID/PID过滤出目标端口,再通过通信协议验证确认是否是秤,两种实现方式:
方式1:用PySerial自带工具枚举+通信验证
import serial import serial.tools.list_ports def find_target_scale(): # 先过滤所有PL2303适配器的COM口(VID:PID=067B:2303) pl2303_ports = [ port.device for port in serial.tools.list_ports.comports() if "VID:PID=067B:2303" in port.hwid ] # 逐个端口尝试通信验证 for port in pl2303_ports: try: ser = serial.Serial(port, 9600, timeout=2) # 测试Sartorius指令 ser.write(b'?\r\n') resp = ser.readline() if resp and b"Entris" in resp: # 根据返回内容判断 ser.close() return f"{port} - Sartorius Entris 秤" # 测试Mettler Toledo指令 ser.write(b'SI\r\n') resp = ser.readline() if resp and b"Excellence" in resp: ser.close() return f"{port} - Mettler Toledo Excellence Plus 秤" ser.close() except Exception: continue return "未检测到目标称重秤" # 调用示例 print(find_target_scale())
方式2:结合Windows WMI获取设备描述(适合多适配器场景)
如果有多个PL2303适配器,想通过设备描述辅助区分,用pywin32调用WMI:
import win32com.client import serial def get_scale_com_ports(): wmi = win32com.client.GetObject("winmgmts:") candidate_ports = [] # 枚举所有串口设备,过滤PL2303相关的 for port in wmi.InstancesOf("Win32_SerialPort"): if "Prolific" in port.Description: candidate_ports.append(port.DeviceID) # 通信验证逻辑和方式1一致 for port in candidate_ports: try: ser = serial.Serial(port, 9600, timeout=2) ser.write(b'?\r\n') if ser.readline(): ser.close() return port ser.close() except Exception: continue return None
重要提醒
- 部分秤需要在本地菜单里开启串口输出模式,并设置输出格式为ASCII,否则不会主动返回数据
- 不要依赖设备描述来直接判断是否是秤,因为适配器的描述都是“Prolific USB-to-Serial Comm Port”,必须通过通信验证才能100%确认
内容的提问来源于stack exchange,提问作者Noah Mazza
相关产品推荐
相关产品推荐

