Thermistor value using the Steinhart-Hart equation vs alpha value

Hi,
I'm still learning to use various components and today tried my hand at temperature reading with a thermistor (the ND03 220K here) and am using a sketch (below) based on AdaFruits' from here. I wanted to see how the approximative alpha value compared to the Steinhart-Hart calculation, but neither are giving reasonable answers. The Steinhart-Hart calc just gives -273 C, and the approx using the alpha seems to give delta-T a factor of ten too small.
What have I missed, misunderstood, and/or messed up?
Would be grateful for any help!
-A
PS Example of serial monitor printout below code

#define RES 10000
#define TPIN A0
#define BETA 4520
#define TNOM 25
#define RNOM 220000
#define ALPHA -5

void setup() {
  Serial.begin(9600);
}

void loop() {
 float reading;                                 //Read the thermistor value
 
 reading = analogRead(TPIN);
 
 Serial.print("raw reading: ");
 Serial.println(reading);
 
 reading=(1023/reading)-1.0;         //Turn raw reading into resistance value
 reading=RES/reading;
 
 Serial.print("Thermistor resistance: ");
 Serial.println(reading);
 
 float caT = reading;                       //calc approximate temperature using alpha value
 caT= TNOM+(reading-RNOM)/(reading*ALPHA);
 Serial.println(caT);
 Serial.println(" "); 

 float recalc;                                  //Calculate temperature using Steinhart-Hart eqn
 recalc = reading / RNOM;
 recalc=log(recalc);
 recalc/=BETA;
 recalc+=1.0/(TNOM + 273.16);
 recalc-=273.15;
 
 Serial.print("Real temp: ");
 Serial.println(recalc);
 Serial.println(" ");
 
 
 delay(1000);
}

SERIAL MONITOR

raw reading: 982.00
Thermistor resistance: 239512.32
24.98

Real temp: -273.15

raw reading: 981.00
Thermistor resistance: 233571.62
24.99

Real temp: -273.15

raw reading: 981.00
Thermistor resistance: 233571.62
24.99

Real temp: -273.15

moderator: added [code] ... [/code] tags

PS When I hold the thermisor the resistance value drops to about 143000 ohm, and the caT reads 25.11 whereas a commercial thermocouple reads 32 C.

The impedance of your thermistor circuit is probably too high.

How did you derive the Steinhart-Hart equations? The one I've seen requires three constants, A,B,C.
In any case, the equation you are using can't produce realistic values.
It is equivalent to this:

recalc = log(981./220000)/4520 + 1/(25+273.16) - 273.15;

where 981 is the input value. Dividing the input number by 220000 is always going to produce a fraction. The log of that is going to be a negative number (on the order of -5) which you then divide by 4520 to produce a small negative fraction. This fraction and the one produced by the term "1/(25+273.16)" aren't going to change the result significantly from -273.15

Pete

Hi guys,
Thanks for the suggestions, but 1) I've never heard of impedence matching for thermistors. Surely it's just a variable resistor?!

and 2) it's not the actual Steinhart-Hart eqn, you're right, I was sloppy calling it that. As noted on adafruit's example page A, B, and C aren't known so I can't use that, and I'm using their simplified beta-value eqn.

Looking through it though with fresh eyes I see I've missed a step in the calculation and should ivert the value. I don't have the bits set up to test now but I'm sure that must be it!

The beta equation will have a lot more error than the Steinhart-Hart approximation.

The usual approach is to measure the temperature and resistance at three points, with the first being at the bottom of the temperature range you are interested in, the second at the mid point and the third at the top of the range of interest. The wider the range the less accurate the approximation so it helps to narrow it down.

If you can't actually make measurements you can still use Steinhart-Hart by choosing values from the thermistor R/T table provided by the manufacturer. That will get you pretty close to the tolerance of the thermistor.

Doing logarithms on an Arduino sounds slow. Another approach might be to incorporate part of the R/T table into your code and interpolate.

How are you connecting the thermistor to the Arduino, with a simple voltage divider circuit? I don't know what the best method is but I would expect you'd lose precision connecting it that way.

When you're reading a temperature once a second (and usually a lot less frequently), the time taken to calculate the logarithm is negligible.
I timed this statement:

T = 1/T0+log(reading/R0)/BETA;

and it takes about 180 microseconds.

Pete

Thanks, that's good to know.

I looked up the R/T values for this thermistor.

I don't know what you're trying to do with this statement, it doesn't follow the R/T curve at all:

caT= TNOM+(reading-RNOM)/(reading*ALPHA);

Selecting the points at 10, 25 and 40°C from the R/T table for this thermistor I got the following Steinhart-Hart coefficients:

A = 9.176 * 10^-4
B = 1.824 * 10^-4
C = 1.032 * 10^-7

Plugging in the A/D value of 982 I calculated a temperature via Steinhart-Hart of 23.3°C. If I'm reading it right there is a 5% tolerance for this sensor which means roughly ±1°C. I could be wrong.

The thing is, a change in the A/D output of 1 bit changes the temperature by 0.5°C. The useful range of the A/D is narrow when using a voltage divider. What's the better way to connect a thermistor? Anybody know?

Thanks, but I can't read temperatures across the range I need, but where did you find the table with R/T values? that would be useful!

jboyton: I think you're precision-ambition is rather greater than mine :wink: I just want to use the thermistor with a couple of thermocouples and a relay to keep my slow cooker at 37~44degC. The temp-variation edge-middle of the pot will be much greater than 0.5degC!

also, the ca temp with the alpha value assumes linear variation, which as you point out, the R/T curve is not, it's just an approximation and rather inaccurate even across a limited range.

The R/T data I found on the AVX web site. Product information -> disc thermistors -> tables ->
http://avx.com/docs/Catalogs/ntc-resist.pdf

Even though you don't need high precision you might as well choose the optimal approach, assuming it isn't expensive or difficult to implement.

Here's the R/T curve for your thermistor for the range of 10-60°C:

When you use a voltage divider (5V -- Thermistor -- Analog Input -- Fixed Resistor -- Ground), the non-linearity of the divider comes close to canceling out the non-linearity of the thermistor. But the choice of the fixed resistor affects the change in voltage per change in temperature. Here's a graph of the A/D output vs. temperature for different fixed resistors:

You can see that 10K is a rather poor choice for a thermistor that is 220K at 25°C.

One thing that I don't understand is the effect of the total resistance on how the A/D works. I believe that as the resistance grows there is a larger error introduced. I think this is the source of Ken's comment about the impedance. Maybe the error is too small to matter for your purposes, but I really don't know.

Thanks for the T/R table!

I don't see why a linear A/D input is a problem? surely this just makes it easier? from your A/D graph I could get quite a good linear approximation of the 100k curve with
AD=962.165-10.811*T
and get to within a degree or so of the correct T.

and why is "100k rather a poor choice"? the 100k curve has a greater slope than the 10k and 50k, only the 200k has greater, and a higher dV/dT would imply greater accuracy? no?

You misread my post. I wrote that 10K is a poor choice.

The way that Adafruit describes doing the A/D --> Temperature calculation doesn't take advantage of the near linearity of the final result. Especially over narrower temperature ranges you can do what you're describing and make it much easier.

I'd choose as narrow a temperature range as I thought was practical (or use several linear approximations, one for each range) and turn the formula around:

10K resistor: T(°C) = -0.267 * AtoD + 288.3
100K resistor: T(°C) = -0.0886 * AtoD + 87.28

I used Excel and a 25-55°C temperature range to get these equations. The 100K line varies by about 1°C from your approximation.

Your fixed resistor is how accurate? 10%? And the thermistor is only good to 5% without calibration. On top of that is the possible issue of the total impedance affecting the A/D by some amount. Why exactly did you choose a 220K resistor instead of one with a lower nominal resistance?

In any case, I think it would be wise to find a thermometer of some reliability, something you trust, to do a rough calibration. For about $15 you can buy a digital kitchen thermometer that will probably be accurate to 1°C.

According to the ATmega328 data sheet, the ADC is optimized for an input resistance (or source impedance) of 10K ohms or less.

For a voltage divider, the source resistance is equivalent to the parallel combination of the two resistors, or R1*R2/(R1 + R2). With a thermistor, the best choice for the fixed resistor is equal to the resistance value of the thermistor at the center of the temperature range of interest.

So if your thermistor is 220K (at for example room temperature), then a 220K resistor will be optimal for the other resistor of the divider. However, that means the total source resistance of 110K is too high for the ADC. To solve that problem you can add a small capacitor, say 1 to 10 nF, from the ADC input to ground.

jremington:
So if your thermistor is 220K (at for example room temperature), then a 220K resistor will be optimal for the other resistor of the divider. However, that means the total source resistance of 110K is too high for the ADC. To solve that problem you can add a small capacitor, say 1 to 10 nF, from the ADC input to ground.

So the capacitor provides the charge that wouldn't otherwise be available. How do you calculate the capacitor value? And what negative effect does adding the capacitor include -- reduced sample frequency?

In lieu of an added capacitor, would it work to switch the A/D multiplexor and give it time (how much time?) to charge before performing the conversion?

The ATmega data sheet is not at all clear on what to do about high source impedance, as follows:

The ADC is optimized for analog signals with an output impedance of approximately 10 kΩ 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, with can vary widely. The user is recommended to only use low impedance
sources with slowly varying signals, since this minimizes the required charge transfer to the S/H
capacitor.

Adding an external capacitor does work. However, it does strongly affect the upper sample frequency limit, as it introduces a low pass filter with a knee frequency of 1/(2PIR*C) where R is the source impedance. That frequency can be your guide to choosing C.

A simple op amp might do the trick

opamp.JPG

A software solution or just a capacitor would be simpler, assuming it works acceptably in this application.

Maybe simpler still is to buy a 10K thermistor for a few bucks.

thanks guys for going into my set-up so thoroughly, and sorry for the slow reply (holidays, travel, work...)
I see why a 10k resistor is not great but got lost when capacitors and imedance entered the conversation. I'll get back to you when I've done my homework and calibrated it against one of our labs' TCs. However, as it stands now it seems to give perfectly reasonable readings.

Alexi:
as it stands now it seems to give perfectly reasonable readings.

If it aint broke don't fix it :slight_smile: