Modbus TCP 协议开发实战:Python 从站模拟、主站读写与异常处理全流程实测
Modbus 是工业协议里的「通用语」,但新手最大的障碍是没硬件——总不能为了学协议先买一台 PLC。这套教学工程用纯 Python 搭了一条完整链路:温控产线从站模拟器(内置温度物理模型与可控加热器)+ 主站读写演示 + 非法地址异常处理,Windows 11 x64 + Python 3.14 + pymodbus 3.15 实测,文内输出全部是真实运行记录。
一、寄存器表(从站 SIM-TEMP-01,设备 ID=1)
| 地址 | 类型 | 含义 |
|---|---|---|
| 保持寄存器 1 | uint16 | 温度 ×10(248 = 24.8℃),受物理模型驱动 |
| 保持寄存器 2 | uint16 | 目标温度设定值 ×10(可写,300 = 30.0℃) |
| 保持寄存器 3 | uint16 | 运行小时数 |
| 线圈 1 | bool | 加热器启停(ON 向设定值爬升,OFF 缓慢回落) |
温度不是拍脑袋随机数:从站内置物理模型,加热器打开后温度向设定值爬升,关闭后缓慢回落环境温度——这让「写设定值 → 观察变化」成为闭环实验。
二、主站实测全流程
三步跑通:pip install pymodbus→ 窗口 A 起从站python slave_simulator.py(监听 127.0.0.1:5020)→ 窗口 B 跑主站python master_demo.py:
[连接] 127.0.0.1:5020 -> 成功 [读] 保持寄存器 1~3:原始值 [248, 12, 0] 温度 = 24.8 ℃ [写] 寄存器 2 写 300 -> 回读设定值 30.0 ℃ [写] 线圈 1 打开(加热器 ON) [观察] 加热 6 秒:25.3 -> 25.8 -> 26.3 -> 26.7 -> 27.1 -> 27.5 ℃ [异常] 读地址 200~205:isError=True 异常码=2写设定值 30.0℃ 后打开加热器,温度每秒爬升约 0.4~0.5℃,物理模型 behaving 如预期——这比「写个数再读出来」的静态演示有说服力得多。
三、异常处理是必考题
# 读不存在的地址 200~205rr=awaitclient.read_holding_registers(200,6,slave=1)ifrr.isError():# Modbus 协议层异常(异常码 2 = Illegal Data Address)print("illegal address:",rr.exception_code)真实从站对越界地址返回异常码 2 而不是报 Python 异常,也有的老设备直接返回零填充数据不报错——所以工程上要「isError 判断 + 数据合理性双重校验」。这个坑在从站模拟器里可以稳定复现,比连真机调试成本低得多。
四、从模拟到真机
换真机只改两个参数:主站连接地址从 127.0.0.1 换成设备 IP,从站 ID 换成设备的 unit id。寄存器表换成设备手册的点表,读写代码一行不用动。这套工程适合作为工业自动化的入门沙盒,也适合给上位机开发当集成测试的假从站。
📦 本文对应的完整工程(从站+主站+教程)已整理上传:点击查看资源包