Richard Holmes

Designing thermometers

In Cool things, Electronics on 4 January 2013 at 9:52 pm

I built a digital thermometer last night:

There are a lot of wires there but most of them are for communicating with the LCD display. The thermometer itself is just two parts, a thermistor and a fixed resistor:

They form a voltage divider, and the voltage from Arduino (analog input) pin 0 to ground depends on the thermistor resistance, and so on temperature. Easy.

Well.

That dependence on temperature isn’t so easy. The thermistor I’m using is a Vishay NTCLE100E3103JB0 and according to the datasheet, the temperature (in Kelvins) as a function of the resistance is given by

1/T = A + B ln(R/Rnom) + C (ln(R/Rnom))2 + D (ln(R/Rnom))2

where Rnom = 10000 ohms and A, B, C, and D are empirically determined constants. This isn’t at all linear, and the sensitivity — the rate at which R varies with T — is largest at low temperatures and much smaller at high temperatures. Notice that as the temperature goes down, R goes up — this is a negative temperature coefficient thermistor.

So, OK, the Arduino code can calculate T from this formula; so what? Well, suppose we wanted to use this thermistor to measure air temperature as a function of altitude up to 100,000 feet. The temperature will vary from roughly –70°C to +25°C, and the sensitivity of the resistance to the temperature will vary considerably over that range.

(Be careful here; the resistance is most sensitive at low temperature, but what we measure is the voltage from the divider, which doesn’t depend linearly on the resistance:

vout = Vin(R2/(R1+R2))

So for example, if at high temperature the thermistor resistance R1 is much smaller than the fixed resistance R2 then the voltage we measure will be close to Vin=5V and it won’t vary much even if R1 does.)

What we read on the Arduino of course isn’t the voltage, but a value from an ADC (analog to digital converter). Analog levels from 0 to 5V are read as integers in the range 0 to 1023 ADC channels. If the sensitivity is low, then a change of 1 ADC channel (the minimum change we can see) might correspond to a large temperature change.

For this thermistor (using the nominal calibration constants from the data sheet) and a fixed resistor R2=10 Kohm (which is what I used in the photo above), the ADC values and the resolution — the number of degrees producing a change of 1 ADC channel — are as shown here. ADC values (in blue, read off the left vertical axis) range from 1 to 512 channels. The resolution (in red, read off the logarithmic right axis) is 0.09 degrees per channel at 25°C, but only 5 degrees per channel at –80°C!

That’s pretty pathetic. Clearly the thermistor resistance at low temperature is way too large compared to the fixed resistor.

So here are two other cases:

The darker colored points are for R2 = 33 Kohm, and the lighter ones are R3 = 1 Mohm. The ADC values are larger, and in fact for 1 Mohm they saturate near 1023 channels above about 0°C, but they do not saturate near 0 channels at the bottom of the temperature range. In fact they start at 124 channels, giving a very comfortable margin of safety. At the low end the resolution is better than 0.1 deg/chan. For 33 Kohm the resolution at high temperature is just slightly worse than befor, still around 0.1 deg/chan. The two resolutions cross at around –25°C.

What I take away from this is, if I haven’t overlooked some other problem (which is very possible!), a good way to operate would be to use two thermometers, one with a 33 Kohm resistor for temperatures above about –25°C and one with 1 Mohm for lower temperatures. The uLog can read three inputs, so we could in fact have three thermometers — two measuring the outside air, optimized for low and high temperatures, and the third measuring the temperature near the uLog as a check on how much (if at all) the insulation helps the electronics stay near its spec range. That one would be optimized for low temperatures too, of course.

Now, all of that assumes I’d be using the Vishay NTCLE100E3103JB0, and I don’t want to do that. It’s not specced for such low temperatures. I’d have to do a similar analysis for the thermistor I do end up using, but I haven’t yet found nominal calibration constants for the one I’m considering.

1. OK, I did overlook something: impedance requirements…

The output impedance of a voltage divider is R1||R2 (R1R2/(R1+R2)). From the ATtiny24 datasheet:

The ADC is optimized for analog signals with an output impedance of approximately 10kΩ or less. If such a source is used, the sampling time will be negligible. If a source with higher impedance is used, the sampling time will depend on how long time the source needs to charge the S/H capacitor, which can vary widely. With slowly varying signals the user is recommended to use sources with low impedance, only, since this minimizes the required charge transfer to the S/H capacitor.

(Similar remarks apply to the ATmega328, etc., typically used in Arduino boards.) So a voltage divider with a 1 Mohm (on that order) thermistor and a 1 Mohm fixed resistor will be way out of spec.

So I need to scrape up some of what I used to know, and/or some things I never did know, to learn how to present the voltage divider input to the uLog with a low output impedance. Either that or find some completely different solution.

• Buffer with a rail to rail op amp? Yet another part specced to only –40°C!

Or, wait, can I just use a 100 ohm thermistor? Except there aren’t many of those around, and then the low temp spec rears its ugly head again.

2. [...] about the temperature sensor? In our last episode I was doing calculations for thermistors. Two problems with them: most of them aren’t rated [...]