电机ADC滤波 - 递推平均滤波算法

1、创作灵感

        最近在做一个电机项目,需要采集电机的运行电流,用来判断电机的运行状态。经过硬件电路转换后可以将电机的运行电流转化为电压,用单片机的ADC进行采集,即可获取电机的运行状态。

        在项目过程中,由于ADC采样速度过快,使得采集到的电机ADC不稳定(启动瞬间ADC过高),加入滤波算法后可以大幅度降低误报风险,本次采取的算法是递推平均值滤波算法。

2、思路分析

        电机ADC持续采样,将采集到的ADC值存到一个数组中(这里对20个数据进行运算。PS:太少容易不稳定,太多容易浪费CPU资源),用新数据不断覆盖老数据,最后将数据进行平均处理,可以得到稳定的ADC值。

3、代码实现

定义一个结构体:

struct average
{
	unsigned char new_data;//输入的数据
	unsigned char data_num;//替换哪一位的数据
	unsigned char data[20];//存放数据,最多放20个
	unsigned int sum;//总和
	unsigned char average_value;//平均值
};

平均值运算程序:

unsigned char average_run(struct average *object)
{
	object -> data[object -> data_num] = object -> new_data;//将新值覆盖掉数组中的一个数据
	
	if(object -> data_num >= 0 && object -> data_num < 19) object -> data_num++;
	else                                                    object -> data_num = 0;
	
	//计算平均值
	object -> sum = 0;//清空总和
	for(unsigned char loop = 0; loop < 20; loop++)
	{
		object -> sum += object -> data[loop];//计算总和
	}
	object -> average_value = (object -> sum / 20);//取平均值
	
	return (object -> average_value);
}

使用示范:

定义一个结构体对象:

struct average adc;

将采集到的数据给到结构体:

(说明:这里是测试代码,在while中不断让num自增,不断更新num的值,对其进行平均值运算。)

adc.new_data = ++num;//将取到的值赋给结构体
adc_average = average_run(&adc);//得到平均值

4、测试结果:

5、总结:

        本次的算法只对最近采集到的20个数据进行平均处理,通过数据覆盖使数据不易进行突变而造成干扰,为了节约CPU资源,所以不进行浮点数的运算(浮点数运算更加准确,需要精确数据的可以进行程序修改)。

注意要点:由于电机采集到的ADC值一般不会超过255,所以采集的值用unsigned char类型的变量进行保存,如果单次输入的值大于255,则要将结构体中的 new_data 、 data[20] 、average_value三个变量的数据类型改成unsigned int。运算函数返回类型也要修改成unsigned int。

  • 13
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值