Twincat经Nimbus卡用功能码04读Salicru设备值全0无报错,Modbus Poll正常如何排查
Twincat经Nimbus卡读取Salicru Modbus数据全0无报错排查方案
高优先级排查项(按排查先后顺序)
- 对齐Modbus地址与读取长度配置
这是同类场景最常见的故障源:Modbus Poll默认开启地址偏移1的显示规则,界面上看到的20200是对外展示的参考地址,对应Modbus PDU层实际发送的请求地址为20199。
你的FB中nMBAddr参数是直接对应PDU层的0基起始地址,无内置偏移。同时当前nQuantity设置为100,远大于你在Poll中验证过的20200-20204有效寄存器区间——多数Salicru设备对超出寄存器映射范围的读取请求不会返回异常码,只会对无映射的地址段静默返回全0,不会触发FB的错误标志。
临时调整参数做验证:把nMBAddr改为20199、nQuantity改为5,和Poll的读取范围完全一致,排查地址和超长读取导致的全0问题。 - 补全FB缺失的触发逻辑与参数配置
你当前的代码存在两处参数/逻辑缺失,会导致FB无报错但实际未发起有效读取:tTimeout参数留空:部分Twincat Modbus FB版本在超时参数未显式赋值时,会使用0值超时,直接跳过超时检测返回无错误状态,实际未发出网络请求。建议显式赋值为tTimeout:=T#2S。bExecute无脉冲触发:FB_MBReadInputRegs仅在bExecute的上升沿发起单次读取,如果bReadRegs一直保持长TRUE,FB只会在上电瞬间发起一次请求,后续不会重复执行。可配合周期触发逻辑实现持续读取:// 每1秒触发一次读取 t_TON(IN:=tonBool, PT:=T#1S); IF t_TON.Q THEN bReadRegs := TRUE; END_IF // 读取完成后复位触发位 IF NOT bReadBusy AND NOT bReadError THEN bReadRegs := FALSE; END_IF
- 校验Unit ID与网络路由匹配性
- 检查
nUnitID的绑定变量:你在VAR区定义的是iConvertedUnitID,但FB参数中实际传入的是iUnitID,如果该变量为未定义的笔误项,实际传入的Unit ID为0,和Salicru设备默认的Unit ID(通常为1)不匹配时,部分从站会静默丢弃请求,不返回异常码。 - 确认Nimbus卡的路由规则:你的Modbus请求是通过Nimbus卡发出,需要确认FB的请求流量是从Nimbus卡对应的网卡流出,而不是Twincat运行时的本地网卡,避免请求发送到错误网口、无响应也不触发错误标志。
- 检查
- 增加读取完成状态判定逻辑
你当前未对FB的执行状态做判定就直接读取数组值:arrTempReadDataRegs的初始值为全0,只有当bReadBusy从TRUE跳变为FALSE、且bReadError为FALSE时,数组内存才会被写入实际读取到的寄存器值。可增加状态判定逻辑确保读取完成后再使用数据:IF NOT bReadBusy AND NOT bReadError AND bReadRegs THEN bReadSuccess := TRUE; // 在此处将arrTempReadDataRegs的数值映射到targetRectifierStrut结构体 END_IF IF bReadError THEN bReadSuccess := FALSE; END_IF
快速验证步骤
把FB参数临时调整为和Modbus Poll完全一致的配置,做最小范围验证:
- 通过Modbus Poll的通信日志查看实际发送的PDU层地址,将其直接赋值给
nMBAddr - 将
nQuantity设为5,仅读取已经验证有数值的寄存器区间 - 将
nUnitID设为和Poll中配置的Slave ID一致 - 显式赋值
tTimeout=T#3S - 手动触发
bReadRegs完成一次FALSE到TRUE的跳变,观察数组前5个元素是否和Poll显示的数值一致。验证通过后再逐步扩大读取长度到100。
内容的提问来源于stack exchange,提问作者chan ming
相关产品推荐
相关产品推荐

