Beckhoff PLC通过Modbus TCP读取Bender PEM353数据的配置疑问
Bender Comtraxx465网关Modbus配置与数据读取问题解决
场景说明
三台Bender PEM353仪表连接至Comtraxx465网关,通过Modbus TCP/IP协议由Beckhoff PLC(客户端)读取网关(服务器)上的仪表测量值。现有结构化文本代码,但存在Unit ID、Modbus地址配置错误,以及网关寄存器映射困惑。
现有代码
FUNCTION_BLOCK FB_ReadInputRegister VAR fbReadInputReister: FB_MBReadInputRegs; arrData : ARRAY [1..3] OF WORD; nQuantity: WORD := 3; nMBAddr: WORD:=0; fbTrigger : R_TRIG; nReadState : (WAIT, TRIGGER, READ); END_VAR
fbTrigger(); IF fbTrigger.Q THEN IF nReadState = WAIT THEN nReadState := TRIGGER; END_IF END_IF CASE nReadState OF WAIT : //Do nothing TRIGGER : fbReadInputReister( sIPAddr:= '134.102.154.7', nTCPPort:= 502, nUnitID:=40, nQuantity:= nQuantity, nMBAddr:= nMBAddr, cbLength:= SIZEOF(arrData), pDestAddr:= ADR(arrData), bExecute:= TRUE, tTimeout:= T#5S, bBusy=> , bError=> , nErrId=> , cbRead=> ); nReadState := READ; READ : fbReadInputReister(bExecute := FALSE); IF NOT fbReadInputReister.bBusy OR fbReadInputReister.bError THEN nReadState := WAIT; END_IF END_CASE
关键配置修正与说明
1. Unit ID(Slave ID)设置
- Comtraxx465网关的Unit ID默认值为1,若未在网关配置中修改,请勿随意设置为40这类非默认值。
- 网关支持两种设备映射模式:
- 单Unit ID模式:所有连接的PEM353共享同一个Unit ID,通过不同的寄存器地址段区分设备。
- 多Unit ID模式:可通过Bender配置工具为每台PEM353分配独立的Unit ID,直接通过ID区分目标设备。
- 需登录Comtraxx465的配置界面(或使用Bender Config Tool)确认当前采用的模式及对应Unit ID值。
2. Modbus寄存器地址配置
- Beckhoff的
FB_MBReadInputRegs功能块中,nMBAddr参数为偏移地址(即去掉Modbus功能码前缀的数值)。例如PEM353手册中标记的输入寄存器40001,对应的偏移地址为0;40002对应偏移1,以此类推。 - Comtraxx465会将每台PEM353的寄存器映射到自身的地址空间中,默认偏移规则通常为:
- 第一台PEM353:起始偏移
0 - 第二台PEM353:起始偏移
100(可配置) - 第三台PEM353:起始偏移
200(可配置)
- 第一台PEM353:起始偏移
- 需通过Bender配置工具查看具体的寄存器映射表,记录每台PEM353目标测量值对应的网关偏移地址。
3. 代码优化点
- 必须为
fbReadInputReister的输出参数绑定变量,才能监控读取状态与错误信息:- 在VAR块中添加:
bBusy : BOOL; bError : BOOL; nErrId : WORD; cbRead : DWORD; - 调用功能块时赋值:
bBusy=> bBusy, bError=> bError, nErrId=> nErrId, cbRead=> cbRead
- 在VAR块中添加:
- 根据目标测量值的寄存器长度调整
nQuantity:若测量值为浮点型,通常占用2个WORD,需将nQuantity设为2。
修正后代码示例
FUNCTION_BLOCK FB_ReadInputRegister VAR fbReadInputReister: FB_MBReadInputRegs; arrData : ARRAY [1..3] OF WORD; nQuantity: WORD := 3; nMBAddr: WORD:=0; // 替换为实际测量值的偏移地址 nUnitID: WORD := 1; // 替换为网关/对应设备的Unit ID fbTrigger : R_TRIG; nReadState : (WAIT, TRIGGER, READ); // 状态监控变量 bBusy : BOOL; bError : BOOL; nErrId : WORD; cbRead : DWORD; END_VAR fbTrigger(); IF fbTrigger.Q THEN IF nReadState = WAIT THEN nReadState := TRIGGER; END_IF END_IF CASE nReadState OF WAIT : // 等待触发信号 TRIGGER : fbReadInputReister( sIPAddr:= '134.102.154.7', nTCPPort:= 502, nUnitID:= nUnitID, nQuantity:= nQuantity, nMBAddr:= nMBAddr, cbLength:= SIZEOF(arrData), pDestAddr:= ADR(arrData), bExecute:= TRUE, tTimeout:= T#5S, bBusy=> bBusy, bError=> bError, nErrId=> nErrId, cbRead=> cbRead); nReadState := READ; READ : fbReadInputReister(bExecute := FALSE); IF NOT bBusy OR bError THEN nReadState := WAIT; // 可添加数据解析或错误处理逻辑 END_IF END_CASE
内容的提问来源于stack exchange,提问作者Alok Nath
相关产品推荐
相关产品推荐

