plctwincatststructured-textiec61131-3

How to call function every Nth seconds in IEC61131-3 structured text (TwinCAT3)?


What I want to do in the code?

I want to create a function block that is made up out of 4 methods: start, stop, run, calculate. Start method will call a run method that has an while loop that periodically calls calculate method. The while loop inside the run method will end only if the stop method is called.

What I have tried already:

  1. When I call the object.start() I want it to start a cycle that will go as long as I don't call the stop method.
timer(IN := triggerTimer, PT := T#0.1S);
trigger(CLK := timer.Q);

workingFlag := TRUE;
run();
  1. The cycle will be in the run method. Cycle will consist of a while loop conditioned via workingFlag variable. When workingFlag is True the the while loop will constantly trigger a timer structure which will every 0.1S call the calculate method.
WHILE workingFlag = TRUE DO
    triggerTimer := TRUE; //Start timer
    
    IF trigger.Q THEN //If timer expired execute code below ...
        calculate();
        triggerTimer := FALSE; //Reset the timer
    END_IF;
END_WHILE
  1. Finally the stop method will just set the workingFlag to False and theoretically it would end the cycle in run method.
workingFlag := FALSE;

What is the problem?

What I want to achieve with this?

So please any suggestions how to approach this problem?


Solution

  • Jouke already told you that WHILE is the reason. Here is your code example refactored. This is how it should be done if you want 100 milliseconds impulse work.

    timer(IN := TRUE, PT := T#100MS);
    IF timer.Q THEN
        calculate();
        timer(IN := FALSE); // reset timer
    END_IF;
    

    But remember that your main PLC cycle should not be longer than 100ms.

    The object will be a PID controller. And I want in the main program just call the start method when I want it to regulate and stop when I need it to shut down.

    Every PID function block has Enable input parameter. You can use that to start and stop PID.

    Just set you Start variable to PID function block input, that is it.