Gogo:Tronics - Parts and Supplies For Electronic Enthusiasts
Your Cart

Gogo:Tronics

NTC Thermistors and You - Converting an ADC (analogRead) value into a Temperature

Presented here is a spreadsheet to help you generate (C) code for easily converting an ADC (Analog to Digital Converter) value, as for example returned by the analogRead() function of Arduino, into a temperature in °C.

When you give it just a few simple parameters it will produce:

  1. A table listing temperature, resistance and the ADC (analogRead) result for a range of values determined by you.
  2. Three C (language) functions for converting an ADC result into a temperature in °C, suitable for Arduino use
    1. A "standard" Beta approximation producing good results across the whole range
    2. A floating point linear approximation producing good results across a narrower (configurable) range
    3. An integer-only linear approximation producing reasonable results across a narrower (configurable) range
  3. Charts showing the relative error-margin for the three different C functions to help you tune your values
  4. Wiring "diagram" is included in the comments of the generated C (language) code

Additionally it incorporates the following helpful functions:

  1. If you don't know, or wish to calibrate yourself, the Beta value of your thermistor, it can calculate it from just one measurement (measure the resistance at a known temperature)
  2. It can select an appropriate value for the paired resistor in the wiring for you to minimise the errors
  3. The ability to test your settings by converting a measured temperature into a resistance which you can check with your multimeter.


The spreadsheet is in Google Docs, create your own copy here to use the NTC spreadsheet.


Comments/Feedback/Discussion/Help 

Head over to this Reddit thread and have at it.

https://www.reddit.com/r/electronics/comments/3z8rpq/ntc_thermistors_and_you_converting_an_adc/


Some brief screenshots and instructions (there's lots of info in the spreadsheet)

When you open the spreadsheet you will see the settings on the right side of the sheet (horizontal scroll across if you don't see them!), note that there are lots of comments there in the green next to the settings, and if you scroll even further right there is even more information in blue.

The settings you will most likely want to adjust are "Beta Value To Use", "Nominal Resistance", Low °C and High °C. The Beta Value and Nominal Resistance you obtain from your thermistor's datasheet or vendor, the Low and High °C are your choice and help the calculations provide results that are of good accuracy in the range you particularly are interested in.

If you don't know the Beta value, or want to re-calibrate it yourself, simply type =O7 into the "Beta Value To Use" field, and then enter a Measured Resistance and Measured Temperature (usually done at 50°C), the Beta will be computed then.

Charts are shown below the settings to give you an idea of the error-margins for the three methods.

This is a screenshot, not an interactive chart, use the spreadsheet for interacting! ;

A table is generated on the left of the spreadsheet from the settings you provide.

C (language) code is produced from your settings, simply right-click the cell, select copy and then paste into your program (or sketch), make sure to delete the extraneous quote mark in your program after pasting, as is noted in the comment :-)

Theory of Operation, Credits Go To

This stuff is extra learning for those who are interested (nobody), and really just notes for myself when I come back to look at this in a couple years and forgot how it all works, You don't need to know any of this to use the spreadsheet or generated C (language) code.


The formula for calculating (closely approximating) temperature to/from a resistance is a well known equation…

https://en.wikipedia.org/wiki/Thermistor#B_or_.CE.B2_parameter_equation

Where T is temperature, B is Beta, To is nominal temperature and Ro is nominal resistance, temperatures are in Kelvin (K = C + 273.15)

Beta is usually a value provided in the NTC datasheet or by the NTC vendor, but in some case you might not know the Beta (reliably) and want to calculate it, we can rewrite the above formula to solve for B when it is unknown and we measure a specific resistance (R) at a specific known temperature (T) (in addition to the nominal To (nominal temperature, usually 25°C) and Ro (resistance of thermistor at that temperature, eg 10000 for a 10k thermistor). Note that usually the measurement for R and T is taken at 50°C, but you can do so at a different point if you like, it just affects the Beta value result slightly.

1/T = 1/To + 1/B * ln(R/Ro)

1/T - 1/To = 1/B * ln(R/Ro)

(1/T - 1/To) / ln(R/Ro) = 1/B

1/ (1/T - 1/To) / ln(R/Ro)) = B

You can see this implemented in cell O7

Once we have a Beta (given or calculated) then we again use this equation, this time solved for "R" the resistance of the thermistor given a known temperature in cell O25 of the spreadsheet (and in the resistance columns of the table), the algebraic manipulation being…

1/T = 1/To + 1/B * ln(R/Ro)

1/T = 1/B * ln(R/Ro) + 1/To    [ Rearrange for clarity ]

1/T – 1/To = 1/B * ln(R/Ro) 

1/T – 1/To = ln(R/Ro) / B        [ 1/B * N == N / B ]

B * (1/T – 1/To) = ln(R/Ro) 

exp(B * (1/T – 1/To)) = R/Ro   [ exp is inverse of natural log ]

Ro * exp(B * (1/T – 1/To)) = R

[ 2017-06-08 : there was an error in the working for the notes above and these have been corrected, the spreadsheet was correct ] 

Going from a calculated resistance to an ADC result is pretty straight forward (if you know the max adc result, and you know both resistances (resistor and thermistor) and know know which order they are in (resistor-thermistor or thermistor-resistor) then you know the ratio between them and get the ADC result, no need to care about what the voltage/current is), this is my own concoction…

[for Thermistor connected to Gnd ] adcVal = Rth /( Rother + Rth ) * adcMax

[for Thermistor connected to Vcc ] adcVal = adcMax - ( Rth /( Rother + Rth ) * adcMax )

For which you can see the implementation in the ADC Result cells of the results table, note that the values are rounded in implementation, because that’s how an ADC works.  

So at this point we have formulae to get us from known temperature to resistance to ADC value, but in practice we need to go the opposite direction.

Reversing the adc equations to solve for resistance with a known adcVal required the help of Wolfram Alpha's solve-for-x ability with the following equivalent equation (because my algebra was too rusty for this…)

[for Thermistor connected to Gnd ] solve for x, v = ((( x )/( u + ( x )) * m ))

[for Thermistor connected to Vcc ] solve for x, v = m - ((( x )/( u + ( x )) * m ))

which Wolframp Alpha helpfully solved to

[for Thermistor connected to Gnd ] x = (uv) / (m-v)

[for Thermistor connected to Vcc ] x = (u (m - v ) ) / v

which more readibly is

[for Thermistor connected to Gnd ] Rth = ((Rother * adcVal) / (adcMax - adcVal))

[for Thermistor connected to Vcc ] Rth = ((Rother * (adcMax - adcVal)) / adcVal)

So now if we have an adcVal we can get a resistance, and we have the same standard beta-approximation-of-temperature equation above

which we can rewrite once again to solve for T (and rename some variables for clarity) to

T = 1/((1/Tnominal) + ln(Rth/Rnominal)/B)

Where: T = Temperature (K), Tnominal = Nominal Temperature, Rth = Thermistor Resistance, Rnominal = Nominal Resistance, B = Beta

and insert our Rth equation that Wolfram Alpha made for us to bring us to

[for Thermistor connected to Gnd ] T = 1/((1/Tnominal) + ln( ((Rother * adcVal) / (adcMax - adcVal))/Rnominal)/B)
[for Thermistor connected to Vcc ] T = 1/((1/Tnominal) + ln(((Rother * (adcMax - adcVal)) / adcVal)/Rnominal)/B)

note these temperatures are in Kelvin, in the spreadsheet and code we convert to/from C in these equations by adding/subtracting 273.15 as appropriate.

Those last two formulae are the crux of converting from an ADC result (analogRead) into a temperature, you'll see you need to know the nominal resistance (eg, 10k thermistor), the nominal temperature (at which the thermistor has that nominal resistance, usually 25 degrees C), the size of the "other" resistor the thermistor is connected in series with, the maximum adc value (adcMax) possible (1023 for a 10bit adc for example), the adc result (adcVal) you want to convert, and the beta value. All the values can be hard coded except for the adc result.

However due the need to use log functions, floating point, division and so forth with that, which might not be possible on a small microcontroller, linear approximations are also calculated. This is done by creating a list (A55:C155) of temperature and calculated ADC value pairs, then using the "SLOPE" and "INTERCEPT" spreadsheet functions to create those two values which can be used in the formula shown in cell N:O33 - with thanks to RHETT ALLAIN from Wired.Com this remarkably closely approximates the "proper" beta-approximation (approximation of an approximation of an approximation…)

That however still requires floating point operations and just truncating them into integer operations wouldn't work at all, so the formula for the float approximation is adjusted to use only pre-calculated integer values, a multiplier factor is included which has the tendency to influence the error margin of the integer approximation in useful ways, this was a happy accidental discovery :-).

This formula is displayed in N:O39. It is then applied to all the ADC Values C55:C155 with results in the cells K55:K155, from this we calculate the error for each result in N:55:N155. This error is averaged in V53, it is preferable that this average is zero, indicating that the errors are evenly distributed above and below the "no-error" line, if there are sufficiently more positive errors than negative errors, or vice-versa, then this value in V53 will be non-zero (it's rounded, this is an integer approximation remember). To counteract such imbalance this imbalance is subtracted, which you can see in the last term of the formula in N:O39, this has the effect of shifting the approximation and reducing the error (significantly) when there is imbalance.

The charts are produced from the various data in the calculations found in rows 53 onwards.

The  “Other Resistor” suggestions for 1% and 5% are made possible from the spreadsheet formulae found at

http://electronicdesign.com/components/excel-formula-calculates-standard-1-resistor-values

which convert a given value into the closest E96/48/24 series resistor.