大地和控制器上位机,带使用说明 can
车间里那台老旧的PLC突然罢工,仪表数据像脱缰野马般收不上来——这种场景工控人都懂。今天咱们就拿大地控制器开刀,用Python和Modbus协议,手把手教你怎么让上位机和控制器"对上暗号"。
1. 连接前的灵魂三问
先确认控制器型号(比如DVP-20EX),找到它的通讯口。通常你会看到DB9接口上标注着485+/485-,这时候需要准备USB转485转换器。别急着写代码,先用调试助手发个测试命令:
`python
import serial
# 串口参数比丈母娘要求还严格
ser = serial.Serial(
port='COM3',
baudrate=9600,
bytesize=8,
parity='N',
stopbits=1,
timeout=1
)
# 发送读取保持寄存器的Modbus指令
cmd = bytes.fromhex('01 03 00 6B 00 02 15 CD')
ser.write(cmd)
response = ser.read(8)
print(f"控制器回传的十六进制数据: {response.hex()}")
`
这段代码里的0x00 0x6B对应的是保持寄存器地址107,如果收到类似01 03 04 00 0A 00 0B的回复,说明物理层握手成功。注意校验码计算是个坑,可以用crcmod库自动生成。
2. 数据解析的千层套路
收到原始数据后,处理方式比老婆的心思还难猜。温度值可能是32位浮点,也可能是两个寄存器的拼接:
`python
import struct
# 假设返回数据是00 0A 00 0B(寄存器1值10,寄存器2值11)
raw_data = b'\x00\x0A\x00\x0B'
# 大端模式解析为两个16位整数
values = struct.unpack('>2H', raw_data)
print(f"寄存器值: {values}") # 输出(10, 11)
# 如果是浮点数
float_bytes = b'\x40\x49\x0f\xdb'
floatvalue = struct.unpack('>f', floatbytes)[0]
print(f"温度值: {float_value:.2f}℃") # 输出3.14℃
`
遇到过最坑的是有的控制器用低位在前高位在后,这时候需要先反转字节顺序。建议用bytearray的reverse()方法处理。
3. 实战中的玄学问题
- 通讯中断:检查终端电阻,120Ω电阻没接就像打电话不开免提
- 数据错乱:接地不良会导致信号毛刺,用万用表量A-B线电压应在2V左右
- 响应延迟:修改超时参数,别用默认的1秒,像这样
ser.timeout=3
最后祭出调试大法:在关键位置插入hexdump打印,或者用Wireshark抓取Modbus TCP包。记住,好的日志记录比算命先生更靠谱。当你搞定这一切,看着数据流在监控界面上欢快跳动时,那感觉就像在车间里喝了瓶冰镇啤酒——通透!