简介:Modpoll 3.4 是一款面向工业自动化与控制系统工程师的 Modbus 协议调试工具,适用于系统集成商、设备制造商及自动化从业者,用于测试和诊断 Modbus 设备的通信功能。它可模拟主站或从站,完成寄存器读写测试、通信故障排查与设备性能监控,并支持 Windows、Linux、Solaris、QNX6 等多种操作系统。资源包共 9 个文件,约 620KB,以 modpoll 可执行文件、exe 程序、pdf 说明文档、readme、license-free 许可文件及 cpp 源码为主,分别对应各平台运行程序、使用指南、授权说明与内部实现参考。目前已有 196 人学习下载。通过该工具,读者可快速验证设备响应、定位硬件或网络通信问题,并借助源码理解 Modbus 请求与响应的处理逻辑,提升调试效率与系统稳定性。
1. Modpoll 3.4:一个命令行工具,为什么成了工业现场调试的兜底手段
如果你在工控现场待过,大概率见过这样的场景:PLC 柜里设备已经上电,网线插好,但上位机软件还没部署,组态画面跑不起来,可甲方就站在旁边等着看数据。这时候能救场的,往往不是哪套庞大的 SCADA,而是一个几百 KB 的命令行小工具——Modpoll 3.4。它干的事情很纯粹:按 Modbus 协议去读写寄存器,把结果打到终端里。没有界面,没有依赖,拷过去就能跑。
这个标题背后对应的需求非常具体:手头有 Modbus TCP 或 Modbus RTU 设备,需要快速验证点位、排查通信、批量读写,或者在没有编程环境的情况下做一次数据核对。适合谁?现场调试工程师、做设备集成的开发者、写测试脚本的自动化人员,以及刚接触 Modbus 协议、想找个能立刻上手工具的新手。它不解决组态和长期采集,但解决“现在就要看到数”的问题。
2. 先把 Modbus 地址模型和 Modpoll 的映射关系理清
很多人第一次用 Modpoll 翻车,不是命令写错,而是地址对不上。Modbus 协议里寄存器分四类,每类有自己的编号习惯,而设备手册、PLC 地址表、Modpoll 参数三者之间经常差一个偏移量。这一章把映射关系讲透,后面命令才不会白敲。
2.1 四类寄存器与功能码的对应
Modbus 把数据分成四个区:线圈(Coil)、离散输入(Discrete Input)、保持寄存器(Holding Register)、输入寄存器(Input Register)。前两个是位数据,后两个是 16 位字数据。Modpoll 用不同的参数去访问它们,底层对应不同的功能码。
| 数据区 | 读写属性 | 功能码 | Modpoll 参数 | 常见设备叫法 |
|---|---|---|---|---|
| 线圈 | 读写 | 01/05/15 | -t0 | 输出继电器、DO |
| 离散输入 | 只读 | 02 | -t1 | 输入点、DI |
| 输入寄存器 | 只读 | 04 | -t3 | 模拟量输入、AI |
| 保持寄存器 | 读写 | 03/06/16 | -t4 | 参数区、AO、设定值 |
这里有个血泪经验:很多设备手册写“40001 对应第一个保持寄存器”,这是 Modicon 传统编号,40001 里的 4 表示保持寄存器区,后面的 0001 是序号。Modpoll 的-r参数要填的是协议地址,也就是从 0 开始的偏移。所以 40001 在 Modpoll 里通常写-r 0,40002 写-r 1,以此类推。如果设备手册写的是 30001,那属于输入寄存器区,用-t3,地址同样从 0 起算。
注意:不同厂商对编号的处理不一致,有的设备手册直接给协议地址,有的给传统编号。拿到手册先确认它用的是哪一种,再决定
-r填什么。
2.2 用一条最小命令验证链路
在动任何批量操作之前,先用一条读命令确认物理链路和参数是对的。假设有一台 Modbus TCP 设备,IP 是 192.168.1.10,端口 502,从站号 1,要读保持寄存器前 10 个。
# -m tcp 指定 Modbus TCP 模式 # -a 1 从站地址为 1 # -r 0 起始寄存器地址为 0 # -c 10 连续读取 10 个寄存器 # -t4 访问保持寄存器(功能码 03) # -1 只执行一次,不循环 modpoll -m tcp -a 1 -r 0 -c 10 -t4 -1 192.168.1.10这条命令执行后,终端会打印每个寄存器的地址和值。如果返回超时,先查网络连通性和端口;如果返回异常码,查从站号和寄存器区是否匹配。参数含义拆开看:-m决定走 TCP 还是 RTU,-a是从站地址,-r是起始地址,-c是数量,-t4是数据区类型,-1表示单次执行。这几个参数是后续所有操作的基础,先把它们跑通,再谈批量。
2.3 RTU 模式下的串口参数怎么配
Modbus RTU 走串口,参数比 TCP 多一层。常见做法是用-m rtu指定模式,再用-b设波特率,-p设校验方式,-d设数据位,-s设停止位。假设设备是 9600 波特率、8 数据位、无校验、1 停止位,串口是 COM3。
# -m rtu 指定 RTU 模式 # -b 9600 波特率 # -p none 无校验 # -d 8 数据位 8 # -s 1 停止位 1 # -a 1 从站地址 # -r 0 起始地址 # -c 5 读取 5 个寄存器 # -t4 保持寄存器 modpoll -m rtu -b 9600 -p none -d 8 -s 1 -a 1 -r 0 -c 5 -t4 COM3串口参数必须和从站设备完全一致,差一个校验位就会全程超时。如果手头没有设备,可以用虚拟串口工具建一对互联端口,一端跑模拟从站,一端跑 Modpoll,先把命令格式练熟。这一步的坑在于:Windows 下串口名超过 COM9 要写成\\.\COM10这种形式,否则工具可能打不开端口。
3. 批量读写与数据格式处理:让 Modpoll 真正干活
单点读取只是验证,现场真正耗时的是批量操作和数据解析。Modpoll 支持一次读多个寄存器,也支持写单个或多个寄存器,还能把结果按不同格式输出。这一章讲怎么把命令写成能复用的脚本,以及浮点数、32 位整数这些跨寄存器数据怎么处理。
3.1 批量读取与轮询间隔控制
读多个寄存器用-c控制数量,但要注意一次请求的寄存器数量有上限,常见设备支持 125 个保持寄存器一次读取,超过会返回异常。如果点位分散,宁可分多次读,也不要硬凑一个大请求。
# 每 2 秒轮询一次,共读 20 个保持寄存器 # -c 20 读取数量 # -r 0 起始地址 # -t4 保持寄存器 # -p 2 轮询间隔 2 秒(部分版本用 -p 表示间隔,需结合实际版本确认) modpoll -m tcp -a 1 -r 0 -c 20 -t4 -p 2 192.168.1.10这里要说明:Modpoll 不同版本对轮询参数的处理有差异,有的用-p表示轮询间隔,有的用-l表示循环。实际使用时先跑modpoll -h看帮助,以本机版本的参数说明为准。批量读取时如果发现部分数据明显不对,先确认设备是否支持连续读取,有些设备对跨区读取会返回异常。
3.2 写单个寄存器与写多个寄存器
写操作分两种:写单个寄存器和写多个连续寄存器。写单个用-r指定地址,后面直接跟值。写多个需要把值按顺序列出。
# 写单个保持寄存器:地址 10,值 1234 modpoll -m tcp -a 1 -r 10 -t4 192.168.1.10 1234 # 写多个连续保持寄存器:从地址 20 开始,依次写 100、200、300 modpoll -m tcp -a 1 -r 20 -t4 192.168.1.10 100 200 300写操作最怕的是地址偏移搞错,把参数写到不该写的寄存器上。现场习惯是:写之前先用读命令确认目标地址当前值,写之后再读一次回验。如果设备有写保护或需要使能位,先确认这些前置条件是否满足,否则命令返回成功但值没变,这种“假成功”最难排查。
3.3 浮点数和 32 位整数的跨寄存器解析
Modbus 寄存器是 16 位的,但现场大量数据是 32 位浮点数或 32 位整数,占用两个连续寄存器。问题在于字节序和字序:同样两个寄存器,不同设备可能按 ABCD、CDAB、BADC、DCBA 四种顺序排列。Modpoll 本身对浮点的支持有限,常见做法是先把原始寄存器读出来,再用脚本转换。
# 用 pymodbus 读取两个寄存器并解析为浮点数 from pymodbus.client import ModbusTcpClient import struct client = ModbusTcpClient('192.168.1.10', port=502) # 读保持寄存器,起始地址 0,数量 2 rr = client.read_holding_registers(address=0, count=2, slave=1) regs = rr.registers # 按 ABCD 字序解析为 32 位浮点数 # 如果设备是 CDAB,交换两个字后再 unpack raw = struct.pack('>HH', regs[0], regs[1]) value = struct.unpack('>f', raw)[0] print(value) client.close()这段代码的逻辑是:先把两个 16 位寄存器按大端打包成 4 字节,再按大端浮点解析。如果结果明显不对,把regs[0]和regs[1]交换再试,这就是 CDAB 字序。参数上,address是起始地址,count是寄存器数量,slave是从站号。实际项目中,我一般会把这四种字序都试一遍,看哪个值落在合理范围内,再固定下来写进配置。
4. 避坑与排查:Modpoll 现场最容易翻车的五个点
这一章按“现象 → 原因 → 解决”整理,都是实际调试中反复遇到的。新手照着排查,能省下大量试错时间。
4.1 现象:命令执行后一直超时,没有任何返回
原因通常有三类:网络或串口物理层不通、从站号不对、寄存器区类型选错。先确认 IP 能 ping 通、端口能 telnet 通;RTU 模式下确认串口线序和转换器供电。然后确认从站号,很多设备默认从站号是 1,但也有设备默认 0 或 255。最后确认-t参数是否和设备实际数据区匹配,用错功能码设备会直接不响应。
解决顺序:先换一条最简单的读命令,只读一个寄存器,逐个排除。如果 TCP 能通但 RTU 不通,重点查串口参数和线序。
4.2 现象:返回异常码,比如 Illegal Data Address
原因是请求的寄存器地址超出了设备支持的范围,或者该区域不可读。有些设备只实现了部分寄存器,地址表上没写的地址去读就会返回异常。解决方法是先查设备手册的寄存器映射表,确认目标地址确实存在且可读。如果手册不全,用扫描的方式从地址 0 开始小批量试读,逐步定位有效区间。
4.3 现象:读回来的值明显不对,但通信正常
原因多半是数据类型或字序问题。16 位整数直接读没问题,但 32 位数据、浮点数、有符号数都需要转换。另外有些设备的值带比例因子,比如读回来 1234 实际表示 12.34。解决方法是先确认设备手册对数据格式的定义,再用脚本做转换。如果手册没写,用已知工况反推:比如温度应该是 25 度左右,看读回来的原始值怎么换算能得到合理结果。
4.4 现象:写操作返回成功,但设备值没变
原因是设备有写保护、需要特定使能序列,或者写到了错误的寄存器。有些设备要求先写使能位,再写目标值,最后复位使能位。解决方法是查手册的写操作流程,确认是否需要多步操作。另外确认写入的值是否在设备允许范围内,超范围的值可能被设备忽略。
4.5 现象:批量读取时部分数据错位
原因是设备对连续读取的支持有限,或者中间有保留寄存器导致地址不连续。解决方法是把批量请求拆小,或者按实际连续的区间分段读取。如果发现错位,先单独读每个地址,确认哪些地址是有效的,再重新组织批量请求。
5. 把 Modpoll 嵌进日常流程:脚本化与结果校验
Modpoll 单次执行只是起点,真正提高效率的是把它变成可重复调用的脚本,并加上结果校验。这一章讲两个具体技巧:用 shell 脚本做批量点位巡检,以及用返回值判断通信质量。
5.1 用 shell 脚本做多设备巡检
现场有多台设备时,逐台敲命令不现实。常见做法是写一个设备列表,循环调用 Modpoll,把结果按设备和时间戳归档。
#!/bin/bash # 设备列表:IP 从站号 起始地址 数量 devices=( "192.168.1.10 1 0 10" "192.168.1.11 1 0 10" "192.168.1.12 2 0 10" ) for dev in "${devices[@]}"; do read ip slave start count <<< "$dev" echo "===== $ip slave=$slave $(date '+%F %T') =====" # 读取并输出,超时设为 3 秒 modpoll -m tcp -a "$slave" -r "$start" -c "$count" -t4 -1 -o 3 "$ip" echo "" done这段脚本的逻辑是:把设备参数写成数组,循环读取,每次输出设备标识和时间戳。-o 3是超时时间,单位秒,现场网络不稳定时可以适当调大。输出重定向到文件后,可以用 diff 对比两次巡检结果,快速发现哪个点位发生了变化。
5.2 用退出码判断通信状态
Modpoll 执行成功和失败会返回不同的退出码,脚本里可以用$?捕获。成功一般是 0,超时或异常是非 0。把这个判断加进巡检脚本,就能自动标记异常设备。
modpoll -m tcp -a 1 -r 0 -c 10 -t4 -1 192.168.1.10 > /tmp/result.txt 2>&1 if [ $? -ne 0 ]; then echo "通信异常,检查设备 192.168.1.10" cat /tmp/result.txt fi参数说明:> /tmp/result.txt 2>&1把标准输出和错误输出都重定向到文件,方便事后查看。退出码判断放在命令之后立即执行,中间不要插入其他命令,否则$?会被覆盖。
5.3 结果校验:用已知值反查地址映射
调试初期最有效的方法之一是:找一个已知状态的点位,比如某个已经闭合的开关、某个稳定的温度值,用 Modpoll 去读,看哪个地址返回的值和已知状态吻合。这样能快速建立地址映射关系,比对着手册逐条核对快得多。我一般会准备一张对照表,左边是物理点位,右边是 Modpoll 读到的地址和值,确认无误后再写进正式配置。
最后一章收在一个具体习惯上:每次到现场,先不急着打开组态软件,而是用 Modpoll 把关键点位读一遍,确认通信和地址映射都对,再往上叠应用。这个习惯帮我省过很多次返工——有一次上位机显示全零,查了半天以为是程序问题,最后用 Modpoll 一读,发现是设备从站号被改过,和组态配置不一致。工具不复杂,但把它放在流程的最前面,能挡住大部分低级问题。希望帮到你。
本文还有配套的精品资源,点击获取