Part 8 - Tc2_Standard library (Timers and Triggers)

Video

#PLC #TwinCAT3 #Beckhoff #IEC_61131-3

🔙 Previous Part | Next Part 🔜

↩️ Go Back

Table of Contents:


A) Objectives

In the previous part we looked into some of the basic instructions of structured text programming. These are however not just basic for PLC programming but basic for any programming language.

In this part of the tutorial we will also look at some basics that are much more specific for PLC programmers. The focus will be some basic functions and function blocks that every PLC conforming to the IEC 61131-3 standard needs to have. There are several functions that all PLCs must support. And for this tutorial I've selected a few ones that I think everyone should know about.

The simple reason for this is that you will use this often when you develop PLC software because of the nature of the systems that PLCs control.

The nice thing about learning these is that because they are so basic they are available in all PLC programming environments, not just CODESYS or TwinCAT 3. This means that all code that uses them is highly portable.

The functions that will be covered are:

It should be pointed out that there are many more string functions than the CONCAT function. The CONCAT is however the one that I've used the most, we actually even used it in the previous part of this tutorial so I think it makes sense to give it a proper introduction.

In the next part of this tutorial we will look into some additional functions that you will most likely use during your PLC software career.


B) TON - Timer On Delay

The first function block that we'll talk about is TON, short for timer on delay.

|400

The TON function block turns on output on after a delay.

It can be used when you for example want something to happen during a period of time or wait a period of time before applying an action.

The input PT is the time of the delay.

B.1) Example - TON (timing diagram)

I will now explain the rest of the inputs and outputs by showing an example.

The functionality is easier to be understood with the sequence timing diagram,

The function block is instantiated in the variable declaration with TON.

|400

In this example I set the PT to three seconds.

|500

Note: The resolution on the standard TON is one millisecond

To use the function block simply call it with a boolean to start or reset the timer.

|500


C) TOF - Timer Off Delay

Next we have TOF, short for timer off delay. It's basically the inverse of TON.

|400

Instead of having the timer elapsing when IN is high, it's counted when IN is low. So in other words a falling edge is a trigger for the function block.

Another difference is that once the timer has elapsed the output Q goes low as opposed to high as in TON.

C.1) Example - TOF (timing diagram)

Let's assume we have just instantiated a TOF with the input PT set to some time In the beginning.

Let's observe the sequence timing diagram to better understand its functionality,

The function block is instantiated in the variable declaration with TOF.

|400

In this example I set the time PT to 3 seconds.

Note: The resolution on the standard TOF is one millisecond

|500

To use the function block simply call it with a boolean to start or reset the timer.

|500


D) TUTORAL 16 - Testing the FUN and FB of Tc2_Standard //FILE -->TwinCAT_Standard (part1) ✍️

Okey, it's time to do a little bit of programming.

What I've done here is that I've simply created a whole new TwinCAT project for this. So I just called it TwinCAT_standard.

The important thing is that everything that we will demonstrate today will be stuff that's in the Tc2_Standard library, so you need a reference to that.

When you create a new TwinCAT project, you always get a reference to these three libraries automatically.

Note: We will talk more about libraries and library creation in a future episode of this tutorial but for now it's just important for you to know that you need a reference to the Tc2_Standard library in order for you to have access to these functions that we're going to go through.

D.1) Testing the Timer TON 🖥️

So we start with TON...

|400

The TON function block in TwinCAT has two primary inputs:

  1. Input (IN)
  2. Preset Time (PT)
Advice: Assigning Preset Time in Declaration

  • In TwinCAT, you have the option to assign the preset time (PT) directly in the function block declaration.
  • This approach is beneficial when the PT value is constant and doesn't need adjustments during runtime.
  • Pre-assigning PT in the declaration simplifies your code, as it eliminates the need to set this value each time the function block is called.

Example:

  • You can declare the TON function block with a preset time. For instance, setting PT to 10 seconds.

  • This way, when you call the function block in your PLC program, there's no need to assign PT again, since it's already defined in the declaration.

Advantage:

  • This method streamlines the code and reduces the need for repetitive assignments during the function block call, especially when the time value is static.

Now we can create a boolean variable to use as an input so we just call this "bThisIsABoolean"

Note: this boolean could in real life be something else. It could be a push of a button or maybe it's a command to "please run a motor". It could be anything that you want to do a time measurement of.

But here it's just a boolean that we can do an online write of to see the behavior of the timer.

And it should work as expected,

Copy PLC Code:

PROGRAM MAIN
VAR
	fbTon : TON := (PT := T#10S);
	bBool : BOOL;	
	
END_VAR
-----------------------------------------------------------------------
fbTon(IN := Bbool);



D.2) Testing the Timer TOF 🖥️

Okay I will continue now with the TOF,

|400

We keep the same time, 10 seconds. Keep the same boolean.

And we test it,

It should work as expected,

Copy PLC Code:

PROGRAM MAIN
VAR
	fbTof : TOF := (PT := T#10S);
	bBool : BOOL;	
	
END_VAR
-----------------------------------------------------------------------
fbTof(IN := Bbool);



D.3) Example - Using TON to start a Motor with a Button (Motor Control Safety) 🖥️

In this example, we explore a practical scenario where using a timer in TwinCAT is not just beneficial but essential. Timers can be used in various applications, but here, we focus on a scenario involving the control of a motor via a Human Machine Interface (HMI) developed with Beckhoff HMI.

Scenario: Motor Control via HMI:
Imagine a situation where you have a button on your HMI that, when pressed, activates a motor. This setup is straightforward: a boolean value, bMoveMotor, becomes true when the button is clicked. However, what happens if the HMI crashes or the button gets stuck? Without a proper safety mechanism, the motor could continue running indefinitely, which can be dangerous.

Solution: Using Timers for Safety:
To mitigate such risks, we can design our system to be more fault-tolerant by incorporating timers. The idea is simple yet effective: the motor should run only for a predetermined duration (say 5 or 10 seconds) each time the button is pressed. This approach ensures that in case of a crash or a stuck button, the motor won’t run indefinitely.

Step-by-Step Guide:

  1. Button and Motor Logic: Initially, when the operator presses the button, bMoveMotor is set to true, activating the motor. Releasing the button sets it to false.

  1. Implementing the Timer: We introduce a TON (Timer On Delay) in our logic. The TON starts when the operator button is clicked.

  1. Conditional Motor Activation: Modify the condition for motor activation. The motor (bMoveMotor) should only operate if two conditions are met:
    • The operator button is pressed.
    • The timer has not yet elapsed.

If the timer has elapsed, the motor should stop. To restart the motor, the operator must release and re-press the button, resetting the timer.

  1. Testing the Setup: Compile and activate your system. When you press the button, observe the timer. The motor should run for the specified duration (e.g., 5 seconds) and then stop. To run it again, release and press the button once more.

Conclusion: This tutorial demonstrates how to enhance safety in your PLC software using timers. Such features are vital for designing robust and reliable systems, especially in industrial environments where safety is paramount. The joy of working with PLC software lies in solving these kinds of interesting challenges and ensuring operational safety.

Copy PLC Code:

PROGRAM MAIN
VAR
	fbTon : TON := (PT := T#5S);
	bOperatorButtonClick : BOOL;	
	bMoveMotor : BOOL;	
	
END_VAR
-----------------------------------------------------------------------
fbTon(IN := bOperatorButtonClick);
bMoveMotor := bOperatorButtonClick AND NOT fbTon.Q;



E) R_TRIG (rising edge ↑)

Next we have our R_TRIG which is a rising edge detector. It's used when you want to detect a rising edge.

Example of this is to detect if an operator has pressed a button or that you want to generate an alarm only once if a certain condition is met.

The function block is simple and has only one input and one output.

The input CLK is the signal to detect and the output Q is the edge detected. Each time the function block is called Q will return false until CLK has been false followed by a rising edge. In other words the value true.

E.1) Example - R_TRIG (timing diagram)

Let us look at an example to better understand its functionality, using the sequence timing diagram

Note: as soon as we set the input signal CLK to high, the output Q will go high and keep high only in the current PLC cycle.

The function block is instantiated in the variable declaration with R_TRIG

To use the function block, simply call it with a boolean to trigger it.


F) F_TRIG (falling edge ↓)

Next we have F_TRIG, which works as our R_TRIG, but detects a falling edge instead of rising edge

Just as R_TRIG, the function block F_TRIG has only one input and one output.

The input CLK is the signal to detect and the output Q is the edge detected.
Each time the function block is called Q will return false until CLK has been true, followed by a falling edge, in other words the value false.

F.1) Example - F_TRIG (timing diagram)

Let's look at an example using the sequence timing diagram,

The function block is instantiated in the variable declaration with F_TRIG,

To use the function block simply call it with a boolean to trigger it.


G) TUTORAL 17 - Testing the R_TRIG and F_TRIG of Tc2_Standard //FILE -->TwinCAT_Standard (part2) ✍️

Okay it's time to show the triggers and that's not gonna take so long time because they're really simple. We'll start with the rising edge trigger.

G.1) Testing the R_TRIG 🖥️

We'll start with the rising edge trigger. We just need some boolean for the trigger.

We also need a counter to count up every time we have triggered. Because the trigger goes every cycle. so it goes really fast and we are not gonna be able to see the output trigger.

So we can just call it "nTriggerCounter"

and we just execute the input signal CLK,

Okay, so the output is gonna get high when the boolean goes high and we simply check IF this goes TRUE, THEN we increase the counter by one.

So we run this and we need to set the input boolean, the CLK signal to TRUE.

The output got high, the edge detection got high, but it goes so fast so you can't see it. But we can see the counter increasing every-time the boolean is triggered.

Copy PLC Code:

PROGRAM MAIN
VAR
	fbRtrig : R_TRIG;
	bSomeBoolean : BOOL;	
	nTriggerCounter : ULINT;	
	
END_VAR
-----------------------------------------------------------------------
fbRtrig(CLK := bSomeBoolean);

IF fbRtrig.Q THEN
	nTriggerCounter := nTriggerCounter + 1;
END_IF



G.2) Testing the F_TRIG 🖥️

Let's do a falling edge trigger too, so let's just copy what we already did and change this,

Now we're gonna detect when we have a falling edge.

Copy PLC Code:

PROGRAM MAIN
VAR
	fbFtrig : F_TRIG;
	bSomeBoolean : BOOL;	
	nTriggerCounter : ULINT;	
	
END_VAR
-----------------------------------------------------------------------
fbFtrig(CLK := bSomeBoolean);

IF fbFtrig.Q THEN
	nTriggerCounter := nTriggerCounter + 1;
END_IF



G.3) Example - Using R_TRIG to execute code only at one PLC cycle 🖥️

Triggers play a crucial role in event-driven programming, especially in industrial automation. In this tutorial, we'll explore a practical example of using a trigger in TwinCAT. This example will help you understand how to generate events efficiently in response to specific actions or conditions.

Scenario: Event Generation on Button Press:
Consider a simple [[Human Machine Interface (HMI)]] with a single button. In our scenario, pressing this button generates an event. This concept can be extended to other situations, such as a temperature sensor reaching a critical level or a machine part attaining a certain position.


Solution: Implementing Rising Edge Trigger:
To address this, we introduce a rising edge trigger (R_TRIG) in our logic. This trigger will only activate once per button press, avoiding the issue of continuous message generation.

Step-by-Step Guide

  1. Introducing R_TRIG: Replace the continuous event generation with a rising edge trigger. The R_TRIG will detect the button press event.

  2. Configuring the Trigger: Set the R_TRIG to detect the operator button click. This ensures that the event is generated only at the button's rising edge (i.e., when it's pressed).


Testing the Trigger:
Compile and run your program. Press the button and observe the message generation. Now, you should see only one message per press. To generate another message, release and re-press the button.

Practical Applications:
This method is not limited to buttons. It can be applied to any sensor or trigger point, like a temperature sensor reaching a threshold. The key is to generate a single event per occurrence.

Conclusion:
This tutorial demonstrates how to use triggers effectively in TwinCAT for efficient and precise event handling. Understanding and implementing such triggers can significantly enhance the functionality and reliability of your automated systems, preventing unnecessary alerts or actions.

Copy PLC Code:

PROGRAM MAIN
VAR
	fbRtrig : R_TRIG;
	bOperatorButtonClick : BOOL;	
		
END_VAR
-----------------------------------------------------------------------
fbRtrig(CLK := bOperatorButtonClick);

IF fbRtrig.Q THEN
	ADSLOGSTR(msgCtrlMask := ADSLOG_MSTYPE_ERROR OR ADSLOG_MSGTYPE_LOG, msgFmtStr := 'Button pressed!', strArg := '');

END_IF


H) CONCAT function

Next I will introduce you to one of the many string functions that are available, which is the CONCAT function which concatenates two strings into one.

It should be noted that all those strings can be much longer than 255 characters....

The CONCAT function only works with strings up to 255 characters, that means that  each input string can only be up to 255 characters and the resulting output string can only be 255 characters.

Note: There is another function called CONCAT2 that can take strings of an arbitrary length and concatenate them.


Read more here

H.1) Example - CONCAT 🖥️

I'll show you how to use this function with a simple example.

Let's assume we have two strings:

In the variable declaration we also declare an empty string that's just called "sResultString", where we will store the result.

To use the CONCAT function simply call it and provide the two strings as input parameters. The return value of the function is the concatenated string and thus we can put the return value in our result string Now the result string will have the value of "Hello world!"

Copy PLC Code:

PROGRAM MAIN
VAR
	sString1 : STRING(255) := 'Hello ';
	sString2 : STRING(255) := 'World!';
	sResultString : STRING(255);
		
END_VAR
-----------------------------------------------------------------------
sResultString := CONCAT(STR1 := sString1, STR2 := sString2);


I) Final thoughts - preview from next part

I'm sure that you will get to use these functions and function blocks a lot in your PLC software development career as even the simplest of the PLC programs usually require you to use at least one of these functions.

Thank you for following this part so far!

In the next part of this tutorial we will continue to looking at some useful tools to write PLC software by looking into TwinCAT's utilities library. See you in the next part!


J) Summary (copy code 🖥️)

J.1) TON examples

Copy PLC Code:

PROGRAM MAIN
VAR
	fbTon : TON := (PT := T#10S);
	bBool : BOOL;	
	
END_VAR
-----------------------------------------------------------------------
fbTon(IN := Bbool);

Example - Using TON to start a Motor with a Button (Motor Control Safety)
Copy PLC Code:

PROGRAM MAIN
VAR
	fbTon : TON := (PT := T#5S);
	bOperatorButtonClick : BOOL;	
	bMoveMotor : BOOL;	
	
END_VAR
-----------------------------------------------------------------------
fbTon(IN := bOperatorButtonClick);
bMoveMotor := bOperatorButtonClick AND NOT fbTon.Q;



J.2) TOF examples

Copy PLC Code:

PROGRAM MAIN
VAR
	fbTof : TOF := (PT := T#10S);
	bBool : BOOL;	
	
END_VAR
-----------------------------------------------------------------------
fbTof(IN := Bbool);



J.3) R_TRIG examples

Copy PLC Code:

PROGRAM MAIN
VAR
	fbRtrig : R_TRIG;
	bSomeBoolean : BOOL;	
	nTriggerCounter : ULINT;	
	
END_VAR
-----------------------------------------------------------------------
fbRtrig(CLK := bSomeBoolean);

IF fbRtrig.Q THEN
	nTriggerCounter := nTriggerCounter + 1;
END_IF


Example - Using R_TRIG to execute code only at one PLC cycle
Copy PLC Code:

PROGRAM MAIN
VAR
	fbRtrig : R_TRIG;
	bOperatorButtonClick : BOOL;	
		
END_VAR
-----------------------------------------------------------------------
fbRtrig(CLK := bOperatorButtonClick);

IF fbRtrig.Q THEN
	ADSLOGSTR(msgCtrlMask := ADSLOG_MSTYPE_ERROR OR ADSLOG_MSGTYPE_LOG, msgFmtStr := 'Button pressed!', strArg := '');

END_IF


J.4) F_TRIG examples

Copy PLC Code:

PROGRAM MAIN
VAR
	fbFtrig : F_TRIG;
	bSomeBoolean : BOOL;	
	nTriggerCounter : ULINT;	
	
END_VAR
-----------------------------------------------------------------------
fbFtrig(CLK := bSomeBoolean);

IF fbFtrig.Q THEN
	nTriggerCounter := nTriggerCounter + 1;
END_IF



J.5) CONCAT examples

Copy PLC Code:

PROGRAM MAIN
VAR
	sString1 : STRING(255) := 'Hello ';
	sString2 : STRING(255) := 'World!';
	sResultString : STRING(255);
		
END_VAR
-----------------------------------------------------------------------
sResultString := CONCAT(STR1 := sString1, STR2 := sString2);

Converting ST_Event to a CSV String (T_MaxString)
Copy PLC Code:

METHOD PRIVATE CreateCsvString : T_MaxString
VAR_INPUT
	stEvent : REFERENCE TO ST_Event;	
END_VAR

VAR
	TempString : T_MaxString; 
	
END_VAR
----------------------------------------------------------------
TempString := TO_STRING(stEvent.eEventType);
TempString := CONCAT(STR1 := TempString, STR2 := ',');
TempString := CONCAT(STR1 := TempString, STR2 := TO_STRING(stEvent.eEventSeverity));
TempString := CONCAT(STR1 := TempString, STR2 := ',');
TempString := CONCAT(STR1 := TempString, STR2 := TO_STRING(stEvent.nEventIdentity));
TempString := CONCAT(STR1 := TempString, STR2 := ',');
TempString := CONCAT(STR1 := TempString, STR2 := stEvent.sEventText);
TempString := CONCAT(STR1 := TempString, STR2 := ',');
TempString := CONCAT(STR1 := TempString, STR2 := TO_STRING(stEvent.dtTimestamp));
TempString := CONCAT(STR1 := TempString, STR2 := '$n');

CreateCsvString := TempString; 


🔙 Previous Part | Next Part 🔜


Z) Glossary

File Definition