Linear interpolation of discrete INT values
The function renders the value y at position x by performing a linear interpolation based on the neighboring reference points Pw(xw, yw) and Pw+1(xw+1, yw+1). In this example, w is the nearest reference point whose x value is smaller than the input value x, i.e. the function connects the individual reference points in series and renders the output value y based on the input value x.
Input
Activation of the function (when EN = TRUE, the function is executed during each PLC cycle)
Input value x
Apply the first element of the user-defined DUT, i.e. the number of xy values, to this input. See description of DUT structure below.
Output
Output value y
ENO is set to TRUE as soon the function is executed. Helpful when cascading function blocks with EN functions.
Instead of using this F instruction, we recommend using the corresponding FP7 instruction: FP_SCALE
The function can be used for:
linearizing measured values, e.g. with non-linear sensors
rendering a heater’s flow temperature y in relation to the outside temperature x
etc.
if the number of reference points is not between 2 ... 100, or the x values are not in ascending order (x1 < x2 < x3 < ...).
if the number of reference points is not between 2 ... 100, or the x values are not in ascending order (x1 < x2 < x3 < ...).
If the input value x is smaller than the x-coordinate of the first reference point (P1: x < x1), the output y is set to the first reference point’s y-coordinate (output y = y1, horizontal dashed line in the graph’s upper left corner).
If the input value x is greater than the x-coordinate of the last reference point (P8: x > x8), the output y is set to the last reference point’s y-coordinate (output y = y8, horizontal dashed line in the graphic’s upper right corner).
DUT for the xy value pairs (reference points P1, P2, ...):
The reference points (P1, P2, ...) are copied to the function via an DUT-type variable that contains the number of reference points and the xy value pairs (number; x1, x2, ...; y1, y2; ...).
Element: x values (ARRAY[1..z] OF INT or ARRAY[0..z-1] of INT)
Element: y values (ARRAY[1..z] OF INT or ARRAY[0..z-1] of INT)
Important information:
x values
The x values have to be entered in ascending order (x1 < x2 < x3 < ...). If the x values are the same (e.g. x2 = x3 = x4) the reference points P2(x2,y2) and P3(x3,y3) are ignored.
In order to avoid an overflow in the calculation, neighboring reference points must fulfill the following conditions:
|ya - yb| < 32767 |x - xb| < 32767 |(ya - yb)*(x - xb)| < 32767 |xa - xb| < 32767 |
This function can only process whole numbers. Numbers that follow the decimal point are cut out when calculating the value y. For example, if at the position x, y = 511,13, the function returns the value 511.
In the DUT Pool, the number of reference points and the xy value pairs are declared.
All input and output variables used for programming this function have been declared in the POU header. The same POU header is used for all programming languages.
VAR
start: BOOL:=FALSE;
(*avtivates the function*)
input_value: INT:=0;
(*input_value x*)
measured_value: Interpolation_8 (X_values := [-5,5,15,20,30,42,45,50],Y_values := [5,-5,10,2,2(5),0,2]);
(*number of reference
points*)
output_value: INT:=0;
(*output_value y*)
@'': @'';
END_VAR
Here the input variable measured_value was declared, corresponding to the type of the DUT defined above. Assigning the x values and y values was done in the POU header. However, you can change the x values and y values in the body by assigning a value to the variable, e.g. Measuredvalues.X_Values[1] for x.
When the variable start is set to TRUE, the function is carried out. For the input value at position x, the output value y is calculated via linear interpolation of the neighboring reference points stored in the variable measured_value.
BODY
WORKSPACE
NETWORK_LIST_TYPE := NWTYPELD ;
ACTIVE_NETWORK := 0 ;
END_WORKSPACE
NET_WORK
NETWORK_TYPE := NWTYPELD ;
NETWORK_LABEL := ;
NETWORK_TITLE := ;
NETWORK_HEIGHT := 5 ;
NETWORK_BODY
B(B_F,F282_SCAL!,Instance,15,0,22,5,,?DEN?Dx?Dxy_data?AENO?Cy);
B(B_VARIN,,input_value,13,2,15,4,);
B(B_VARIN,,measured_value.referencepoints,13,3,15,5,);
B(B_VAROUT,,output_value,22,2,24,4,);
B(B_CONTACT,,start,6,1,8,3,);
L(8,2,15,2);
L(1,2,6,2);
L(1,0,1,5);
END_NETWORK_BODY
END_NET_WORK
END_BODY
IF start then
F282_SCAL(input_value, measured_value.referencepoints, output_value);
END_IF;