使用Arduino(浮子)提高精度

时间:2016-09-23 05:34:07

标签: c floating-point precision arduino-uno temperature

我试图在Arduino上进行Steinhart-Hart温度计算。等式为enter image description here

我解决了3个方程的系统,得到A,B和C的值,它们是:

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

当我将这些插入WolframAlpha以解决T时,我在Kelvins中得到一个有意义的值:

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

T = 298.145 Kelvins = 77 Fahrenheit

然而,当我尝试在我的Arduino上使用这个等式时,我得到一个非常错误的答案,我怀疑因为双精度没有足够的精度。以下是我正在使用的内容:

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

这样就会返回222 Kelvin,这是关闭的。

那么,我怎样才能在Arduino中进行这样的计算?非常感谢任何建议,谢谢。

2 个答案:

答案 0 :(得分:3)

精确度不是主要问题。甚至可以使用floatpowf()。热敏电阻温度计算不 准确。毕竟温度肯定不比±0.1°C accurate好。热敏电阻的自加热是一个更大的因素。

OP的C代码假定日志库2,使用日志库 e log(),因为常量是使用日志库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)));`

示例实现,避免了不必要的慢pow()调用。

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));

答案 1 :(得分:1)

是的,浮点运算对大多数arduinos的精度有限。

您是否考虑使用固定精度?如果使用正确,这可能会给您带来更好的结果。然而,对此的要求是具有相当窄的参数,并且要小心单位转换。

arduino上的unsigned long也是4个字节,因此它可以包含最多2^32-1的数字。如果使用固定点,您可能希望将此1/T替换为100000/T,其中分子常量和T已根据所需精度进行缩放。

您还需要保留每个变量包含的小数位数的(精神或纸质)模型,以便优化操作顺序而不会丢失精度。

对于log2函数,我怀疑它是否可用于整数的开箱即用。您可以投射结果或reimplement it。这个问题有很多资源,即使是在SO上也是如此。