Wireshark 在 TwinCAT3 中使用 ST 语言读写 Modbus 寄存器的不同周期

问题描述 投票:0回答:1

我有一个在TwinCAT 3中读写Modbus数据的程序。任务周期设置为13 ms。通过观察 Wireshark 日志,我发现读取数据的周期约为 25 ms,而写入数据的周期约为 50 ms。

IF NOT fbmbreadregs.bBusy THEN
    fbMBReadRegs(
        sIPAddr:= '192.168.2.20', 
        nTCPPort:= 1504, 
        nUnitID:= 16#FF, 
        nQuantity:= 14, 
        nMBAddr:= 0, 
        cbLength:= SIZEOF(st_ModbusRead), 
        pDestAddr:= ADR(st_ModbusRead), 
        bExecute:= TRUE, 
        tTimeout:= , 
        bBusy=> , 
        bError=> , 
        nErrId=> , 
        cbRead=> );
    
    
    
    fbBasicPID(
        fSetpointValue:= 50,
        fActualValue:= st_ModbusRead.SOC, 
        bReset:= FALSE, 
        fCtrlCycleTime:=0.013 , 
        fKp:= 0.00005, 
        fTn:= 1, 
        fTv:= 0, 
        fTd:= 0, 
        fCtrlOutput=> nFout, 
        nErrorStatus=>);
    
            
    nPref:=(1/0.001)*(50-nFout);
    
    
ELSE
    fbMBReadRegs(bExecute:= FALSE);
END_IF



IF NOT fbMBWriteRegs.bBusy  THEN
        
        arrPQ[0]:=REAL_TO_WORD(ABS(nPref));
        
    fbMBWriteRegs(
        sIPAddr:= '192.168.2.20', 
        nTCPPort:= 1504, 
        nUnitID:= 16#FF, 
        nQuantity:= 5, 
        nMBAddr:= 16#0014, 
        cbLength:= SIZEOF(arrPQ), 
        pSrcAddr:= ADR(arrPQ), 
        bExecute:= TRUE, 
        tTimeout:= , 
        bBusy=> , 
        bError=> , 
        nErrId=> );

ELSE
    fbMBWriteRegs(bExecute:=FALSE);
END_IF

为什么这些时期不同?如何实现读和写操作的周期相同?

twincat modbus-tcp
1个回答
0
投票

您可以通过同步 fbMBWriteRegs 和 fbMBReadRegs 的 bExecute 输入来实现此目的:

fbTON100ms(PT := T#100MS);
IF bRedgeEvery100ms  THEN 
    bRedgeEvery100ms := FALSE; 
    fbTON100ms.IN := TRUE; 
END_IF;
IF fbTON100ms.Q AND (NOT fbmbreadregs.bBusy) AND (NOT fbMBWriteRegs.bBusy) 
THEN
    fbTON100ms.IN := FALSE;
    bRedgeEvery100ms := TRUE;
END_IF
fbMBReadRegs(
        sIPAddr:= '192.168.2.20', 
        nTCPPort:= 1504, 
        nUnitID:= 16#FF, 
        nQuantity:= 14, 
        nMBAddr:= 0, 
        cbLength:= SIZEOF(st_ModbusRead), 
        pDestAddr:= ADR(st_ModbusRead), 
        bExecute:= bRedgeEvery100ms, 
        tTimeout:= , 
        bBusy=> , 
        bError=> , 
        nErrId=> , 
        cbRead=> );
        
fbMBWriteRegs(
        sIPAddr:= '192.168.2.20', 
        nTCPPort:= 1504, 
        nUnitID:= 16#FF, 
        nQuantity:= 5, 
        nMBAddr:= 16#0014, 
        cbLength:= SIZEOF(arrPQ), 
        pSrcAddr:= ADR(arrPQ), 
        bExecute:= bRedgeEvery100ms, 
        tTimeout:= , 
        bBusy=> , 
        bError=> , 
        nErrId=> );

但据我所知,TwinCat 上的 modbus 通信使用单独的 Windows 进程与 PLC 运行时异步通信 - 您无法 100% 控制 modbus 电报的执行。

可能适用于某些用例的替代选项 - 让 Modbus 通信保持原样,但创建另一对变量,如 st_ModbusReadSyncarrPQSync 并同步更新它们,如

IF bRedgeEvery100ms THEN
  st_ModbusReadSync := st_ModbusRead;
  arrPQ := arrPQSync;
END_IF

另外,将 fbBasicPID 放入 IF NOT fbmbreadregs.bBusy THEN 对我来说似乎是个坏主意。我没有对 PID 调节器的精确解释的经验,但通常它们应该在每个周期中不间断地执行。

© www.soinside.com 2019 - 2024. All rights reserved.