0

How can create a simple LUT(Look-Up Table) in TwinCAT3 for example I have data like this:

(1,1)
(2,4)
(3,9)
(4,16)
...

I want to create a function that uses the above data to calculate new data, y=f(x) will be a function that gives the result 2.25 for input 1.5.

asys
  • 667
  • 5
  • 20

2 Answers2

2

Specifically that the function you are looking for is: FB_CTRL_LIN_INTERPOLATION

However this is a paid library, so I would suggest that if this is a one-off or simple project it may be relevant to write your own version.


Below is a simple version of an interpolation program I have used before, however I would recommend that rather than just copy/pasting you examine:

  • What your code should do if target value is above/below range?
  • Does you code need to handle misordered arrays?
  • How do you catch div/0 errors?
Raw         : REAL;
PairCnt     : INT :=    0;
PairArr     : ARRAY [1..MAX_PAIRS, 0..1] OF REAL;
i           : UDINT;
Out         : REAL;
//  Default value just in case no pairs exist
Scale := 0;

FOR i := 1 TO ( MAX_PAIRS - 1 ) DO (* -1 for looking at i+1 *)
    IF Raw > PairArr[ i, 0 ] AND_THEN
       Raw < PairArr[( i+1 ), 0 ] THEN
         Out := ((( Raw - PairArr[ i, 0 ])/( PairArr[( i+1 ), 0 ] - PairArr[ i, 0 ])) * (PairArr[( i+1 ), 1 ] - PairArr[ i, 1 ])) + PairArr[ i, 1 ];
    ELSE
        Out := PairArr[( i+1 ), 1 ];
    END_IF
END_FOR
Steve
  • 963
  • 5
  • 16
  • What your code should do if the target value is above/below range? ans: in my case, I do not need extrapolation. Does your code need to handle misordered arrays? ans: in general form yeah it needed but in this case, I can ignore them. How do you catch divide by zero errors? ans: yes and it could be solved with exception handling. – asys Jun 16 '21 at 05:48
0

The sample data you provided describes a polynomial, y=x^2. I assume your actual data is a bit more complicated. Interpolating linearly between the two surrounding points may or may not be sufficient depending on your application the coarseness of your data. It wouldn't work if you expect to get y=2.25 at x=1.5 with the given data.

One option for higher accuracy would be to do a least squares polynomial curve fit. You'd probably have to roll your own code as I haven't seen an ST function for this outside of paid libraries.

This link has a good explanation of the process: https://neutrium.net/mathematics/least-squares-fitting-of-a-polynomial/

kolyur
  • 457
  • 2
  • 13