Beispielprogramm zur EL2258: Multi-Timestamp

Das folgende Beispielprogramm vergibt 4 x 10 Schaltaufträge innerhalb eines PLC-Taskzyklus und setzt für die ersten vier Kanäle der EL2258 die Ausgangszustände abwechselnd von „1“ nach „0“, beginnend mit „1“ für den ersten Zustand.

Die willkürlichen, für die vier Kanäle jeweils unterschiedlich festgelegten Schaltzeiten sind in der folgenden Oszilloskop-Aufzeichnung gezeigt:

Beispielprogramm zur EL2258: Multi-Timestamp 1:
Aufzeichnung von vier Kanälen aus dem Multi-Timestamp Programmbeispiel

Alle Feldvariablen sind entsprechend den acht Kanälen mit jeweils allen notwenigen Zustands, Ausgangs und Eingangsvariablen zu verknüpfen. In dem zum Download zur Verfügung stehenden Beispiel ist dies bereits erfolgt:
Beispielprogramm zur EL2258: Multi-Timestamp 2:Programmlink

Dieses Beispiel erfordert eine PLC Steuerung mit einer Klemme EL2258. Sie können entweder einen embedded PC verwenden, an dem die Klemme rechtsseitig angebracht wird, oder einen IPC mit einer EtherCAT-Verbindung eines z.B. RJ-45 Anschlusses zum EK1100 Koppler mit der Klemme (z.B. C6915 + EK1100 + EL2258). Optional kann eine digitale Eingangsklemme z.B. EL1004 zusätzlich zur Programmsteuerung verwendet werden.

Das weitere Vorgehen ist im Kapitel TwinCAT Quickstart, TwinCAT 3, Starten der Steuerung beschrieben.

Beispielprogramm EL2258: Multi-Timestamp

Variablendeklaration:

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 

 

Programm:

// 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