modpoll 是一个命令行的 Modbus 主站模拟器与测试工具,由 proconX / FOCUS Software 基于自家 FieldTalk 协议栈开发,当前版本 3.16。它是一个单文件二进制,Windows、Linux、树莓派都能跑,免费使用(按附带的 LICENSE-FREE 条款,可自由使用与分发,但不开放源码)。
调试 Modbus 有两条路:一条是图形工具,点鼠标、填表格、看数据网格;另一条是命令行,一行命令发出请求,结果打在终端里。图形工具适合坐在现场对着设备琢磨;命令行工具适合脚本、批量、定时、无人值守——而后者恰恰是实际工程里最缺的。
一、为什么是它
先看它能替掉什么:
一句话:它把 Modbus 请求变成了一个可以放进脚本、放进管道、放进 crontab 的东西。
先理清三个容易混的名字
搜 "Modbus 调试工具",会出现三个读音很像的东西,它们不是同一个软件:
mbpoll 的官方说明里明确写了这件事:
mbpoll 的输出语法和命令行选项语法与 proconX 发布的原版 modpoll 程序相似。但 mbpoll 是一个完全独立的项目,源码与原版 modpoll 不同。
这意味着:两者参数长得像,但不能混着抄。 拿 mbpoll 的教程去调 modpoll,或者反过来,很容易在某些选项上得到意外的行为。
关于更新节奏,如实说明
我查了官方下载文件的服务器时间戳:
距今约一年半。这不算"高频迭代",但要放在正确的语境里看:Modbus 协议本身从 1979 年至今没有发生颠覆性变化,一个功能已经完整的命令行工具,迭代慢是正常的。它和"厂商跑路、版本停在 2014 年"完全是两回事——官网在,下载可用,二进制仍在维护线上。
如果你需要的是频繁更新、可读源码、活跃社区,那 mbpoll(GPL,基于 libmodbus)更合适;如果你要的是参数成熟、开箱即用、跨平台单文件,modpoll 更省事。两者可以都装着,按场景挑。
二、安装
modpoll 没有安装程序,就是下载、解压、加进 PATH。
Windows
下载 modpoll.zip,解压到任意目录,进到 win 子目录,用命令提示符运行:
cd modpoll\win
modpoll -h
想在任何目录直接调用,就把 modpoll\win 目录加进系统环境变量 Path。
Linux
tar xzf modpoll.tgz
压缩包里是多个架构的二进制,挑一个匹配你机器的加进 PATH。以 ARM 平台(树莓派、BeagleBoard 等)为例:
export PATH=$PWD/modpoll/linux_arm-eabihf:$PATH
modpoll -h
x86_64 的机器则用 x86_64-linux-gnu 目录。
验证安装
modpoll -h
能打出完整的参数列表就说明就绪了。建议第一次装完就先把 -h 的输出存一份——这个帮助信息本身就是最准确的参数手册,比任何二手教程都可靠。
三、命令行长什么样
modpoll 的命令行结构非常简单,只有三个部分:
modpoll [OPTIONS] SERIALPORT|HOST [WRITEVALUES...]
最后这一条是理解 modpoll 的关键:读和写用的是同一个命令,区别只在于尾部有没有跟数值。
# 读:尾部没有值
modpoll -r 100 -c 5 192.168.1.200
# 写:尾部跟上要写的值(写入 1201 号寄存器)
modpoll -r 1201 -c 1 192.168.1.200 1234
还有一个很省事的默认行为:协议可以自动推断。
第一个参数里包含
/、\或COM→ 按 RTU 处理;其他情况(IP 或主机名)→ 按 TCP 处理。
所以 modpoll -r 1 192.168.1.200 不用写 -m tcp 也能工作。但建议还是显式写上,脚本里显式声明比依赖隐式推断更安全。
四、参数速查
通用选项
数据类型(-t)
-t 后面的数字就是设备手册上的寄存器区号,记忆起来很直接:
在每个区号后面可以加类型后缀,一次读多个寄存器拼成一个值:
例如 -t 4:f32 就是"保持寄存器区,按 32 位浮点解释"。
另外有两个特殊类型用于协议探测:
数值字节序
这几个参数是 32/64 位数据读出来"数值离谱"时的解药:
网络选项
注意非标端口:标准 Modbus TCP 用 502,但很多设备厂家会用 10001、10002、10003 这类端口。不写 -p 就会连到 502 上去,然后超时。
串口选项
串口默认值是 19200 / even 校验,这个要注意。 而市面上大量设备的出厂设置是 9600 / 无校验。不改参数直接读,表现就是一直超时——这跟线接错、设备不给响应的现象一模一样,很容易误判。
五、五个真实场景
场景 1:读一台 TCP 设备的前 10 个保持寄存器
modpoll -m tcp -p 502 -a 1 -r 1 -c 10 192.168.1.200
按 1 秒一次持续轮询,Ctrl+C 停止。想跑一次就退出,加 -1:
modpoll -m tcp -p 502 -a 1 -r 1 -c 10 -1 192.168.1.200
脚本里一定要加 -1,否则进程不会自己退出,会一直占着。
场景 2:一次读满 100 个寄存器,扫描整张点表
单次读取的上限是 125 个寄存器,所以 100 个可以一次读完:
modpoll -m tcp -p 10001 -a 1 -r 1 -c 100 -1 192.168.1.200
输出是带 [地址] : 值 的逐行列表,可以直接喂给 grep / awk 做判断:
# 检查第 37 个寄存器的值是否为 1(0 基协议地址 36)
modpoll -m tcp -p 10001 -a 1 -r 37 -c 1 -1 192.168.1.200 | tail -1
如果设备寄存器超过 125 个,要分段读:
for start in 1 126 251; do
modpoll -m tcp -p 10001 -a 1 -r $start -c 125 -1 192.168.1.200
done
场景 3:读 32 位浮点,以及"数值离谱"时怎么办
设备手册写着"温度,Float,地址 40001",对应命令是:
modpoll -m tcp -p 10001 -a 1 -r 1 -c 2 -t 4:f32 -1 192.168.1.200
注意 -c 2——一个 32 位浮点占两个 16 位寄存器,只读 1 个是拼不出来的。
如果读出来是 1.09e-19 这种量级,或者是个几十亿的怪数,通常不是通信故障,而是字序不对。依次试:
modpoll -m tcp -p 10001 -a 1 -r 1 -c 2 -t 4:f32 -i -f -1 192.168.1.200
-i -f 表示从站按大端处理。仍然不对的话,就要考虑设备用的是字节交换(BADC/CDAB)这类非标准排法——modpoll 没有直接对应的开关,得用 -t 4:hex 读出原始两个寄存器,自己按字节重排。
场景 4:写寄存器——FC06 还是 FC16
写操作的关键在于用哪个功能码,由 -c 决定:
# 不写 -c:默认走 FC16(写多个寄存器)
modpoll -m tcp -p 10001 -a 1 -r 1201 192.168.1.200 1234
# 加 -c 1:强制走 FC06(写单个寄存器)
modpoll -m tcp -p 10001 -a 1 -r 1201 -c 1 192.168.1.200 1234
官方参数说明里写得很清楚:-c 1 to force FC5 or FC6。有些老设备只实现了 FC06,不接受 FC16,这时候不加 -c 1 就会收到异常响应——这个坑值记住。
写多个连续的寄存器,就是尾部跟多个值,配 -c:
modpoll -m tcp -p 10001 -a 1 -r 10 -c 3 192.168.1.200 100 200 300
场景 5:定时轮询 + 落盘,做长期记录
Linux 上,把输出接给时间戳脚本,追加进日志:
while true; do
echo "=== $(date '+%F %T') ===" >> /var/log/modbus-10001.log
modpoll -m tcp -p 10001 -a 1 -r 1 -c 100 -1 192.168.1.200 >> /var/log/modbus-10001.log 2>&1
sleep 10
done
也可以让 modpoll 自己以 5 秒间隔持续轮询(注意这样不会自己退出):
modpoll -m tcp -p 10001 -a 1 -r 1 -c 100 -l 5000 192.168.1.200 | tee -a modbus.log
Windows 批处理同理:
:loop
echo === %date% %time% === >> modbus-10001.log
modpoll.exe -m tcp -p 10001 -a 1 -r 1 -c 100 -1 192.168.1.200 >> modbus-10001.log
timeout /t 10 /nobreak > nul
goto loop
长期采集一定要考虑日志体积——100 个寄存器每 10 秒一次,一天就是几十万行。配合 logrotate 或者按天切文件。
六、和图形工具的字段对照
如果你之前用的是带界面的 Modbus 工具,迁移到 modpoll 几乎是零成本,因为界面上的每个输入框都对应一个命令行参数:
最值得注意的一条是地址:很多图形工具和手册上显示的地址是 1 基(1-100),而 modpoll 的 -r 默认也是 1 基。两边都是 1 基时你直接照抄就行,不要自作聪明去减 1。 反过来,如果对方给的是 0 基的协议地址(常见于 PLC 组态软件导出的清单),才需要加 -0。
七、常见坑
八、上手路径
真正需要练的只有一件事:遇到"要定时读一批寄存器"的需求时,想到用 modpoll 而不是打开图形界面。
九、参考
官方主页与下载:https://www.modbusdriver.com/modpoll.html
官方免费许可条款:https://www.modbusdriver.com/info/LICENSE-FREE
FieldTalk 协议栈:https://www.modbusdriver.com/fieldtalk
命令语法相似的开源替代(GPL,基于 libmodbus):https://github.com/epsilonrt/mbpoll
本文基于 modpoll 3.16 编写,二进制发布日期为 2025-04-03。参数以
modpoll -h的输出为准;Modbus 协议本身稳定,但不同设备对功能码、字节序的支持差异很大,遇到异常优先怀疑设备实现而不是工具。