Jake - 1 month ago 7x
C Question

# Better precision with Arduino (floats)

I'm trying to do the Steinhart-Hart temperature calculation on an Arduino. The equation is

I solved a system of 3 equations to obtain the values of A, B and C, which are:

``````A = 0.0164872
B = -0.00158538
C = 3.3813e-6
``````

When I plug these into WolframAlpha to solve for
`T`
I get a value in Kelvins that makes sense:

`T=1/(0.0164872-0.00158538*log2(10000)+3.3813E-6*(log2(10000))^3) solve for T`

`T = 298.145 Kelvins = 77 Fahrenheit`

However when I try to use this equation on my Arduino, I get a very wrong answer, I suspect because doubles do not have enough precision. Here's what I'm using:

`double temp = (1 / (A + B*log(R_therm) + C*pow(log(R_therm),3)));`

This returns 222 Kelvin instead, which is way off.

So, how can I do a calculation like this in Arduino?? Any advice is greatly appreciated, thanks.

Precision is not the main issue. Could even use `float` and `powf()`. A thermistor temperature calculation is not that accurate. After all the temperature is certainly not better than ±0.1°C accurate. Self heating of the thermistor is a larger factor.

OP's C code assumes log base 2, use log base e `log()` as the constants were derived using log base 2. @Martin R

``````// double temp = (1 / (A + B*log(R_therm) + C*pow(log(R_therm),3)));
double temp = (1 / (A + B*log(R_therm)/log(2) + C*pow(log(R_therm)/log(2),3)));`
``````

Sample implementation, that avoids an unnecessary slow `pow()` call.

``````static const inv_ln2 = 1.4426950408889634073599246810019;
double ln2_R = log(R_therm)*inv_ln2;
double temp = 1.0 / (A + ln2_R*(B + C*ln2_R*ln2_R));
``````
Source (Stackoverflow)