example - UpdateEventTimestampWithSystemTime custom function in ST (TC3)

#PLC #TwinCAT3 #Beckhoff

Learn more at Part 5 - Structures & functions (IEC 61131-3)

This function fills the DATE_AND_TIME value of the Structure with the current system time of the PLC.

Copy the PLC Code:

  1. Enum
TYPE E_EventType :
(
	Alarm := 0,
	Message := 1
);
END_TYPE
  1. Structure
TYPE ST_Event :
STRUCT
	eEventType : E_EventType;
	eEventSeverity : TcEventSeverity;
	nEventIdentity : UDINT;
	sEvenText : STRING(255);
	dtTimestamp : DATE_AND_TIME;
END_STRUCT
END_TYPE
  1. Function
FUNCTION UpdateEventTimestampWithSystemTime
VAR_INPUT
	stEvent : REFERENCE TO ST_Event;
END_VAR
VAR
	fbGETSYSTEMTIME : GETSYSTEMTIME;
	stFileTime : T_FILETIME; // requires Tc2_Utilities
END_VAR

------------------------------------------------------------------
fbGETSYSTEMTIME(timeLoDW => stFileTime.dwLowDateTime,
				timeHiDW => stFileTime.dwHighDateTime);

stEvent.dtTimestamp := FILETIME_TO_DT(fileTime := stFileTime);

  1. Main
PROGRAM MAIN
VAR
	stThisIsOurFirstInstanceOfAStructure : ST_Event;
	bBoolean : BOOL := FALSE;
END_VAR

------------------------------------------------------------------
IF NOT bBoolean THEN
	UpdateEventTimestampWithSystemTime (stEvent := stThisIsOurFirstInstanceOfAStructure);
	bBoolean := TRUE;
END_IF

This is how it works:

  1. we call the function that we just created (UpdateEventTimestampWithSytemTime).
  2. We provide the function with our event (stThisIsOurFirstIntstanceOfAStructure).
  3. The function takes the event as an input, but the input is passed as a REFERENCE to. So no copying is done. It's just provided a REFERENCE of it into the function.
  4. And then we use a Beckhoff function GETSYSTEMTIME to get the system time of the PLC.
  5. We store the output of this function block into a structure called T_FILETIME
  6. Then we need to convert it into a date_and_time, which we do with FILETIME_TO_DT
  7. And then we store the value in the timestamp of our structure

1) How to create Enums


To create an enumeration, right click on DUTs, select Add, then click on DUT.
500

This will bring up a new window, in where you can define new DUTs, that is Data Unit Types.
250

Write the name, that is the identifier in the NAME textbox. Make sure ENUMERATION radio box is selected. Click "Open"

Your enumeration is created. Now you can fill in the enumeration list

Conclusion:
There are a few other data types available in the IEC standard and TwinCAT 3, but these are the most common ones. This link is Beckhoff's documentation for all data types available, if you want to read more.

In TwinCAT3, and in PLCs in general, all type declaration is done at compile time. You have to declare the data types of your variables before you use them, and the type cannot be changed during the execution of the program. Implicitly trying to convert from one type to another will generally result in a compiler warning or error.

In PLCs you generally allocate memory upfront. Dynamic memory allocation, the way it can be done in for example C++ can be done in TwinCAT, although it is generally not used.

2) How to create a Structure


To create a new structure data unit type, right-click on DUTs, select Add, next select DUT.
400

Enter the name of the DUT, in this case ST_Event and make sure that "Structure" is selected.

This will create the STRUCT so that we can fill the members of the struct.

Just as with enumerations, the scope of structures is global which means that all the code in your project will see the structure definition.

You can't do like in for example C++ and create a local structure within a class.

3) How to create a Function


To create a function, right-click on POUs, select Add, Select POU.
400

Write the name of the function and fill in the data type of the return value. Make sure that structured text is selected.

This will create a shell for your function and now you can fill in the implementation.