I realize this is an old thread, but it really helped me a lot, so I wanted to contribute my solution.

My equation is based on the code from CrossRoads, that was super-helpful! I’ve likely just re-written the function in a different way, but I’ve also tested it and it appears to be working.

Where vMin and vMax are min and max voltage readings and iMin and iMax are the edges of the corresponding range:

newVal = iMax - ((iMax - iMin) * ((reading - vMin) / (vMax - vMin)))

Let’s say our reading is 180. Look below at the lookup table. On the left are the voltage readings I’m getting from the sensor and on the right the corresponding measurements. Note that the voltage readings are ascending, while the measurements are descending.

```
// look-up tables for mapping readings to measurements
int[] theArray = {
140, 300,
151, 280,
162, 260,
184, 240,
211, 220,
250, 200,
285, 180,
328, 160,
371, 140,
0, 0
};
```

180 lies between 162 and 184, the corresponding range is 260 to 240, inverted. We can already assume that our result should be a little bit higher than 240, because 180 is a little bit lower than 184.

iMin = 240

iMax = 260

vMin = 162

vMax = 184

newVal = 260 - ((260-240) * ((180-162)/(184-162)))

newVal = 243.64

Here’s the for loop I use to find the range of my reading and then interpolate that to measurements.

```
for (int i=0; i<theArray.length-2; i=i+2) {
if ((A >= theArray[i]) && (A <= theArray[i+2])) {
newVal = theArray[i+1] - ((theArray[i+1]-theArray[i+3]) * ((A-theArray[i]) / (theArray[i+2]-theArray[i])));
break;
}
}
```