如何使用结构化文本在Codesys中的函数内添加计时器? [英] How can I add a timer within a function in codesys using structured text?

查看:668
本文介绍了如何使用结构化文本在Codesys中的函数内添加计时器?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在Codesys V3.5 SP9补丁5中遇到结构化文本的问题.我要做的是能够在我创建的函数中使用计时器,该函数在POU中被调用.在不使用功能的情况下,我通过将计时器直接放入POU进行了同样的操作.

I'm having a problem with structured text in Codesys V3.5 SP9 Patch 5. What I want to do is to be able to use a timer within a function created by me, which is called in a POU. I've done the same without using function by putting timer directly into POU and it is working.

我的函数声明:

FUNCTION AssignDOORStatus : USINT
VAR_INPUT

    DDUC_ComSta_Dcux_x: BOOL; //No communication
    DDUC_DCUxEmHdler_x: BOOL; //Emergency handler

END_VAR
VAR

    Timer: TP; //Timer to do intermittence between current doors status and emergency handler
    CurrentDoorStatus: USINT;
    TONProcessTime: TIME := T#1S; //TONProcesTime

END_VAR

我的功能代码:

IF DDUC_ComSta_Dcux_x THEN

    CurrentDoorStatus := 0;

ELSE

    CurrentDoorStatus := 1; 

END_IF


IF DDUC_DCUxEmHdler_x THEN

    Timer(IN := NOT Timer.Q, PT := TONProcessTime); //Timer starts
    Timer();

    IF Timer.Q THEN //When TONProcessTime has gone by

        IF AssignDOORStatus <> CurrentDoorStatus THEN

            AssignDOORStatus := CurrentDoorStatus;

        ELSE AssignDOORStatus := 10;

        END_IF

    END_IF

ELSE

    AssignDOORStatus := CurrentDoorStatus;

END_IF

我在POU主代码中的代码:

My code in POU main:

testdoor := AssignDOORStatus(DDUC_ComSta_Dcu1_S1_T,DDUC_DCU1EmHdler_S1_T);

此代码用于根据变量"DDUC_ComSta_Dcux_x"将0或1分配给"AssignDOORStatus",然后,当"DDUC_DCUxEmHdler_x"为true时,它将使用计时器将"AssignDOORStatus"值从"0或1"翻转为10.

This code is used to assign to "AssignDOORStatus" 0 or 1 depending on variable "DDUC_ComSta_Dcux_x " and then, when "DDUC_DCUxEmHdler_x " is true, it flips "AssignDOORStatus" value from "0 or 1" to 10, using timer.

我必须多次调用POU才能使用此功能.

I have to call in POU many times this function.

提前谢谢!

推荐答案

函数没有内存.因此,在VAR中声明的所有变量都是临时变量,并为每个新调用重置为默认值.

Functions have no memory. Therefore all variables declared inside VAR are temporary and are reset to their default for each new call.

功能块/程序具有内存.因此,在VAR中声明的所有变量在每次调用之间均保持其值.

FunctionBlocks/Programs have memory. Therefore all variables declared inside VAR remain their values between each call.

这就是为什么您不应该使用一个函数,该函数会忘记每次MAIN调用之间的所有操作.例如,计时器将从上一个呼叫中重置.

That's why you should not use a function, which will forget everything between each call from MAIN. For instance the timer will be reset from the previous call.

相反,您应该编写一个功能块(或FB),可以将其重新用于要处理的几扇门.在功能块内部将包含一组变量(尤其是计时器),这些变量对于每个实例而言都是唯一的,并且在每次调用时都会被记住.

Instead you should write a function block (or FB), which can be re-used for the several doors you want to handle. Inside the function block will be a set of variables (especially the timer), which will be unique for each instance and also be remembered from call to call.

上面的描述很简短,因此您应该在编译器帮助文件中查找功能块,以获得正确的解释,例如用于输入/输出参数.
以下是我对一个针对三个不同门实例使用相同FB的程序的建议:

The above is a very short description so you should really look up the function block in your compilers help file to get a proper explanation, e.g. for input/output parameters.
Below is my suggestion for a program that uses the same FB for three different door instances:

(The FB, first the declaration and then it's code)
FUNCTION_BLOCK FB_AssignDOORStatus
VAR_INPUT
    DDUC_ComSta_Dcux_x: BOOL; //No communication
    DDUC_DCUxEmHdler_x: BOOL; //Emergency handler
END_VAR
VAR_OUTPUT  
    AssignDoorStatus: USINT;    
END_VAR
VAR
    Timer: TP; //Timer to do intermittence between current doors status and emergency handler
    CurrentDoorStatus: USINT;
    TONProcessTime: TIME := T#1S; //TONProcesTime
END_VAR
----------
IF DDUC_ComSta_Dcux_x THEN
    CurrentDoorStatus := 0;
ELSE
    CurrentDoorStatus := 1; 
END_IF

IF DDUC_DCUxEmHdler_x THEN
    Timer(IN := NOT Timer.Q, PT := TONProcessTime); //Timer starts
    Timer();

    IF Timer.Q THEN //When TONProcessTime has gone by
        IF AssignDOORStatus <> CurrentDoorStatus THEN
            AssignDOORStatus := CurrentDoorStatus;
        ELSE
            AssignDOORStatus := 10;
        END_IF
    END_IF
ELSE
    AssignDOORStatus := CurrentDoorStatus;
END_IF

(MAIN, first the declaration and then it's code)
PROGRAM MAIN
VAR
    // You must make an instance of your function block(s). This instance will live from call to call. 
    fbAssignDOORStatus_1: FB_AssignDOORStatus;
    fbAssignDOORStatus_2: FB_AssignDOORStatus;
    fbAssignDOORStatus_3: FB_AssignDOORStatus;
    // ...
    // Better to use an array to hold the many FB instances needed...
    // You could use a for loop in the MAIN program to call all the instances.

    // Test variables to hand to the fb's during runtime.
    ComSta: BOOL;
    EmHdler: BOOL;
    TestDoor1, TestDoor2, TestDoor3: USINT;
    // Here you could also use an array or re-use some common variable... 
END_VAR
----------
fbAssignDOORStatus_1(
    DDUC_ComSta_Dcux_x := ComSta,
    DDUC_DCUxEmHdler_x := FALSE,
    AssignDoorStatus => TestDoor1);

fbAssignDOORStatus_2(
    DDUC_ComSta_Dcux_x := TRUE,
    DDUC_DCUxEmHdler_x := EmHdler,
    AssignDoorStatus => TestDoor2);

fbAssignDOORStatus_3(
    DDUC_ComSta_Dcux_x := ComSta,
    DDUC_DCUxEmHdler_x := EmHdler,
    AssignDoorStatus => TestDoor3);

这篇关于如何使用结构化文本在Codesys中的函数内添加计时器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆