I use a level sensor to measure liquid level in a non linear tank and I need to convert the measured level in mm to volume in liters.
The look up table of the tank looks like below:
The values in between 0-9, 10-19 etc will be calculated using linear interpolation.
Any suggestions or programing examples on how to implement the aforementioned algorithm are welcomed.
I think the values in the table should be entered into a two dimentional array and then I need to make a search for an appropriate value.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
TYPEudtSoundingTable:STRUCTÂ Â Level:ARRAY[0..10]OFREAL;Â Â Volume:ARRAY[0..10]OFREAL;END_STRUCTEND_TYPE
As for the code, I use a modified binary search.
As parameters, I pass my level array and the actual level of the tank and the function will return the upper and lower indexes between which my value is.
FUNCTIONFindClosest1DVAR_INPUTÂ Â key:REAL;END_VARVAR_IN_OUTÂ Â arr:ARRAY[*]OFREAL;END_VARVAR_OUTPUTÂ Â out1:INT;Â Â out2:INT;END_VARVARÂ Â size:DINT;Â Â i:INT;Â Â j:INT;Â Â middle:INT;END_VAR
//Binarysearchsize :=UPPER_BOUND(arr,1);IFkey<=arr[0] THEN
  out1 :=0;
  out2 :=0;
  RETURN;END_IFIFkey>=arr[size] THEN
  out1 :=TO_INT(size);
  out2 :=TO_INT(size);
  RETURN;END_IFi :=0;j :=TO_INT(size);middle :=0;WHILE(i<j)DO
 Â
  middle :=(i+j)/2;
  IFkey=arr[middle] THEN
    out1 :=middle;
    out2 :=middle;
    RETURN;
  END_IF
 Â
  IFkey<arr[middle] THEN
   Â
    IF(middle>0)AND(key>arr[middle-1])THEN
     Â
      IFkey<0THEN
        out1 :=middle-1;
        out2 :=middle;
      ELSE
        out1 :=middle;
        out2 :=middle-1;
      END_IF
      RETURN;
    END_IF
   Â
    j :=middle;
     Â
  ELSE
   Â
    IF(middle<size)AND(key<arr[middle+1])THEN
      out1 :=middle;
      out2 :=middle+1;
      RETURN;
    END_IF
Â
    i :=middle+1;
   Â
  END_IFEND_WHILE
And after, I do a Linear Interpolation.
FUNCTIONLinearInterpolation:REALVAR_INPUTÂ Â X:REAL;Â Â X1:REAL;Â Â Y1:REAL;Â Â x2:REAL;Â Â Y2:REAL;END_VARVAREND_VAR
IFY1<>Y2THEN
  LinearInterpolation :=Y1+(X-X1)*((Y2-Y1)/(X2-X1));ELSE
  LinearInterpolation :=Y1;END_IF
Bellow is an example on how I use them:
PROGRAMProgVAR  Tank1:udtSoundingTable:=(Level:=[0,1,2,3,4,5,6,7,8,9,10],Volume:=[12.3,15.8,19,21.3,25.9,29,32.3,34,36,38,40]);  ActualLevel:REAL;//Modifythis  Volume:REAL;  x1:INT;  x2:INT;END_VAR
I use a level sensor to measure liquid level in a non linear tank and I need to convert the measured level in mm to volume in liters.
The look up table of the tank looks like below:
mm : lt
0 : 53
10 : 78
20 : 99
.
.
1990:13423
2000: 13478
The values in between 0-9, 10-19 etc will be calculated using linear interpolation.
Any suggestions or programing examples on how to implement the aforementioned algorithm are welcomed.
I think the values in the table should be entered into a two dimentional array and then I need to make a search for an appropriate value.
I prefer to have a struct like this:
As for the code, I use a modified binary search.
As parameters, I pass my level array and the actual level of the tank and the function will return the upper and lower indexes between which my value is.
And after, I do a Linear Interpolation.
Bellow is an example on how I use them: