Jake Jake - 1 year ago 96
C Question

Better precision with Arduino (floats)

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

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
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.

Answer Source

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));
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download