TWINCAT V3 : timers in function block

dezuiper

Member
Join Date
Dec 2017
Location
Belgium
Posts
6
Hi,

I have just started programming in TWINCAT to get some experience in structured text. I have just finished my first function block but I have hit a problem. My timers do not count inside a function block. What am I doing wrong?


The block is manipulated via a visualization.

Code:
PROGRAM MAIN
VAR
    myValve : FB_PNUEMATICVALVE;
    setOpen : BOOL;
END_VAR


myValve(bSetOpen:=setOpen);
Code:
FUNCTION_BLOCK FB_PNUEMATICVALVE
VAR_INPUT
    bSetOpen : BOOL := FALSE;
END_VAR
VAR_OUTPUT
    uiWarning : UINT := 0; //b1: valve sensor error
    bIsOpen : BOOL := FALSE;
END_VAR
VAR
    fbTimerValve : TON;
    fbTimerFeedBack : TON;
    
    usiState : USINT := 0;
    usiLoopAttempts : USINT := 0;
    
    bSensorOpen : BOOL := FALSE;
    bSensorClosed : BOOL := TRUE;
    
    bValve : BOOL := FALSE;
    bFeedBack : BOOL := FALSE;
    
END_VAR


CASE usiState OF
    0: // STATIC
        IF bSetOpen <> bIsOpen THEN
            fbTimerValve(IN:=TRUE, PT:=T#100S);
            
            //fbTimerFeedBack(IN:=TRUE, PT:=T#50S);
            
            usiState := 10;
            bValve := bSetOpen;
        END_IF 
    10: // MOVING
        IF fbTimerValve.Q THEN
            fbTimerValve(IN:=FALSE);
            IF bSensorOpen OR bSensorClosed THEN
                uiWarning := uiWarning OR E_BIT_MASKS.b1;
            ELSE
                uiWarning := uiWarning OR E_BIT_MASKS.b2;
            END_IF
            usiState := 20;
            RETURN;
        END_IF
            
        IF fbTimerFeedBack.Q THEN
            fbTimerFeedBack(IN:=FALSE);
            uiWarning := uiWarning OR E_BIT_MASKS.b5;
            usiState := 30;
            RETURN;
        END_IF;
    
        IF (bSensorClosed AND NOT bSetOpen) OR (bSensorOpen AND bSetOpen) THEN
            fbTimerValve(IN:=FALSE);
            
            fbTimerFeedBack(IN:=FALSE);
            usiState := 0;
            bIsOpen := bValve;
        END_IF
        
        IF bFeedBack = bValve THEN
            fbTimerFeedBack(IN:=FALSE);
        END_IF
    
    20: //ERROR, try looping
        
    
    30: //Crititcal ERROR, do nothing
        
END_CASE
 
Is this the proper way to handle timers?

Code:
[B]fbTimerValve();
fbTimerFeedBack();[/B]

CASE usiState OF
    
    0: // STATIC
        IF bSetOpen <> bIsOpen THEN
            fbTimerValve(IN:=TRUE, PT:=T#100S);
            fbTimerFeedBack(IN:=TRUE, PT:=T#50S);
            
            usiState := 10;
            bValve := bSetOpen;
        END_IF 
    10: // MOVING
        IF fbTimerValve.Q THEN
            fbTimerValve(IN:=FALSE);
            IF bSensorOpen OR bSensorClosed THEN
                uiWarning := uiWarning OR E_BIT_MASKS.b1;
            ELSE
                uiWarning := uiWarning OR E_BIT_MASKS.b2;
            END_IF
            usiState := 20;
            RETURN;
        END_IF
            
        IF fbTimerFeedBack.Q THEN
            fbTimerFeedBack(IN:=FALSE);
            uiWarning := uiWarning OR E_BIT_MASKS.b5;
            usiState := 30;
            RETURN;
        END_IF;
    
        IF (bSensorClosed AND NOT bSetOpen) OR (bSensorOpen AND bSetOpen) THEN
            fbTimerValve(IN:=FALSE);
            fbTimerFeedBack(IN:=FALSE);

            usiState := 0;
            bIsOpen := bValve;
        END_IF
        
        IF bFeedBack = bValve THEN
            fbTimerFeedBack(IN:=FALSE);
        END_IF
    
    20: //ERROR, try looping
        
    
    30: //Crititcal ERROR, do nothing
        
END_CASE
 
You have the calls to the timers on the outside of the Case statement, which is correct--they need to run every scan. The preset value can be specified in the call since it never changes. You shouldn't try to re-execute the timer inside the Case; instead just change the IN parameter to enable or disable the timer.

Code:
fbTimerValve(PT:=T#100S);
fbTimerFeedBack(PT:=T#50S);

CASE usiState OF
    
    0: // STATIC
        IF bSetOpen <> bIsOpen THEN
            fbTimerValve.IN:=TRUE;
            fbTimerFeedBack.IN:=TRUE;
            
            usiState := 10;
            bValve := bSetOpen;
        END_IF 
    10: // MOVING
        IF fbTimerValve.Q THEN
            fbTimerValve.IN:=FALSE;
            IF bSensorOpen OR bSensorClosed THEN
                uiWarning := uiWarning OR E_BIT_MASKS.b1;
            ELSE
                uiWarning := uiWarning OR E_BIT_MASKS.b2;
            END_IF
            usiState := 20;
            RETURN;
        END_IF
            
        IF fbTimerFeedBack.Q THEN
            fbTimerFeedBack.IN:=FALSE;
            uiWarning := uiWarning OR E_BIT_MASKS.b5;
            usiState := 30;
            RETURN;
        END_IF;
    
        IF (bSensorClosed AND NOT bSetOpen) OR (bSensorOpen AND bSetOpen) THEN
            fbTimerValve.IN:=FALSE;
            fbTimerFeedBack.IN:=FALSE;

            usiState := 0;
            bIsOpen := bValve;
        END_IF
        
        IF bFeedBack = bValve THEN
            fbTimerFeedBack.IN:=FALSE;
        END_IF
    
    20: //ERROR, try looping
        
    
    30: //Crititcal ERROR, do nothing
        
END_CASE
 
I put TON in CASE statements like this..
Code:
Case Seq OF
    10:
    IF fbMyTimer.Q THEN //advance
        Seq := 20;
    END_IF;

    fbMyTimer(
              IN := <Your Condition> AND (Seq = 10),
              PT := T#2s
              );

    20:
    //next step....

This keeps everything to do with the timer in one place.
Putting the (Seq = 10) clause in tidies up behind itself.
I also use ENUMs for the Sequencer rather than an INT type variable, but that doesn't change the functionality.
Pp
 
Last edited:

Similar Topics

Sorry if this has been asked before, and apologies if this seems like a trivial issue, but I am new to Beckhoff and have been banging my head...
Replies
1
Views
60
Hi everyone, This is my first time posting, so please forgive any omissions or mistakes. I am attempting to control the velocity of a stepper...
Replies
18
Views
741
I am trying to communicate between a 1769-L16 and a beckhoff EL6652 EtherNet/IP-Master. I need 8 INT and 2 REALS. When I generate the eds file, in...
Replies
1
Views
110
Hi everyone, I'm a last year student at the university in Ghent, and for my thesis i need to write a TwinCAT program that writes data to a .daq...
Replies
0
Views
119
We have a Pinnacle power supply from Advanced Energy which we'd like to control using TwinCAT 3, via an EL6002 and RS-232. I got the...
Replies
2
Views
697
Back
Top Bottom