﻿<?xml version="1.0" encoding="utf-8"?>
<TcPlcObject Version="1.1.0.1">
  <POU Name="Logging_work" Id="{cfa6a1bf-2bf9-4567-9b77-3b2f2ee3868b}" SpecialFunc="None">
    <Declaration><![CDATA[PROGRAM Logging_work
VAR
	dataStore 			: ARRAY[0..26] OF logData;
	index 				: UINT;
	unixTime 			: ULINT ;
	arraySize 			: UINT;
	currentTension1 	: LREAL;
	currentTension2 	: LREAL;
	previousTension1 	: LREAL;
	previousTension2 	: LREAL;
	w1LogTimer 			: TOF :=(PT := T#1M);		// continue logging after winch stops
	w2LogTimer 			: TOF :=(PT := T#1M);		// continue logging after winch stops
	updatePulse 		: TON ;						// used to store values regardless if they change or not
	storeDatatoStruct	: BOOL;	
	sinCounter 			: LREAL;					// debug
	sinus 				: LREAL;					// debug
	logCount 			: UINT;						// debug
	runDebugLogging		: BOOL;						// debug	
END_VAR

VAR CONSTANT
    MSECONDS_TO_EPOCH 	: ULINT := 11644473600000; 	//ms between 01.01.1601 - 01.01.1970
	MINIMUM_CHANGE		: LREAL	:= 0.01;			// how much must tension change to trigger a logging
END_VAR
]]></Declaration>
    <Implementation>
      <ST><![CDATA[unixTime := F_GetSystemTime() / 10000 - MSECONDS_TO_EPOCH; // divide by 10.000 to get ms

// alarms for loadcell tension is handled by the autowinch object

// keep logging after winch stops
w1LogTimer(IN := runDebugLogging OR gvlCtd01.eWinch.OpState = P6OpState.RUN OR gvlCtd01.eWinch.OpState = P6OpState.PREPARE);
w2LogTimer(IN := runDebugLogging OR gvlTractionWinch01.eWinch.OpState = P6OpState.RUN OR  gvlTractionWinch01.eWinch.OpState = P6OpState.PREPARE);

updatePulse(in := NOT updatepulse.Q, PT := T#0.5S);

// write current tension in datastore if it has changed or every half second.
IF w1LogTimer.Q THEN 
	currentTension1 := FLOAT_TO_INT(gvlCtd01.Sheavesensor.Tension)/ 10 / 100.0; //tons, rounded to the nearest 10 kg.
ELSE
	currentTension1 := -1;		// will be ignored by logging in HMI
END_IF

IF  (currentTension1 > previousTension1 + MINIMUM_CHANGE) OR (currentTension1 < previousTension1 - MINIMUM_CHANGE) OR updatePulse.Q THEN
	dataStore[index].tension1 := currentTension1;
	previousTension1 := currentTension1;
	storeDatatoStruct := TRUE; 
END_IF

IF w2LogTimer.Q THEN 
	currentTension2 := gvlTractionWinch01.Sheavesensor.Tension / 10 / 100.0; //tons, rounded to the nearest 10 kg.
ELSE
	currentTension2 := -1;		// will be ignored by logging in HMI
END_IF

IF (currentTension2 > previousTension2 + MINIMUM_CHANGE) OR (currentTension2 < previousTension2 - MINIMUM_CHANGE) OR updatePulse.Q THEN
	dataStore[index].tension2 := currentTension2;
	previousTension2 := currentTension2;
	storeDatatoStruct := TRUE; 
END_IF

//sinus := SIN(sincounter * PI / 50) * 50 + 50;
//sincounter := sincounter + 0.02;
//IF sincounter >= 100 THEN
//	sincounter:=0;
//END_IF

//dataStore[index].tension1 := sinus;
//dataStore[index].tension2 := sinus;

IF storeDatatoStruct THEN
	storeDatatoStruct := FALSE;
	dataStore[index].timestamp := unixTime; 
	index := index +1;
	arraySize :=  SIZEOF(datastore)/SIZEOF(logData); // total number of bytes divided on size of logData
	IF index >= arraySize THEN
		index := 0;
	END_IF
	logCount := logcount +1;
END_IF
]]></ST>
    </Implementation>
  </POU>
</TcPlcObject>