Example program for EL2258: Multi-Timestamp
The following example program delivers 4 x 10 Switching-Tasks within one PLC-Taskcycle to the first four channels of the terminal EL2258 and also sets the respective output states inverting from „1“ to „0“, beginning with „1“ as for the first state.
The arbitrariness, for the first four channels respective different fixed switch times are illustrated by the following oscilloscope recording:
All arrays have to be linked to eight channels with all the necessary status, output and input variables respectively. This is already be done by the downloadable example:
Programlink
This example requires a PLC control with a terminal EL2258. You can use either an embedded PC that has the terminal placed on the right or an IPC with an EtherCAT link of an e.g. RJ‑45 connector to the EK1100 coupler with the terminal (e.g. C6915 + EK1100 + EL2258). Optionally a digital input terminal e.g. EL1004 can be used for program control.
The further procedure is described in section TwinCAT Quickstart, TwinCAT 3, Starting the controller.
Example program for EL2258: Multi-Timestamp
Variables declaration:
PROGRAM MAIN
VAR CONSTANT
// Number of used channels of the terminal in this code example
nNumOfSwitchTasks : INT:=4;
END_VAR
VAR_INPUT
// External switch to start by user
bEnable AT%I* : BOOL;
// Reference to check if last tasks were already executed
nOutputOrderFeedback AT%I*: ARRAY[0..7] OF USINT;
END_VAR
VAR_OUTPUT
// Link to terminal EL2258 (Output event time n):
aQE_Time AT%Q* : ARRAY[0..7] OF ARRAY[0..9] OF UDINT;
// Link to terminal EL2258 (Output event state n):
aQE_State AT%Q* : ARRAY[0..7] OF ARRAY[0..9] OF BOOL;
// Outputvariables to reset the output buffers of EL2258
bOutputBufReset AT%Q*: ARRAY[0..7] OF BOOL;
// Real number of fixed State/Time-Events as a Task for EL2258
nNoOfOutputEvents AT%Q*: ARRAY[0..7] OF USINT;
// Start-Event to trigger beginning of task scheduling
nOutputOrderCounter AT%Q*: ARRAY[0..7] OF USINT;
END_VAR
VAR
aSwitchTimes : ARRAY[0..7] OF ARRAY[0..9] OF UDINT:=
// All 8 x 10 time offsets in ms allocated to the 10 states and 8 channels
[
[ // Channel 1 time offsets:
100, 50, 25, 75, 75, 25, 50, 25, 50, 50
]
,[ // Channel 2 time offsets:
100, 25, 50, 25, 50, 50, 25, 75, 75, 50
]
,[ // Channel 3 time offsets:
100, 50, 25, 75, 75, 50, 25, 50, 25, 50
]
,[ // Channel 4 time offsets:
100, 25, 50, 50, 25, 75, 75, 50, 50, 25
]
(* More time offsets for switch tasks:
,[ // Channel 5 time offsets:
100, 50, 25, 75, 75, 25, 50, 50, 25, 50
]
,[ // Channel 6 time offsets:
100, 25, 50, 25, 50, 50, 25, 75, 75, 50
]
,[ // Channel 7 time offsets:
100, 50, 25, 75, 75, 50, 25, 50, 25, 50
]
,[ // Channel 8 time offsets:
100, 25, 50, 50, 25, 75, 75, 50, 25, 50
]
*)
];
nState : UINT:=0; // Use for "CASE .. OF" statement
nShortTime : UDINT; // Timevalue of current DC time/ lower 32 Bit only
nCurrentTime : ULINT; // Current DC-Time of the PLC-Task
bStateValue : BOOL; // Variable to set a toggled state of a task-event
nScheduleNo: INT; // Consists No of respective state/time pair of a Switch-Task
nChannel: INT; // Channel of the EL2258
END_VAR
Program:
// Example program: 10x Multi-Timestamp for EL2258
nCurrentTime := F_GetCurDcTaskTime64(); // Get current DC-Time (Task-Related)
CASE nState OF
// ====================== Do some initializations here: ============================
0:
FOR nChannel:= 0 TO (nNumOfSwitchTasks-1) DO
// Reset ouput buffer of the terminal EL2258
bOutputBufReset[nChannel] := TRUE;
END_FOR
nState := nState + 1;// Go to next state
1:
FOR nChannel:= 0 TO (nNumOfSwitchTasks-1) DO
bOutputBufReset[nChannel] := FALSE;
END_FOR
nState := nState + 1; // Go to next state
2:
// Wait for external start-event by user (e.g. ext. switch)
IF bEnable THEN
nState := 10; // Go to next state and set events
END_IF
// =================================================================================
// ============ Now fill up all state/time pairs for the four channels =============
10:
FOR nChannel:= 0 TO (nNumOfSwitchTasks-1) DO
// Last tasks already executed?
IF nOutputOrderFeedback[nChannel] = nOutputOrderCounter[nChannel] THEN
bStateValue:=1;
// Set first state level ('1')
aQE_State[nChannel][0] := bStateValue;
// Cut 64 Bit time value to 32 Bit
nShortTime := ULINT_TO_UDINT(nCurrentTime AND 16#FFFFFFFF);
// Set first time value (duration for "save" begin)
aQE_Time[nChannel][0] := (nShortTime + aSwitchTimes[nChannel][0] * 1000000);
// Put all switch states with their times into the terminal:
FOR nScheduleNo:=1 TO 9 DO // Use 'nScheduleNo' as loop counter
bStateValue := NOT bStateValue;
// Set inverting output states of one switch-task
aQE_State[nChannel][nScheduleNo] := bStateValue;
// Set timestamps by fixed array into one switch-task
aQE_Time[nChannel][nScheduleNo] :=
(aQE_Time[nChannel][nScheduleNo-1]
+ aSwitchTimes[nChannel][nScheduleNo] * 1000000);
END_FOR
END_IF
END_FOR
nState := nState + 1; // Go to next state
// =================================================================================
// ======== Allow some taskcycles (min. 2) to let EL2258 schedule all tasks ========
11:
// 'nScheduleNo' is still 9; wait until 12: 3 more PLC-Taskcycles
IF nScheduleNo = 12 THEN
FOR nChannel:= 0 TO (nNumOfSwitchTasks-1) DO
nNoOfOutputEvents[nChannel] := 10;
// Trigger Multi-Timestamp scheduling: now start:
nOutputOrderCounter[nChannel] := nOutputOrderCounter[nChannel] + 1;
END_FOR
nState := nState + 1;
ELSE
// Just count PLC-Taskcycles here
nScheduleNo := nScheduleNo + 1;
END_IF
12:
// ================================== End ==========================================
// Wait for external switch to be released
IF NOT bEnable THEN
// Go to beginning state (could be '0' also)
nState := 2;
END_IF
END_CASE