复用多次的NTC B值计算代码,最近发现温度越高,读数偏差越大,相比实际温度要低很多。调查发现问题在于:
1. 本次使用的是100K NTC,然而10K NTC是没有问题的。
2. 本质上是Log函数的问题,将代码中近似计算lnx的函数改为库函数logx就能解决。
那这个近似计算lnx的函数问题在哪里呢?
double lnSelf1(double a)
{
int N = 15;//取了前15+1项来估算
int k,nk;
double x,xx,y;
x = (a-1)/(a+1);
xx = x*x;
nk = 2*N+1;
y = 1.0/nk;
for(k=N;k>0;k--)
{
nk = nk - 2;
y = 1.0/nk+xx*y;
}
return 2.0*x*y;
}
显然这也copy自网上某处代码,用这个近似也是为了降低对单片机性能的要求,通用性会更好。
该函数使用了如下公式:
又是泰勒公式!可知高数不好好学真是寸步难行……
Ln(x)的泰勒公式在x=1附近的展开,这与教材上的ln(1+x)的形式有所不同,简单的证明如下:
可得:
下边式子做一个变形
然后两式相加即可得证。
为什么计算10K NTC没问题,换到100K的就出现明显偏差?
看一下以上展开式的皮亚诺余项:
可知x无限大的时候,上式趋向与1,相比于ln(1+t)的展开中的O(t^n)来说已经小了非常多,但是精确度还不够。举个例子:
定性判断,此处没有精确计算偏差:
x=10以下的时候,展开为15项的误差一定小于0.00199,或许还可以接受,但是到了100时候,这个公式的估计能力严重下降。
即使展开项多到100项,误差比0.135小,这也是不行的。
实际上计算机去计算log就是用数学方法去逼近真实值,有一个常用算法就是利用泰勒展开,技巧性在于浮点数在计算机的存储格式可以提供计算所需参数 ,具体的参考其他资料。
参考资料:
计算机如何计算Log: