C 使用Arduino(浮动)可提高精度

C 使用Arduino(浮动)可提高精度,c,floating-point,precision,arduino-uno,temperature,C,Floating Point,Precision,Arduino Uno,Temperature,我想在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*log210000+3.3813E-6*log210000^3求解T T=298.145开尔文=77华氏度 然而,当我试图在我的Arduin

我想在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*log210000+3.3813E-6*log210000^3求解T

T=298.145开尔文=77华氏度

然而,当我试图在我的Arduino上使用这个方程时,我得到了一个非常错误的答案,我怀疑是因为双打不够精确。以下是我正在使用的:

双温度=1/A+B*对数热+C*功率对数热,3

这将返回222开尔文,这是一个很大的差距


那么,我怎样才能在Arduino进行这样的计算呢??非常感谢您的建议,谢谢

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

你考虑过使用固定精度吗?如果使用正确,这可能会给您带来更好的结果。但是,这样做的要求是要有相当窄的参数,并且要注意单位转换

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

您还需要保留每个变量包含的小数位数的心智模型或纸质模型,以便优化操作顺序,以免丢失精度


对于log2函数,我怀疑它是否适用于整数。你可以决定结果,也可以选择。这个问题有很多资源,即使在这里也是如此。

精度不是主要问题。甚至可以使用float和powf。热敏电阻温度的计算不是那么准确。毕竟,这里的温度肯定不比这里好。热敏电阻的自加热是一个更大的因素

OP的C代码假设log base 2,使用log base e log,因为常量是使用log base 2导出的

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


log2表示以2为底的对数,log表示自然对数或以e为底的对数。这可能已经解释了差异。另外,C=000003.3813和3.3813E-6不是同一个数字。是的,这里ln可能指尼泊尔对数,即lnx=log2x/log2 exp1 logR_therm->logR_therm/log2@MayeulCln总是指自然尼伯对数。在C语言中,它被称为logI,它会说浮点运算不仅在大多数Arduinos上精度有限,而且在所有Arduinos上精度有限,在所有其他计算机上也是如此…@ThomasPadron McCarthy:如果你想挑剔的话,每个数字表示在某一点上精度有限。但是基于avr的arduinos只有4字节的浮点数。没有双重精度。例如,Due具有双精度浮点数。但这可能是这里的问题。
// 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)));`
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));