微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Twincat 3 使用 FB_MBReadRegs Modbus

如何解决Twincat 3 使用 FB_MBReadRegs Modbus

当工厂 IO 正在发送/接收输入和保持寄存器时,我无法让 FB_MBReadinputs 在 Twincat 中工作。

首先,这是我目前从 Factory IO 处理 Modbus 的工作片段:

VAR
    GAB_FactoryIO_Inputs    AT %I*  :   ARRAY [0..15] OF BYTE;
... 
END_VAR

LFB_MBReadInputs(
    sIPAddr := '192.168.0.109',nTCPPort := 505,nUnitID := 255,nQuantity := 64,nMBAddr := 0,cbLength := SIZEOF(IO.GAB_FactoryIO_Inputs),pDestAddr := ADR(IO.GAB_FactoryIO_Inputs),bExecute := TRUE,tTimeout := T#1S,bBusy =>,bError =>,nErrId =>,cbRead =>,);
LFB_MBReadInputs(bExecute := FALSE);

它在状态机中运行并愉快地产生字节,然后由 MBWriteCoils 再次写入。

但我无法开始工作的是 FB_MBReadRegs。 Beckhoff 示例在 MBReadInputs 和 MBReadRegs 之间看起来几乎相同,我第一次收到 ADS 错误 1794 并将 VAR 更改为 DINT 和 WORD,但现在没有任何反应而不是错误。 我期待 X、Y 和 Z 坐标到寄存器上的任何字节、位或整数,但绝对没有任何反应。

我已尝试简化并找出问题所在,这是目前正在发生的事情:

VAR
GAB_FactoryIO_RegsIN    AT %I*  :   ARRAY [0..5] OF DINT;
    
LFB_MBReadRegs(
        sIPAddr := '192.168.0.109',nQuantity := 16,cbLength := 100,pDestAddr := ADR(IO.GAB_FactoryIO_RegsIN),);
    LFB_MBReadRegs(bExecute := FALSE);

添加@kolyur 的建议,据我所知,它应该如何作为状态机的一部分。

显然现在我有了新的尝试,如果 FB_MBReadRegs=bBusy THEN ... 不起作用。 “错误功能块 'FB_MBReadRegs' 必须实例化才能访问”。所以这是明天要弄清楚的项目。

玩了一段时间后,我仍然没有完全掌握使用或不使用 %I*,但 %M*(或 %MB0 和 %MB64)确实做到了这一点。在 https://forge.codesys.com/forge/talk/CODESYS-V2/thread/cc22cd1dc1/ 中找到部分解决方案 无论如何,我误解了 MBReadRegs 的作用,因为 MBReadInputRegs 是从 Factorio 接收位置信息/任何内容时所在的位置。

下面明显有效的代码片段:

VAR_GLOBAL
    GAB_FactoryIO_Inputs    AT %I*  :   ARRAY [0..15] OF BYTE;  //I/O between Factory IO and TC
    GAB_FactoryIO_Outputs   AT %Q*  :   ARRAY [0..15] OF BYTE;
    GAB_FactoryIO_RegsIN    AT %MB0     :   ARRAY [0..5] OF WORD;  // %M* on both didnt work,coordinates spiraled to thousands
    GAB_FactoryIO_RegsOUT   AT %MB32    :   ARRAY [0..5] OF WORD;
    END_VAR


      
VAR;
    LFB_MBReadInputRegs     : FB_MBReadInputRegs  ;
END_VAR

    CASE iState OF
    //...other states in between
    10:  //next is in its own file

    LFB_MBReadInputRegs(
        sIPAddr := '192.168.0.109',nQuantity := 12,);
    LFB_MBReadInputRegs(bExecute := FALSE);
    //5ms wait routine and jump to next iState

稍后再进行一次编辑:

bErr 1794 不会消失的新情况。

  • 出于某种原因,cbLength 不再喜欢 100,但必须读取其大小
  • 也重启。如果我只是切断 PLC 电源开关的电源,就可以避免无谓的故障排除工作。尽管从逻辑上思考软件重启也一样好,但无论如何通过硬重置,内存问题得到了改善。
IF NOT bModbusBusy4 THEN
        bModbusBusy4    := TRUE;
fbMBReadInputRegs (
    sIPAddr := ipAddr,nTCPPort := 506,nQuantity := 32,cbLength := SIZEOF(TIO.GAB_FactoryIO_RegsIN),pDestAddr := ADR(TIO.GAB_FactoryIO_RegsIN),);
  ELSE
    IF NOT fbMBReadInputRegs.bBusy THEN
        bModbusBusy4    := FALSE;
    END_IF
fbMBReadInputRegs(bExecute := FALSE);
END_IF

解决方法

我注意到的一些事情:

  • MBReadRegs 将写入您的数组 GAB_FactoryIO_RegsIN,但您在输入空间 %I* 中配置了此变量。有什么原因吗?
  • 在您的第二个示例中,您正在阅读 16 个单词,但目标变量只有 12 个单词(ARRAY [0..5] OF DINT)。这可能是 ADS 错误 1794“无效索引组”的原因。对于 MBReadRegs,nQuantity 是指 16 位字,而 MBReadInputs 是指位。
  • 您在每次扫描时都会触发 bExecute 位。通常,您应该触发一次并等待 bBusy 位变为假,然后再触发。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?