1、限制过滤法(又称程序判断过滤法)
/* A、名称:限幅滤波法(又称程序判断滤波法) B、方法: 根据经验判断,确定两次采样允许的最大偏差值(设为A), 每次检测到新值时判断: 如果本次值与上次值之差<=A,则本次值有效, 如果本次值与上次值之差>A,则本次值无效,放弃本次值,用上次值代替本次值。 C、优点: 能有效克服因偶然因素引起的脉冲干扰。 D、缺点: 无法抑制那种周期性的干扰。 平滑度差。 E、整理:shenhaiyu 2013-11-01 */intFilter _ ValueintValue
void setup(){ Serial . begin(9600);//初始化串行通信randomSeed(analog read(0));//生成随机种子值= 300;}
void loop(){ Filter _ Value = Filter;//获取过滤器输出值Value = Filter _ Value//最后一次有效采样的值,全局变量serial . println(Filter _ Value);//串行输出延迟(50);}
//用于随机生成一个300左右的当前值intget _ ad () {return random (295,305);}
//限制筛选法(也叫程序判断筛选法)# definefilter _ a1intfilter(){ intnewvalue;NewValue = Get _ AD如果(((新值-值)>;FILTER_A) || ((Value - NewValue)>;FILTER_A))返回值;elsereturnNewValue}
2.中值滤波方法
/*A、名称:中位值滤波法B、方法:连续采样N次(N取奇数),把N次采样值按大小排列,取中间值为本次有效值。C、优点:能有效克服因偶然因素引起的波动干扰;对温度、液位的变化缓慢的被测参数有良好的滤波效果。D、缺点:对流量、速度等快速变化的参数不宜。E、整理:shenhaiyu 2013-11-01*/intFilter _ Value
void setup(){ Serial . begin(9600);//初始化串行通信randomSeed(analog read(0));//生成随机种子}
void loop(){ Filter _ Value = Filter;//获取过滤器输出值serial . println(Filter _ Value);//串行输出延迟(50);}
//用于随机生成一个300左右的当前值intget _ ad () {return random (295,305);}
//中值滤波方法# define filter _ n 101 intfilter(){ int filter _ buf[filter _ n];inti,j;intfilter _ tempfor(I = 0;i <。FILTER _ N;i++){ filter _ buf[I]= Get _ AD;延迟(1);}//对于(j = 0)采样值从小到大排列(冒泡法);j <。FILTER _ N-1;j++){ for(I = 0;i <。FILTER _ N-1-j;i++) {if(filter_buf[i]>filter _ buf[I+1]){ filter _ temp = filter _ buf[I];filter _ buf[I]= filter _ buf[I+1];filter _ buf[I+1]= filter _ temp;} } } returnFIlter _ buf[(FILTER _ N-1)/2];}
3.算术平均滤波法
/*A、名称:算术平均滤波法B、方法:连续取N个采样值进行算术平均运算:N值较大时:信号平滑度较高,但灵敏度较低;N值较小时:信号平滑度较低,但灵敏度较高;N值的选取:一般流量,N=12;压力:N=4。C、优点:适用于对一般具有随机干扰的信号进行滤波;这种信号的特点是有一个平均值,信号在某一数值范围附近上下波动。D、缺点:对于测量速度较慢或要求数据计算速度较快的实时控制不适用;比较浪费RAM。E、整理:shenhaiyu 2013-11-01*/intFilter _ Value
void setup(){ Serial . begin(9600);//初始化串行通信randomSeed(analog read(0));//生成随机种子}
void loop(){ Filter _ Value = Filter;//获取过滤器输出值serial . println(Filter _ Value);//串行输出延迟(50);}
//用于随机生成一个300左右的当前值intget _ ad () {return random (295,305);}
//算术平均滤波法# define filter _ n12 intfilter(){ inti;int filter _ sum = 0;for(I = 0;i <。FILTER _ N;i++){ filter _ sum+= Get _ AD;延迟(1);} return(int)(FIlter _ sum/FILTER _ N);}
4.递归平均滤波法(也称移动平均滤波法)
/*A、名称:递推平均滤波法(又称滑动平均滤波法)B、方法:把连续取得的N个采样值看成一个队列,队列的长度固定为N,每次采样到一个新数据放入队尾,并扔掉原来队首的一次数据(先进先出原则),把队列中的N个数据进行算术平均运算,获得新的滤波结果。N值的选取:流量,N=12;压力,N=4;液面,N=4-12;温度,N=1-4。C、优点:对周期性干扰有良好的抑制作用,平滑度高;适用于高频振荡的系统。D、缺点:灵敏度低,对偶然出现的脉冲性干扰的抑制作用较差;不易消除由于脉冲干扰所引起的采样值偏差;不适用于脉冲干扰比较严重的场合;比较浪费RAM。E、整理:shenhaiyu 2013-11-01*/intFilter _ Value
void setup(){ Serial . begin(9600);//初始化串行通信randomSeed(analog read(0));//生成随机种子}
void loop(){ Filter _ Value = Filter;//获取过滤器输出值serial . println(Filter _ Value);//串行输出延迟(50);}
//用于随机生成一个300左右的当前值intget _ ad () {return random (295,305);}
//递归平均滤波法(也叫移动平均滤波法)# define filter _ n ^ 12 int filter _ buf[filter _ n+1];int filter(){ inti;int filter _ sum = 0;FILTER _ buf[FILTER _ N]= Get _ AD;for(I = 0;i <。FILTER _ N;i++){ filter _ buf[I]= filter _ buf[I+1];//所有数据左移,低位仍然被filter_sum += filter_buf[i]丢弃;} return(int)(FIlter _ sum/FILTER _ N);}
5、中值平均滤波法(又称抗脉冲干扰平均滤波法)
/*A、名称:中位值平均滤波法(又称防脉冲干扰平均滤波法)B、方法:采一组队列去掉最大值和最小值后取平均值,相当于“中位值滤波法”+“算术平均滤波法”。连续采样N个数据,去掉一个最大值和一个最小值,然后计算N-2个数据的算术平均值。N值的选取:3-14。C、优点:融合了“中位值滤波法”+“算术平均滤波法”两种滤波法的优点。对于偶然出现的脉冲性干扰,可消除由其所引起的采样值偏差。对周期干扰有良好的抑制作用。平滑度高,适于高频振荡的系统。D、缺点:计算速度较慢,和算术平均滤波法一样。比较浪费RAM。E、整理:shenhaiyu 2013-11-01*/intFilter _ Value
void setup(){ Serial . begin(9600);//初始化串行通信randomSeed(analog read(0));//生成随机种子}
void loop(){ Filter _ Value = Filter;//获取过滤器输出值serial . println(Filter _ Value);//串行输出延迟(50);}
//用于随机生成一个300左右的当前值intget _ ad () {return random (295,305);}
//中值平均滤波法(又称抗脉冲干扰平均滤波法)(算法1)# definefilter _ n 100 int filter(){ inti,j;intfilter_temp,filter _ sum = 0;int FIlter _ buf[FIlter _ N];for(I = 0;i <。FILTER _ N;i++){ filter _ buf[I]= Get _ AD;延迟(1);}//对于(j = 0)采样值从小到大排列(冒泡法);j <。FILTER _ N-1;j++){ for(I = 0;i <。FILTER _ N-1-j;i++) {if(filter_buf[i]>filter _ buf[I+1]){ filter _ temp = filter _ buf[I];filter _ buf[I]= filter _ buf[I+1];filter _ buf[I+1]= filter _ temp;} } }//去掉最大和最小极值后,平均值为(I = 1;i <。FILTER _ N-1;i++)filter _ sum+= filter _ buf[I];returnFIlter _ sum/(FILTER _ N-2);}
//中值平均滤波法(也叫抗脉冲干扰平均滤波法)(算法二)/* # definefilter _ n100 int filter { int I;int filter _ sum = 0;int filter_max,filter _ minint FIlter _ buf[FIlter _ N];for(I = 0;i <。FILTER _ N;i++){ filter _ buf[I]= Get _ AD;延迟(1);} filter _ max = filter _ buf[0];filter _ min = filter _ buf[0];filter _ sum = filter _ buf[0];for(I = FILTER _ N-1;i >。0;i - ) {if(filter_buf[i]>filter _ max)filter _ max = filter _ buf[I];else if(filter _ buf[I]& lt;filter _ min)filter _ min = filter _ buf[I];filter _ sum = filter _ sum+filter _ buf[I];filter _ buf[I]= filter _ buf[I-1];} I = FILTER _ N-2;filter _ sum = filter _ sum-filter _ max-filter _ min+I/2;// +i/2的目的是舍入filter _ sum = filter _ sum/I;return filter _ sum}*/
6、极限平均滤波法
/*A、名称:限幅平均滤波法B、方法:相当于“限幅滤波法”+“递推平均滤波法”;每次采样到的新数据先进行限幅处理,再送入队列进行递推平均滤波处理。C、优点:融合了两种滤波法的优点;对于偶然出现的脉冲性干扰,可消除由于脉冲干扰所引起的采样值偏差。D、缺点:比较浪费RAM。E、整理:shenhaiyu 2013-11-01*/# define filter _ N 12 IntFilter _ Value;int FIlter _ buf[FIlter _ N];
void setup(){ Serial . begin(9600);//初始化串行通信randomSeed(analog read(0));//生成随机种子FILTER _ buf[FILTER _ N-2]= 300;}
void loop(){ Filter _ Value = Filter;//获取过滤器输出值serial . println(Filter _ Value);//串行输出延迟(50);}
//用于随机生成一个300左右的当前值intget _ ad () {return random (295,305);}
//极限平均滤波法# definefilter _ a1intfilter(){ inti;int filter _ sum = 0;FILTER _ buf[FILTER _ N-1]= Get _ AD;if(((FIlter _ buf[FIlter _ N-1]-FIlter _ buf[FIlter _ N-2])> 1;FILTER _ A)| |((FILTER _ buf[FILTER _ N-2]-FILTER _ buf[FILTER _ N-1])>;FILTER _ A))FILTER _ buf[FILTER _ N-1]= FILTER _ buf[FILTER _ N-2];for(I = 0;i <。FILTER _ N-1;i++){ filter _ buf[I]= filter _ buf[I+1];filter _ sum+= filter _ buf[I];} return(int)FIlter _ sum/(FILTER _ N-1);}
7.一阶滞后滤波方法
/*A、名称:一阶滞后滤波法B、方法:取a=0-1,本次滤波结果=(1-a)*本次采样值+a*上次滤波结果。C、优点:对周期性干扰具有良好的抑制作用;适用于波动频率较高的场合。D、缺点:相位滞后,灵敏度低;滞后程度取决于a值大小;不能消除滤波频率高于采样频率1/2的干扰信号。E、整理:shenhaiyu 2013-11-01*/intFilter _ ValueintValue
void setup(){ Serial . begin(9600);//初始化串行通信randomSeed(analog read(0));//生成随机种子值= 300;}
void loop(){ Filter _ Value = Filter;//获取过滤器输出值serial . println(Filter _ Value);//串行输出延迟(50);}
//用于随机生成一个300左右的当前值intget _ ad () {return random (295,305);}
//一阶滞后滤波法# definefilter _ a 0.01 intfilter(){ intnewvalue;NewValue = Get _ ADValue =(int)((float)new Value * FILTER _ A+(1.0-FILTER _ A)*(float)Value);returnValue}
8.加权递归平均滤波方法
/*A、名称:加权递推平均滤波法B、方法:是对递推平均滤波法的改进,即不同时刻的数据加以不同的权;通常是,越接近现时刻的数据,权取得越大。给予新采样值的权系数越大,则灵敏度越高,但信号平滑度越低。C、优点:适用于有较大纯滞后时间常数的对象,和采样周期较短的系统。D、缺点:对于纯滞后时间常数较小、采样周期较长、变化缓慢的信号;不能迅速反应系统当前所受干扰的严重程度,滤波效果差。E、整理:shenhaiyu 2013-11-01*/intFilter _ Value
void setup(){ Serial . begin(9600);//初始化串行通信randomSeed(analog read(0));//生成随机种子}
void loop(){ Filter _ Value = Filter;//获取过滤器输出值serial . println(Filter _ Value);//串行输出延迟(50);}
//用于随机生成一个300左右的当前值intget _ ad () {return random (295,305);}
//加权递归平均滤波法# define filter _ n 12 int Coe[filter _ n]= { 1,2,3,4,5,6,7,8,9,10,11,12 };//加权系数表int sum _ Coe = 1+2+3+4+5+6+7+8+9+10+11+12;//加权系数和int FILTER _ buf[FILTER _ N+1];int filter(){ inti;int filter _ sum = 0;FILTER _ buf[FILTER _ N]= Get _ AD;for(I = 0;i <。FILTER _ N;i++){ filter _ buf[I]= filter _ buf[I+1];//所有数据左移,低位仍然被filter _ sum+= filter _ buf[I]* Coe[I]丢弃;} filter _ sum/= sum _ Coe;returnfilter _ sum}
9.防抖滤波方法
/*A、名称:消抖滤波法B、方法:设置一个滤波计数器,将每次采样值与当前有效值比较:如果采样值=当前有效值,则计数器清零;如果采样值<>当前有效值,则计数器+1,并判断计数器是否>=上限N(溢出);如果计数器溢出,则将本次值替换当前有效值,并清计数器。C、优点:对于变化缓慢的被测参数有较好的滤波效果;可避免在临界值附近控制器的反复开/关跳动或显示器上数值抖动。D、缺点:对于快速变化的参数不宜;如果在计数器溢出的那一次采样到的值恰好是干扰值,则会将干扰值当作有效值导入系统。E、整理:shenhaiyu 2013-11-01*/intFilter _ ValueintValue
void setup(){ Serial . begin(9600);//初始化串行通信randomSeed(analog read(0));//生成随机种子值= 300;}
void loop(){ Filter _ Value = Filter;//获取过滤器输出值serial . println(Filter _ Value);//串行输出延迟(50);}
//用于随机生成一个300左右的当前值intget _ ad () {return random (295,305);}
//去抖动滤波法# define filter _ N 12 inti = 0;int FIlter(){ int new _ value;new _ value = Get _ AD如果(值!= new _ value){ i++;if(i >;FILTER _ N){ I = 0;Value = new _ value} } elsei = 0;returnValue}
10、限制抖动的滤波方法
/*A、名称:限幅消抖滤波法B、方法:相当于“限幅滤波法”+“消抖滤波法”;先限幅,后消抖。C、优点:继承了“限幅”和“消抖”的优点;改进了“消抖滤波法”中的某些缺陷,避免将干扰值导入系统。D、缺点:对于快速变化的参数不宜。E、整理:shenhaiyu 2013-11-01*/intFilter _ ValueintValue
void setup(){ Serial . begin(9600);//初始化串行通信randomSeed(analog read(0));//生成随机种子值= 300;}
void loop(){ Filter _ Value = Filter;//获取过滤器输出值serial . println(Filter _ Value);//串行输出延迟(50);}
//用于随机生成一个300左右的当前值intget _ ad () {return random (295,305);}
//削波和抗抖动滤波方法# define filter _ a 1 # define filter _ n 5int I = 0;int filter(){ IntNewValue;intnew _ valueNewValue = Get _ AD如果(((新值-值)>;FILTER_A) || ((Value - NewValue)>;FILTER _ A))new _ Value = Value;elsenew _ value = NewValue如果(值!= new _ value){ i++;if(i >;FILTER _ N){ I = 0;Value = new _ value} } elsei = 0;returnValue}
11.卡尔曼滤波(非扩展卡尔曼滤波)
#include<Wire.h> // I2C library, gyroscope//加速度计adxl 345 # define ACC(0x 53)//adxl 345 ACC地址# define a _ TO _ READ(6)//我们每次要读取的字节数(每个轴两个字节)
//陀螺仪ITG3200 #defineGYRO 0x68 //陀螺仪地址,二进制= 11101000当AD0连接到Vcc时(参见您的分线板原理图)# define eg _ SMPLRT _ DIV 0x 15 # define eg _ DLPF _ FS 0x 16 # define eg _ INT _ CFG 0x 17 # define eg _ PWR _ MGM 0x3E
# DEFineg _ TO _ READ 8//x,y,z轴各2字节
//偏移量是芯片特定的。inta _ offx = 0;inta _ offy = 0;inta _ off z = 0;
int g _ off x = 0;intg _ offy = 0;intg _ off z = 0;////////////////////////
////////////////////////char str[512];
void initacc {//开启ADXL345writeTo(ACC,0x2D,0);writeTo(ACC,0x2D,16);writeTo(ACC,0x2D,8);//默认情况下,设备读数在+-2g范围内}
voidgetAccelerometerData(int * result){ InteGadress = 0x 32;//adxl 345字节缓冲器上的第一轴加速度数据寄存器[A _ TO _ READ];读取自(ACC,regAddress,A_TO_READ,buff);//从ADXL 345//读取加速度数据,每个轴读数的分辨率为10位,即2字节。最低有效字节优先!!//因此我们将两个字节都转换成一个int result[0]=(((int)buff[1])& lt;& lt8)| buff[0]+a _ offx;结果[1]=(((int)buff[3])& lt;& lt8)| buff[2]+a _ offy;结果[2]=(((int)buff[5])& lt;& lt8)| buff[4]+a _ off z;}
//初始化陀螺仪无效陀螺仪{/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ITG 3200 *电源管理设置为:*时钟选择=内部振荡器*无复位、无睡眠模式*无待机模式*采样速率至= 125赫兹*参数至+/- 2000度/秒*低通滤波器=5赫兹*无中断* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */写至(陀螺仪,G_PWR_MGM,0x 00);writeTo(GYRO,G_SMPLRT_DIV,0x 07);// EB,50,80,7F,DE,23,20,FFwriteTo(GYRO,G_DLPF_FS,0x1E);// +/- 2000 dgrs/sec,1KHz,1E,19writeTo(GYRO,G_INT_CFG,0x 00);}
voidget陀螺仪数据(int * result){/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *陀螺仪ITG-3200 I2cregisters:temp MSB = 1B,temp LSB = 1Cx轴MSB = 1D,x轴LSB = 1Ey轴MSB = 1F,y轴LSB = 20z轴MSB = 21,z轴LSB = 22 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
intregAddress = 0x1Binttemp,x,y,z;字节缓冲器;readFrom(陀螺仪、regAddress、G_TO_READ、buff);//从itg 3200 result[0]=((buff[2]& lt;& lt8)| buff[3])+g _ offx;结果[1]=((buff[4]& lt;& lt8)| buff[5])+g _ offy;结果[2]=((buff[6]& lt;& lt8)| buff[7])+g _ off z;结果[3]=(buff[0]& lt;& lt8)| buff[1];//温度}
floatxz=0,yx=0,yz = 0;floatp_xz=1,p_yx=1,p _ yz = 1;floatq_xz=0.0025,q_yx=0.0025,q _ yz = 0.0025floatk_xz=0,k_yx=0,k _ yz = 0;floatr_xz=0.25,r_yx=0.25,r _ yz = 0.25//int ACC _ temp[3];//float ACC[3];intacc[3];int gyro[4];floatAxzfloatAyxflouyz;floatt = 0.025void setup { Serial . begin(9600);Wire.begininitAccinitGyro}
//无符号长定时器= 0;//float o;void loop { GetAccelerometrdata(ACC);get陀螺仪数据(陀螺仪);//timer =毫;sprintf(str," %d,%d,%d,%d,%d,%d ",acc[0],acc[1],acc[2],陀螺仪[0],陀螺仪[1],陀螺仪[2]);//ACC[0]= ACC[0];//ACC[2]= ACC[2];//ACC[1]= ACC[1];//r = sqrt(ACC[0]* ACC[0]+ACC[1]* ACC[1]+ACC[2]* ACC[2]);陀螺[0]=陀螺[0]/14.375;陀螺[1]=陀螺[1]/(-14.375);陀螺[2]=陀螺[2]/14.375;Axz=(atan2(acc[0],ACC[2])* 180/PI;Ayx=(atan2(acc[0],ACC[1])* 180/PI;/*if((acc[0]!= 0)& amp;& amp(acc[1]!=0)){Ayx=(atan2(acc[0],ACC[1])* 180/PI;} else { Ayx = t *陀螺仪[2];}*/Ayz=(atan2(acc[1],ACC[2])* 180/PI;//Kalman filter calculate _ xz;calculate _ yxcalculate _ yz//sprintf(str," %d,%d,%d ",xz_1,xy_1,x _ 1);//serial . print(xz);Serial.print(",");//serial . print(yx);Serial.print(",");//serial . print(yz);Serial.print(",");//sprintf(str," %d,%d,%d,%d,%d,%d ",acc[0],acc[1],acc[2],陀螺[0],陀螺[1],陀螺[2]);//sprintf(str,“%d,%d,%d”,陀螺[0],陀螺[1],陀螺[2]);serial . print(Axz);Serial.print(",");//serial . print(Ayx);Serial.print(",");//serial . print(Ayz);Serial.print(",");//Serial . print(str);//o =陀螺[2];//w = ACC[2];//serial . print(o);Serial.print(",");//serial . print(w);Serial.print(",");serial . print(" n ");
//延迟(50);}voidcalculate_xz{
xz = xz+t *陀螺仪[1];p _ xz = p _ xz+q _ xz;k _ xz = p _ xz/(p _ xz+r _ xz);xz = xz+k _ xz *(Axz-xz);p _ xz =(1-k _ xz)* p _ xz;} void calculate _ yx { yx = yx+t * gyro[2];p _ yx = p _ yx+q _ yx;k _ yx = p _ yx/(p _ yx+r _ yx);yx = yx+k _ yx *(Ayx-yx);p _ yx =(1-k _ yx)* p _ yx;
} void calculate _ yz { yz = yz+t * gyro[0];p _ yz = p _ yz+q _ yz;k _ yz = p _ yz/(p _ yz+r _ yz);yz = yz+k _ yz *(Ayz-yz);p _ yz =(1-k _ yz)* p _ yz;}
///-Functions//将val写入accvotywriteto(int DEVICe,字节地址,字节val)上的地址寄存器{ Wire . Begin Intramission(DEVICe);//开始传输到ACC Wire.write(地址);//发送寄存器address wire . write(val);//将值发送到writeWire.endTransmission//结束传输}
//从ACC上的地址寄存器开始读取字节数,以缓冲ArrayVodiReadFrOm(int DEVICe,字节地址,intnum,字节缓冲[]){ Wire . Begin Intramission(DEVICe);//开始传输到ACC Wire.write(地址);//从Wire.endTransmission发送要读取的地址;//end transmission wire . begin in mission(DEVICe);//开始传输到ACCWire.requestFrom(DEVICE,num);//从ACCinti请求6字节= 0;而(Wire.available) //ACC可能发送的比请求的少(异常){ buff[I]= wire . read;//接收一个bytei++;} Wire.endTransmission//结束传输}
1.《滤波 纯干货警告!11种滤波算法程序大全(含源代码)》援引自互联网,旨在传递更多网络信息知识,仅代表作者本人观点,与本网站无关,侵删请联系页脚下方联系方式。
2.《滤波 纯干货警告!11种滤波算法程序大全(含源代码)》仅供读者参考,本网站未对该内容进行证实,对其原创性、真实性、完整性、及时性不作任何保证。
3.文章转载时请保留本站内容来源地址,https://www.lu-xu.com/guonei/677183.html