Sample program 4 (generate LookUp table)
Download TwinCAT 3 project: Program link
Program description / function:
Inclusion of LookUp table interpolation values from a terminal input signal to a field variable (and optional subsequent transfer of the LookUp table interpolation values via CoE access to the terminal using sample program 3).
It is envisaged to use a ramp generator with a trigger input, whose level, in conjunction with an input of a digital input terminal (e.g., EL1002) sets the variable "bStartRecord" to TRUE via a link (e.g., push button connected to +24 V). This allows recording of the values to be synchronized with the ramp input voltage. Alternatively, an output terminal can be used (e.g., EL2002), whose output controls the trigger input and whose output is then set to TRUE via the TwinCAT development environment ("bStartRecord" would then have to be declared as AT%Q* and linked to a terminal output).
Variable declaration sample program 4
// Variable declaration for example program 4
PROGRAM MAIN
VAR CONSTANT
nEndX : BYTE := 50; // Number of support values
END_VAR
VAR
nPAISampleIn AT%I* : DINT; // PDO PAISamples
bStartRecord AT%I* : BOOL; // +Electrical junction to trigger ramp
bGetMinMax : BOOL := FALSE;
bRecordLUT : BOOL := FALSE;
r_trigStartRecord : R_TRIG;
nX : BYTE := 0;
aValues : ARRAY[0..nEndX-1] OF DINT;
nYstepValue : DINT;
tp_timer : TP;
ton_timer : TON;
nMinValue : DINT := 7812500;
nMaxValue : DINT := -7812500;
nYvalue : DINT;
tRepeatTimerValue : TIME := T#51MS;
aLUT : ARRAY[0..99] OF DINT;
END_VAR
Execution part:
// Example program 4:
// ################# Recording of 50 sample points: #################
// a) Determination of min./max. values (corresponding to the value range of the sensor)
tp_timer(IN:=bGetMinMax, PT:=T#2.51S); // Periodic duration of ramp (+reserve)
IF tp_timer.Q THEN
nMinValue := MIN(nPAISampleIn, nMinValue);
nMaxValue := MAX(nPAISampleIn, nMaxValue);
END_IF
// b) Recording of values: Start
r_trigStartRecord(CLK:=bStartRecord);
IF r_trigStartRecord.Q THEN
nX := 0;
memset(ADR(aLUT), 0 , 100);
bRecordLUT := TRUE;
END_IF
ton_timer();
IF bRecordLUT OR ton_timer.Q THEN
bRecordLUT := FALSE;
ton_timer(IN:=FALSE);
IF(nX < nEndX) THEN
// b.1) Record of values:
aValues[nX] := nPAISampleIn;
nX := nX + 1;
ton_timer(IN:=TRUE, PT:=tRepeatTimerValue); // T=2.5s/49 = 51ms
ELSE
// b.2) Recording end:
// Create linearized values:
nYstepValue := (nMaxValue - nMinValue) / nEndX; // Y steps
nYvalue := aValues[0]; // Common start value of the LUT
FOR nX:=0 TO nEndX DO
// Create LUT (X = actual values, Y = target values):
aLUT[nX*2] := aValues[nX]; // X value
aLUT[nX*2+1] := nYvalue; // Y value
// next Y value of the LUT (make a "straight"):
nYvalue := nYvalue + nYstepValue; // f(x) = b+x
END_FOR
END_IF
END_IF