AD数据采集滤波算法

背景知识

数字滤波常应用实时低通滤波,硬件滤波常应用于实时高通滤波。
在设计滤波算法时,应考虑采用速度、干扰类型(脉冲干扰、周期性干扰)、采用数据变化特性(如变化速度、变化方向速度)、滞后性等等因素。

数字滤波算法采用输出比抗毛刺干扰能力抗噪声干扰能力
限幅滤波1:1很弱
中值滤波N:1较强一般
算术平均滤波N:1较弱较强
去极值平均滤波N:1较强较强
滑动平均滤波1:1较强
滑动加权平均滤波1:1较强

算法设计

本文滤波算法构成:
1.filter data at power freqency
2.average without min and max val
3.handler with val out of range
4.weighted average
5.set change deadzone
6.set zero zone
注意事项
1.前期设计算法时未考虑到限幅+消抖算法,为一个败笔
2.超限处理(处理3)位置靠前,是为了后面的滤波算法提供一个有效值
3.超限处理算法是否添加计数器,有待商榷

#ifndef		__AI_H__
#define		__AI_H__
#include "config.h"//类型命名

#define	AICHANNUMB 		8   
#define SAMPLE_TOTAL_NUM	8
#define WEIGHTED_ARR_SIZE	4

typedef signed short sample_t;//采样的数据类型

struct ai_data{
	unsigned char type;//通道类型
	
	sample_t up_limit;//上限值
	sample_t down_limit;//下限值
	sample_t up_exception_val;//输入小于下限值时,显示的值
	sample_t down_exception_val;//输入大于上限值时,显示的值
	
	int dead_zone_size;//变化死区大小 防止数据小范围跳动
	
	int zero_val;//输入为0时,对应的值
	int zero_zone_size;//零区大小
	
	int sample_num;//去最值平均滤波的采样个数
	sample_t sample_data[SAMPLE_TOTAL_NUM];//采样的数据
	sample_t power_freq[SAMPLE_TOTAL_NUM/2];//工频滤波后的数据
	
	int first_weighted;//是否为第一次加权递推平均滤波
	sample_t weighted_average[WEIGHTED_ARR_SIZE];//存放历史数据
	
	sample_t input;//最终的输入值
};
extern struct ai_data ai_data_buff[AICHANNUMB];

extern void ai_sample_data(int channo);
extern void ai_data_buff_init(void);
extern void init_channel_para(int channo, uint8 type);

#endif

/*AI.c*/
#include	"AI.h"
stcAI_DATA AI_DATA_BUF[AICHANNUMB];

struct ai_data ai_data_buff[AICHANNUMB];

static void ai_data_filter(struct ai_data *buff);
static void power_freq_filter(sample_t sample_data[], sample_t power_freq[], int len);
static sample_t average_filter(sample_t sample_data[], int len);
static void weighted_average_filter(sample_t current_data, sample_t history_data[]);

void ai_data_buff_init(void)
{
	int i = 0;
	memset(&ai_data_buff[0], 0, sizeof(struct ai_data)*AICHANNUMB);
	for(i=0; i<AICHANNUMB; i++) {
		ai_data_buff[i].first_weighted = 0xff;
		
	}
		
}

void init_channel_para(int channo, uint8 type)
{
	ai_data_buff[channo].type = type;
	switch(type) {
	case 0:
		return;		
	case 2:
		ai_data_buff[channo].dead_zone_size = 5;	
		ai_data_buff[channo].zero_val = 0;	
		ai_data_buff[channo].zero_zone_size = 15;	
		ai_data_buff[channo].down_limit = 0;
		ai_data_buff[channo].up_limit = 20000;
		ai_data_buff[channo].down_exception_val = 0;
		ai_data_buff[channo].up_exception_val = 20000;
		break;
	case 3:
		ai_data_buff[channo].dead_zone_size = 5;	
		ai_data_buff[channo].zero_val = 0;	
		ai_data_buff[channo].zero_zone_size = 25;	
		ai_data_buff[channo].down_limit = 0;
		ai_data_buff[channo].up_limit = 20000;
		ai_data_buff[channo].down_exception_val = 0;
		ai_data_buff[channo].up_exception_val = 20000;		
		break;
	case 4:
		ai_data_buff[channo].dead_zone_size = 3;	
		ai_data_buff[channo].zero_val = 0;	
		ai_data_buff[channo].zero_zone_size = 5;	
		ai_data_buff[channo].down_limit = -500;
		ai_data_buff[channo].up_limit = 1500;
		ai_data_buff[channo].down_exception_val = 32767;
		ai_data_buff[channo].up_exception_val = 32767;
		break;
	default:
		break;
		
	}
}

void ai_sample_data(int channo)
{
	sample_t sample_data = read_input();
	ai_data_buff[channo].sample_data[ai_data_buff[channo].sample_num] = sample_data;
	ai_data_buff[channo].sample_num++;
	
	if(ai_data_buff[channo].sample_num >= SAMPLE_TOTAL_NUM) {
		ai_data_buff[channo].sample_num = 0;
		ai_data_filter(&ai_data_buff[channo]);
	}
	
} 

/*
 *brief  Function: data filter
	   1.filter data at power freqency
	   2.average without min and max val
	   3.handler with val out of range
	   4.weighted average
	   5.set change deadzone
	   6.set zero zone
*/
void ai_data_filter(struct ai_data *buff)
{
	int i = 0;
	int weighted_arr_len = sizeof(buff->weighted_average)/sizeof(sample_t);
	sample_t average = 0;
	sample_t curr_input = 0;
	sample_t last_input = buff->input;
	
	int dead_zone_size = buff->dead_zone_size;
	
	int zero_zone_size = buff->zero_zone_size;
	int zero_val = buff->zero_val;
		
	power_freq_filter(buff->sample_data, buff->power_freq, sizeof(buff->power_freq)/sizeof(sample_t));
	average = average_filter(buff->power_freq, sizeof(buff->power_freq)/sizeof(sample_t));
	
	if(average < buff->down_limit) {
		buff->input = buff->down_exception_val;
		return;
	}
	
	if(average > buff->up_limit) {
		buff->input = buff->up_exception_val;
		return;
	}
	
	if(buff->first_weighted != 0) {
		buff->first_weighted = 0;
		for(i=0; i<weighted_arr_len; i++)
			buff->weighted_average[i] = average;
		
		buff->input = average;
		return;
	}
	
	weighted_average_filter(average, buff->weighted_average);
	curr_input = buff->weighted_average[weighted_arr_len -1];
	
	if((curr_input > last_input-dead_zone_size) && (curr_input < last_input+dead_zone_size))
		curr_input = last_input;
			
	if((curr_input < zero_val+zero_zone_size) && (curr_input > zero_val - zero_zone_size))
		curr_input = buff->zero_val;
	
	buff->weighted_average[weighted_arr_len-1] = curr_input;	
	buff->input = curr_input;	
}

void power_freq_filter(sample_t sample_data[], sample_t power_freq[], int len)
{
	int i = 0;
	for(i=0; i<len; i++)	
		power_freq[i] = (sample_data[2*i] + sample_data[2*i+1])/2;
}

sample_t average_filter(sample_t sample_data[], int len)
{		
	int total = sample_data[0];
	int i = 0;
	
	sample_t max = sample_data[0];
	sample_t min = sample_data[0];
	
	for(i=1; i < len; i++) {
		if(sample_data[i] < min)
			min = sample_data[i];
		if(sample_data[i] > max)
			max = sample_data[i];
		total += sample_data[i];
	}
	
	return (total-min-max)/(len-2);	
}

void weighted_average_filter(sample_t current_data, sample_t history_data[])
{	
	int i = 0;
	int len = WEIGHTED_ARR_SIZE;
	int weight[10] = {0};//??
	int total_weight = 0;//???
	int total_sample_data = 0;
	
	weight[0] = 1;
	total_weight += weight[0];
	for(i=1; i<len; i++) {
		weight[i] = weight[i-1]*2;
		total_weight += weight[i];
	}
	
	for(i=0; i<len-1; i++)
		history_data[i] = history_data[i+1];
	
	for(i=0; i<len-1; i++)	
		total_sample_data += history_data[i] * weight[i];		
	
	total_sample_data += current_data * weight[len-1];
	history_data[len-1]	= (sample_t)(total_sample_data/total_weight);
}

  • 0
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
数字信号处理是数据采集系统中的重要一环,而数据采集与数字滤波则是数字信号处理的重要分支,并且数字滤波算法则是整个数据采集系统中极为重要的组成部分,换而言之,数字滤波算法的优劣直接决定着整个系统的精度与速度。 本文主要服务于高速铁路实时数据采集系统,对现有的数字滤波算法进行分析研究,比对了各个算法的优缺点,改进了现有的算法,在现有算法的基础上,提出了一种复合滤波算法。这种算法结合了中值滤波法、滑动平均滤波法和加权平均滤波法,它是一种在这三种算法的基础上建立的复合滤波算法。 这种算法扬长避短,它综合了三种基本算法的优点,能够滤除随机性脉冲信号干扰和周期性脉冲信号干扰,与现有的基本算法相比,它能够全面的滤除掉采样值中的干扰信号,并且他能够在本文的高速铁路实时数据采集系统中起到良好的过滤效果,这个是其他数字滤波算法所不能比拟的。 之后,本文为了考量改进后的数字滤波算法,本文对部分基本数字滤波算法进行了实验,并且也将改进后的数字滤波算法应用到实验中,将部分基本数字滤波算法与改进后的数字滤波算法相对比,从各方面思考,从中得出结论,改进后的数字滤波算法,更能消除高速铁路实时数据采集系统中信号干扰,比起其他方法,该算法更适用于高速铁路实时数据采集系统。 最后,对课题工作进行了总结,并对未来研究工作给予了展望。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值