Modbus RTU / TCP 触发与输出¶
通讯设备选了 MODBUSRTU(串口)或 MODBUSTCP(网口)时,软件和 PLC 之间不是发字符串,而是读写寄存器和线圈:
软件盯着 PLC 的某个地址,值一变成约定的数就拍照;检测完再往另一个地址写 1 或 0 告诉 PLC 结果。
这一页讲这两头的地址和值怎么填。
前置条件¶
- 运行端"设备设置 →通讯设备"页已经选好
MODBUSRTU或MODBUSTCP并填好串口 / IP 参数,状态条显示"通讯(MODBUSRTU) 已就绪"。 - 手里有 PLC 侧的地址表:哪个地址代表"产品到位",结果要写到哪个地址。
- 调试端"编辑运行顺序"里已经在阶段里添加了通讯触发和通讯输出。
只有选了 Modbus,这些参数才点得动
"编辑运行顺序"窗口里 Modbus 的参数和字符串的参数是并排放的。设备类型不是 Modbus 时,Modbus 那一半全是灰的,反之亦然。
触发参数¶
在"编辑运行顺序"里选中 (trigger#n) 行,填右边下半部分:
| 项 | 填写/含义 | 调参建议 |
|---|---|---|
| 从站ID: | 对方设备的 Modbus 站号 | 串口的 IO 控制器出厂多半是 1;PLC 看它自己的设置。Modbus TCP 有些网关也要求填对站号 |
| 寄存器类型: | 四选一,决定用哪个功能码去读 | 见下表 |
| 地址: | 要读的那个线圈 / 寄存器的地址 | 填协议地址,不要加 1,也不要写成 40001 这种。详见下面的"地址怎么填" |
| 触发条件值: | 读到的值等于这个数时就算触发 | 常用 1。PLC 那边写什么就填什么 |
| 读取间隔: | 两次读之间隔多久,单位秒 | 默认 0.2 偏慢,信号短容易漏。产线常用 0.05。小于 0.01 会按 0.01 算 |
| 触发延时: | 触发到手之后再等几秒才往下走,单位秒 | 传感器装在相机前面时用它补上。一般填 0 |
寄存器类型和功能码的对应¶
| 下拉里的名字 | 功能码 | 读的是什么 |
|---|---|---|
READ_COILS |
01 | 线圈(可读可写的位) |
READ_INPUT_REGISTERS |
04 | 输入寄存器(只读的 16 位字) |
READ_HOLDING_REGISTERS |
03 | 保持寄存器(可读可写的 16 位字) |
READ_DISCRETE_INPUTS |
02 | 离散输入(只读的位) |
线圈和离散输入读回来的是 0 或 1,寄存器读回来的是 0~65535 的整数。所以读线圈时"触发条件值:"只能填 0 或 1。
老版本里 READ_DISCRETE_INPUTS 不能用
早期版本虽然下拉里有这一项,但选了它实际发出去的是功能码 03(读保持寄存器),读的是完全不同的地址空间。当前版本已经改成真正的功能码 02。
两条实用建议:
- 现场机器还没升级时,不要选
READ_DISCRETE_INPUTS,改用READ_HOLDING_REGISTERS并填对应的寄存器地址。 - 老工程里选了
READ_DISCRETE_INPUTS而且"恰好能用"的,升级之后读到的值会变,必须现场复核一遍。
地址怎么填¶
Modbus 有两套地址写法,很容易混:
- 协议地址:从 0 开始,就是报文里真正发出去的那个数。
- PLC 组态手册上的地址:常写成
00001、40001、4x0001这种,是协议地址加 1、再加上区域前缀。
软件里一律填协议地址。对照关系:
| 手册上写 | 软件里填 |
|---|---|
线圈 00001 |
0 |
保持寄存器 40001 |
0 |
保持寄存器 40011 |
10 |
厂家文档写 0x3000 |
12288(十六进制转十进制) |
拿不准就先用 PLC 厂家或 IO 板厂家的调试软件读一次,能读到值的那个地址号,减 1 之后填进来。
这是电平触发,不是边沿触发
软件只是反复读那个地址、看值等不等于"触发条件值:"。值一直挂在那里不撤,软件跑完一轮回来看还在,就会再拍一次,一直重复。所以 PLC 那边必须在触发之后把这个值清掉,或者用产品经过式的瞬时信号。
输出参数¶
选中 (output#n) 行,填右边:
| 项 | 填写/含义 | 调参建议 |
|---|---|---|
| 从站ID: | 要写的那台设备的站号 | 通常和触发用同一个 |
| 寄存器类型: | WRITE_COIL(写线圈)或 WRITE_HOLDING_REGISTER(写保持寄存器) |
结果只有通过/不通过两种用线圈就够;要发数值(卡尺读数)必须用保持寄存器 |
| 地址: | 要写的地址,同样是协议地址 | |
| 写入值: | 要写什么。可以从下拉里选一个变量,也可以直接打一个整数 | 见下面 |
| PASS/NG: | 两个数字框,中间一个斜杠。选的变量是"通过/不通过"这种是非值时,通过写左边那个数、不通过写右边那个数 | 默认是 1 / 0。PLC 约定反过来就填 0 / 1,也可以填 2 / 3 之类 |
| 延时输出: | 执行到这一行先等几秒再写,单位秒 | 一般填 0 |
| 是否为最终输出 | 勾上 = 写之前先等所有检测方案跑完 | 发总结果的那一条必须勾上 |
"写入值:"填什么¶
这是一个可以下拉选、也可以直接打字的框:
- 从下拉里选一个变量:下拉里列的是当前工程能引用的全部变量(
相机工位名->检测方案名、总结果、检测时间、SN,你自己挂的自定义变量,以及启用的整件逻辑检测整件逻辑->名字——它只在所有方案跑完后才有,只能用在勾了"是否为最终输出"的那条里)。选了之后软件会自动带上&前缀存起来。 - 直接打一个整数:例如固定写
1。只能是整数,打别的会提示"输出值必须是整数"。
变量的值最后怎么变成写进寄存器的数:
| 变量的值 | 写进去的数 |
|---|---|
通过 / 不通过(是非值,如 总结果、各检测方案结果) |
通过写"PASS/NG:"左边那个数,不通过写右边那个数 |
| 整数(如某些自定义变量) | 原样写 |
| 小数(如卡尺量出来的毫米数) | 见下面的浮点数规则 |
文字(如 SN、检测时间、条码内容) |
不支持,运行到这里会报错停机 |
SN 和条码内容发不进 Modbus
Modbus 寄存器只能放数字。要把 SN 发给 PLC,只能改用字符串协议,或者让 PLC 从别的渠道拿。
浮点数占两个寄存器¶
"写入值:"选的变量如果是小数(最典型的是卡尺量出来的毫米数),软件会把这个 32 位浮点数拆成两个 16 位寄存器,一次写到"地址:"和它的下一个地址。
这有三个后果:
- 无论"寄存器类型:"选的是线圈还是保持寄存器,浮点数一律写保持寄存器(线圈放不下 32 位)。
- 下一个地址会被占掉,排 PLC 地址表时要给它留出两个字的位置。
- 字节序默认是小端。PLC 那边读出来的数不对(数量级离谱或者正负颠倒),多半是两个字的顺序或字内字节序不一致,在 PLC 侧调换一下即可。
关于功能码的两条注意¶
- 写用的是"写多个"功能码:写线圈用功能码 15(写多个线圈)、写寄存器用功能码 16(写多个寄存器),即使只写一个点也是如此。现场确实有只认 15 / 16 不认 05 / 06 的 PLC,这是有意为之。反过来,如果你的 PLC 只开放了 05 / 06,需要在 PLC 侧或网关侧放开 15 / 16。
- 读一次只读一个点:软件每次只读一个线圈或一个寄存器,不做批量读。地址表里把触发位单独放一个地址即可。
失败时会怎样¶
- 读失败(串口没接好、PLC 没响应、地址不存在):软件不报错、不停机,当作"这一轮没读到",按"读取间隔:"继续下一轮。表现就是一直停在"等待通讯触发"。
- 写失败(对方返回异常、连接断了):会停机,弹出
Modbus RTU write data error或Modbus TCP write data error加上具体原因。 - 连接断了:软件后台每秒自动重连一次,通了自己恢复,状态条会变回绿的。
联调步骤¶
- 先用 PLC 厂家或 IO 板厂家自带的调试软件,确认那个触发地址在产品到位时确实会变成你要的值。记下读回来的那个数,它就是"触发条件值:"要填的。
- 关掉厂家的调试软件(串口只能被一个程序占用,不关就轮到 labeldetect 打不开串口)。
- 在运行端"设备设置"里填好串口 / IP 参数,确认状态条变绿。
- 在"编辑运行顺序"里按上面的表填触发参数,点"保存",保存工程。
- 点运行。日志应该停在"等待通讯触发(trigger#1)"。
- 让产品过一次(或在 PLC 里手动置位),日志应该依次出现"通讯触发(trigger#1)完成"→ 各相机拍照 → 检测结果 →"通讯输出(output#1)完成"。
- 在 PLC 里确认结果地址收到了预期的数。
常见问题¶
一直停在"等待通讯触发"。
- 状态条是不是绿的"通讯(MODBUSRTU) 已就绪"。红的先查串口 / 网络。
- 串口:波特率、数据位、校验位、停止位四项和对方完全一致吗?RS485 的 A、B 两根线有没有接反(对调一次试)。
- 从站 ID 对不对。
- 地址是不是多加了 1,或者填成了
40001这种手册写法。 - 寄存器类型选错了(选成
READ_DISCRETE_INPUTS而设备只支持 03)。 - 厂家调试软件是不是还开着占了串口。
- "触发条件值:"和实际读回来的数一样吗。
软件报 Modbus RTU failed to open serial port。
串口被别的程序占着,或者 COM 口号填错、USB 转 485 的驱动没装。
软件报 Modbus TCP failed to connect。
IP 或端口不通。先 ping 一下,再确认 Modbus TCP 端口(标准是 502)和防火墙。
PLC 那边看到软件周期性断开重连。 这是底层通讯库的已知行为:累计几次超时之后客户端会主动断链,下次读写时自动重连。只要业务上没丢数据就不用管;频繁出现说明线路质量差或 PLC 响应慢。
写结果报错停机。 看错误里的地址和从站 ID 是不是 PLC 允许写的。也可能是 PLC 只认功能码 05 / 06,见上面"关于功能码的两条注意"。
同一个产品拍了好多次。 触发是电平判断,PLC 没把触发值清掉。见上面的"这是电平触发,不是边沿触发"。
一个完整的现场实例¶
不用 PLC、只用一个传感器加串口 IO 控制器的完整接线和参数,见传感器经串口 IO 控制器触发拍照。那一页从接线、用厂家软件验证、到软件里填哪几个格子都写全了,照着做就能跑通。