Arduino(浮点数)精度更高

Better precision with Arduino (floats)

我正在尝试在 Arduino 上进行 Steinhart-Hart 温度计算。等式是

我求解了 3 个方程组以获得 A、B 和 C 的值,它们是:

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

当我将这些插入 WolframAlpha 以求解 T 时,我得到了一个有意义的开尔文值:

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

取而代之的是 returns 222 开尔文,这太离谱了。

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

是的,浮点运算在大多数 arduino 上的精度有限。

您是否考虑过使用固定精度?如果使用得当,这可能会给您带来更好的效果。然而,这样做的要求是具有相当窄的参数,并注意单位转换。

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

您还需要保留每个变量包含的小数位数的(心理或纸上)模型,以便优化运算顺序而不丢失精度。

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

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

OP 的 C 代码假定对数基数为 2,使用对数基数 e log() 因为常量是使用对数基数 2 导出的。

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