So I took a look at the outputs out of a Wheatstone bridge vs. a Unipolar design in Excel. The conclusion I come to is that either design can work, it really depends on whether the ADC is of the unipolar bipolar type. The latter definitely benefits from a Wheatstone bridge - otherwise you're throwing away a bit of resolution for no good reason.
The resolution at low temperatures for the resistor values I chose (4k7x2 and 2k2 on the Wheatstone and 11k for the Unipolar design) and the 2k2 precision thermistor from US Sensors is gargantuan when it comes to 0-50*C measurements which are the mainstay of our expected temperature measurements. (I never expect measurements below zero *C, that would require a different kind of sensor.)
The differences are more pronounced at the high end of the temperature scale, however, where the linearization of the Wheatstone tends to decompress the steps a bit. To cite an extreme, the number of bit 'steps' from 110C to 120C for the Bipolar/Wheatstone approach is 542 while the Unipolar design makes it to 392.
So, you gain a bit of resolution at the high end of the temperature scale with the Bipolar design while enjoying fewer steps at the low end of the temperature scale. To put that in perspective, the 0-10*C range enjoys 17k steps in the unipolar design and 'only' 12k steps in the bipolar design. But either approach is offering up 10x the theoretical resolution of the Arduino. And 10k+ steps should allow me to characterize the temperature rather well.
To properly get to temperature measurements in between stated data points, I decided to create a lookup table that uses a ln(x) function between each published data point for interpolation. The results match up to beyond 3 digits after the dot, which is good enough for me. I plan on dumping these floats into ProgMem as an array and using them in a ln approximation function as a function of the integer that the ADC is reporting.
I derived the offset and multiplier through an iterative approach in Excel. The nice thing about all that work is knowing that I can now convert directly from the long integer values reported by the ADC into a temperature. See below:
Temp (*C) |
ADC Integer Value |
ln(x) multiplier |
ln(x) Offset constant |
120 |
1045 |
-22.27923662 |
274.880177 |
110 |
1637 |
-24.95192121 |
294.6597015 |
100 |
2444 |
-26.56710287 |
307.2603658 |
90 |
3561 |
-27.61393547 |
315.8211499 |
80 |
5115 |
-28.17896062 |
320.6464267 |
70 |
7294 |
-28.51382449 |
323.6249762 |
60 |
10358 |
-28.86768587 |
326.8966067 |
50 |
14646 |
-29.47440202 |
332.716181 |
40 |
20562 |
-30.6152316 |
344.0459878 |
30 |
28505 |
-32.1216923 |
359.4990127 |
25 |
33306 |
-33.62930719 |
375.1985497 |
20 |
38645 |
-36.90097385 |
409.7544579 |
10 |
50674 |
-44.05057072 |
487.2072436 |
0 |
63588 |
-56.60933954 |
626.1094879 |
To get at the offset and gain issues inside the ADC, I am considering the following: Use a 8 channel multiplexer with 3 precision resistors to create a linear offset. Every time the MUX inputs are cycled for all the channels, these resistors are sampled also. Then, the offset is calculated and added as function of the integer that the ADC is responding with on later measurements. So that takes care of offset and hopefully gain errors also.
At the 15 samples per second rate that this ADC supports in 16 bit mode, I may even elect to do two measurements of the other analog input channels (i.e. 10 samples altogether) and average them for ever second time-slice I am interested in.
Last but not least, I expect that no matter how well the thermistors are calibrated up front that they will need to be calibrated once they're on the ADC. The test with least damage potential is ice water, as thermistors apparently do not like prolonged exposure to temperatures above 90*C. But I might try both an ice water and a boiling pot of water, just to 'bound' the ADC range.