Steinhart-Hart reverse equation

Hello!

I want to calculate a resistance of a thermistor from a given temperature...
I want to use the Steinhart-Hart equation. I found a couple of pages that give the equations but i don't know how to program them in the IDE.

Can someone mathematically inclinde help me?

Thank you!

Tady:
I found a couple of pages that give the equations

And you thought "Screw them! I will not post a link!"?

We would like to help you but some effort from your side is needed. Links and where do you get stuck?

This is the usage below for a 10K NTC thermistor. I use it in this form for measuring aquarium temperature, and it is within 0.5 degree F.

  float CheckTemp()
 {
    int bits;
    float A = 0.00112531;                         //these values hold for 10K NTC thermistors
    float B = 0.000234712;
    float C = 0.0000000856635;
    float V, temp, Rt, TInv, ln;
  
    bits = analogRead(tempInPin);
    V = calFactor*VSupply*float(bits)/1023.0;    //voltage on analog pin at base of thermistor
    Rt = 10000.0*(VSupply - V)/V;                    //resistance of thermistor at current temp
    ln = log(Rt); 
    TInv = A + B*ln + C*pow(ln, 3); 
    temp = 1.8*(1.0/TInv - 273.15) + 32.0;       //temperature converted to Farhenheit
    return temp;
}

The only two variable above that are not intrinsically part of the equation are calFactor, which I adjust by experiment to get a best reading (due to errors in the voltage divider) and VSupply, which is an exact measurement of my power supply input, since I am using analogReference(DEFAULT)

Hope this helps.

1 Like

The ADC division factor should be 1024, not 1023.

Hi,
You asked;

I want to calculate a resistance of a thermistor from a given temperature...
I want to use the Steinhart-Hart equation. I found a couple of pages that give the equations but i don't know how to program them in the IDE.

Everybody else didn't read it properly.
You want to calculate the resistance given the temperature.
But you only have;

You need to google finding a solution by iteration

It involves getting a computer to do what it does best, continual repetitive calculations.

The basic process is using the function you have above;

  • Choose a value of R.
  • Calculate the value of T using the function.
  • Check if the value of the Calc T is higher or lower than the Desired T.
  • Adjust the value of R according to step 3.
  • Redo Step 2, 3, keep adjusting R to get closer Calc T to your Desired T.
  • The value of R that gets you a value of Calc T within acceptible limits of Desired T, will be your asnswer.

It sounds complicated but it is ideal for computer program solution.
(The first programs I was given as exercises in Basic and Fortran were iterative solutions to equations)

Tom... :slight_smile:

we know that a thermistor is half of a voltage divider, so we have a known fixed resistor.

so, we know the maximum value for the existing thermistor.
run (reverse) the calculation with the known T, find R

Hi,

I think what dave says, I think, is program the controller with the equation, and using known resistances in place of the thermistor, read what the function gives you in T.

You can then make a table of values, R vs T.

If you use a potentiometer and a DMM, you can adjust the pot for the temperature readout you need, like 20DegC or 100DegC, then remove the pot and measure that resistance.

Tom..... :slight_smile:
Good thinking dave...but I still won't open the podbay door...

TomGeorge:
Quote

I want to calculate a resistance of a thermistor from a given temperature...
I want to use the Steinhart-Hart equation. I found a couple of pages that give the equations but i don't know how to program them in the IDE.

Hi,
You asked;Everybody else didn't read it properly.

I just deleted a long post as I too got wrapped up in the steps and details about input accuracy and decimal places on calculations.....

I think we know that there are lots of sketchs that read the ADC from a thermistor and then output temperature.
what I think he is looking to do is to take a known temperature and re-write that forumla to calculate resistance.

but, if you use an Arduino with a thermistor on the ADC, and you have a known fixed resistor, you have a voltage. and it is much easier to do the math to calculate resistance of a voltage divider.

It is possible to solve the equation for R but it's quite a bit of algebra.
First let x = ln(R) and substitute into the original equation:
1/T = A + Bx + C(x^3)
and rearranging terms we have:
C(x^3) + Bx + (A - 1/T) = 0
This is a depressed cubic (x^2 term is absent) which can be solved for x and from there it is easy to obtain R = exp(x).
The tricky bit is the solution of the depressed cubic. I don't have the time or patience to solve this but the procedure is given on various webpages including these two:
http://www.sosmath.com/algebra/factor/fac11/fac11.html
http://2000clicks.com/mathhelp/FactoringCubic1.aspx

Pete

The ADC division factor should be 1024, not 1023.

Not so. The highest integer value that yu can get from analogRead is 1023. That represents full reference voltage. So suppose I have 5 volts reference, and a 5 volt input to my analog pin. Using 1024 would give me

voltage = 5volts*(bitsFromRead/1024) = 1023/1024 = 4.995.

1 Like

You need to google finding a solution by iteration

I don't understand this. You find the resistance from the voltage read from the analogRead input on the voltage divider comprising a 10K resistor to ground, and the thermistor. Once I have the voltage at that point, say V, all I need is to solve for the thermistor's resistance from the equation for a voltage divider, i.e.

R =10000* (VRef - V)/V.

Now you have R. What's to iterate? you plug it into the equation for 1/T, and, voila, out comes T. The software implementation I gave above is dead on and produces very accurate results.

jrdoner:
Not so. The highest integer value that yu can get from analogRead is 1023. That represents full reference voltage. So suppose I have 5 volts reference, and a 5 volt input to my analog pin. Using 1024 would give me

voltage = 5volts*(bitsFromRead/1024) = 1023/1024 = 4.995.

What about zero ?

There are 1023 intervals but 1024 values.

jrdoner:
Not so. The highest integer value that yu can get from analogRead is 1023. That represents full reference voltage. So suppose I have 5 volts reference, and a 5 volt input to my analog pin. Using 1024 would give me

voltage = 5volts*(bitsFromRead/1024) = 1023/1024 = 4.995.

I think that you will find that Dr Diettrich and Boardburner2 are correct.

Because you are not entirely conversant with working in binary, consider the following, working in the more familiar denary numbering system:

How do you calculate a percentage?
Do you divide by 99, the largest 2 digit number, (=(102-1)), or do you divide by 100 (= 102)?
The answer is obviously 100, so working in binary why do you want to divide by (210-1), when you should be dividing by (210 )?

The best way to see why it should be 1024 is to figure out what you would use with a much smaller ADC. For example if you are using an ADC with only 2 bits, instead of 10, it can produce only four values 0, 1, 2 or 3 which divides the input voltage into four equal pieces.
If you divide the count by 3 to get voltage, then those values are equal to 0, 1/3, 2/3, 1. But that is wrong because the difference between successive counts is 1/3, not 1/4, which is quite a large error.
Just because there are more bits in the Arduino ADC and the intervals are smaller, doesn't change the fact that the correct divider is 1024 so that the difference between successive counts is correct.

Pete

1 Like

TomGeorge:
(The first programs I was given as exercises in Basic and Fortran were iterative solutions to equations)

Tom... :slight_smile:

Oh yes.

My introduction was converting OS coordinates to lat long.
Did it on paper first longhand then spent a year with postal punchcards getting it right.

Turned out there were two methods, simplified which was less accurate.
And the proper method.

I was 'accidentally' given the complex one.

Let's take an ADC of 1000 steps (3 digits), for simplicity, and a 1000mV reference. Then the first step, numbered 0, will apply to anything from 0 to 1mV, step #1 to 1-2mV, and finally step #999 to 999-1000mV.

A step #1000 doesn't exist, like on a 10 bit ADC the highest step is #1023, not #1024.

An offset of 0.5mV; or AREF/1024/2; can be added, if one is more comfortable with the mean value of each interval.

Hi,

DrDiettrich:
Let's take an ADC of 1000 steps (3 digits), for simplicity, and a 1000mV reference. Then the first step, numbered 0, will apply to anything from 0 to 1mV, step #1 to 1-2mV, and finally step #999 to 999-1000mV.

A step #1000 doesn't exist, like on a 10 bit ADC the highest step is #1023, not #1024.

An offset of 0.5mV; or AREF/1024/2; can be added, if one is more comfortable with the mean value of each interval.

Exactly, what people do not realize is that there are 1024 STEPS, the FIRST STEP is numbered ZERO.
ZERO is a number, ZERO is a voltage level.
Tom.... :slight_smile:

There are 1023 intervals but 1024 values.

That's right, 1023 intervals. So suppose I have a fence with 1024 posts, labeled 0, 1, 2, ..., 1023, evenly spread out over a mile. If I start at the zero-th post and walk to post 1, I have covered the first of 1023 intervals. Proportionally, I am 1/1023rd of the way to the far end of the fence. When I at at the post numbered 1023, I have covered 1023/1023 of the mile.

Case closed.

jrdoner:
Case closed.

If you would set aside your childish pride for just a few seconds you could find the correct divisor in the datasheet.

I will give you a hint: it is not what you think it is.

TomGeorge:
Hi,Exactly, what people do not realize is that there are 1024 STEPS, the FIRST STEP is numbered ZERO.
ZERO is a number, ZERO is a voltage level.
Tom.... :slight_smile:

Something i am not sure of here is , does the first step mean zero or some undefined level which could be anything from less than .005 to minus 100 or so.

Similar argument at 1023.

Extreme example i know.