ADC采集噪声问题及均方根值滤波与Kalman滤波比较

时间:2024-03-25 15:47:03

    有一阵子笔者在做一个PT100热电阻的调理电路的时候采用了,使用恒流源的方式测热电阻的阻值。为了采集方便,将0.3mA的电流接入PT100直接把ADC输入端接在了PT100的两端。之后再输出温度的时候数据非常乱。查阅资料受到启发,采用求该信号的有效值(均方根值)方法进行滤波。

  • ADC采样、恒流源

    ADC使用的是STM32F10x系列的内部12位ADC。恒流源电流值为0.3mA。

  • PT100热电阻

    PT100是在零度下,阻值为100Ω的热电阻,其温度特性曲线如图1

ADC采集噪声问题及均方根值滤波与Kalman滤波比较

图1:PT100温度特性曲线

    基本上在-200—600摄氏度之间温度与电阻是线性关系。故测量PT100电阻值的其中一种办法就是给PT100接入一个恒流源,然后测其两端电压进而求出PT100电阻值。

  • 噪声分析

    电路上电(电源采用的是两节18650串联,AMS1115-3.3V降压稳压)将热电阻两端接入示波器(输入阻抗1MΩ)如图2。Single一下,然后将界面的所有采样数据做FFT(快速傅里叶变换)得到图3、图4.不难看出噪声主要来自于1Mhz的频段和一些高斯白噪声。

ADC采集噪声问题及均方根值滤波与Kalman滤波比较

                                                                                    图2:原始信号

ADC采集噪声问题及均方根值滤波与Kalman滤波比较

                                                                                         图3:FFT

ADC采集噪声问题及均方根值滤波与Kalman滤波比较

                                                                                           图4:FFT

 

  • 均方根值去除噪声

                                                                          ADC采集噪声问题及均方根值滤波与Kalman滤波比较

    求一段信号的均方根值其实就是求这段信号的的有效值(RMS)即信号平方的均值再开方。ADC采样频率为10Khz。每次取100个数据进行计算。计算后数据由串口输出,见图:6、图7.(C代码见程序1)

ADC采集噪声问题及均方根值滤波与Kalman滤波比较

                                                                                  图5:串口输出原始数据

ADC采集噪声问题及均方根值滤波与Kalman滤波比较

                                                                                    图6:滤波数据

ADC采集噪声问题及均方根值滤波与Kalman滤波比较

                                                                              图7:给PT100加温度

  • 一阶低通滤波器

                                                                        y(n) = q*x(n) + (1-q)*y(n-1)

    中Y(n)为输出,x(n)为输入。其中Q取0.5输入波形见图8.(C代码见程序2)

ADC采集噪声问题及均方根值滤波与Kalman滤波比较

                                                                       图8:加入一阶低通滤波串口输出

 

  • kalman滤波

    第一步将数据导入MATLAB,画出原始数据曲线。见图9.。将数据做卡尔曼滤波观测矩阵。将该数据的t-2到t时刻的均值作为推测矩阵(详细见附加代码)。最后将卡尔曼输出做滑动平均。卡尔曼输出模型(蓝色)见图10.(matlab代码见程序3)

ADC采集噪声问题及均方根值滤波与Kalman滤波比较

                                                                             图9:MATLAB导入原始数据

ADC采集噪声问题及均方根值滤波与Kalman滤波比较

                                                                           图10:原始数据与滤波后的数据

  • 总结:

    噪声的产生有很大一部分原因应该是在画电路板的时候没有把数字地和模拟地分开造成的。Kalman滤波算法是一种基于时域的滤波算法。笔者认为该电路中的高斯白噪声主要来源于电源和数字信号对模拟信号的干扰。就本电路而言求信号的均方根值是比较有效的办法。笔者学识有限,如有错误的地方欢迎指正。

 

  • 程序1

unsigned int disposePT100v()
{
	unsigned char i;
	double dData[100];
	double dSum;
	for(i=0;i<100;i++)
	{
		dData[i] = g_iADC[0];//获取ADC数据
		dSum +=pow(dData[i],2);//做平方和
		delay_us(100);
	}
	dSum /= 100;//求均值
	dSum = sqrt(dSum);//开方
	return (unsigned int)dSum*3300/4096;//mv电压值
}
  • 程序2

unsigned int lowV(unsigned int com)
{
	static unsigned int iLastData;
	unsigned int iData;
	double dPower=0.5;
	iData = (com*dPower)+(1-dPower)*iLastData;//计算
	iLastData = iData;//jilu 
	return iData;//返回数据
}
  • 程序3

clear
clc
ydata=textread('a123.txt','%s');%%导入数据
cData = hex2dec(ydata);%转换为10进制数据

%t-1时刻的输出作为本次时刻的系统推测数值  最优偏差(初值)g_zer  推测误差(初值)g_ter  测量值偏差(初值)g_cer
%测量结果(矩阵) ner1   推测结果(矩阵)ner2  (end)
g_zer = 5;%%最优偏差初值
g_ter = 3;%%推测偏差初值
g_cer = 2;%%测量偏差初值
kdata = 0;
for i=1:5792%%迭代5000次
    ner1 = cData(i);
    if i>3
        ner2 = (cData(i-2)+cData(i-1)+cData(i))/3;%%t-2时刻到t时刻的平均值作为t时刻的推测值
    else
        ner2 = kdata;
    end
    if g_zer>g_ter
    g_er = sqrt((g_zer^2)-(g_ter^2));%计算本次误差
    else
    g_er = sqrt((g_ter^2)-(g_zer^2));%计算本次误差
    end
    kk = sqrt((g_er^2)/((g_er^2)+(g_cer^2)));%计算卡尔曼增益
    kdata = ner1+kk*(ner2-ner1);%更新卡尔曼输出
    g_zer = ((1-kk)*g_ter^2)^0.5;%计算本次最优偏差
    cKdata(i) = kdata;
end
%%%%%%%滑动平均%%%%%%%%%%
t = 1:5792;
a = 0;
b = 0;
pKdata = zeros(1,5792);
for i=1:5700
    for j=1:50
        a = a + cKdata(i+j);
    end
    b = a/50;%%求平均
    a = 0;
    pKdata(i)=b;
end
plot(t,cData,'R',t,cKdata,'G',t,pKdata,'B');