滑动平均滤波也叫递推平均滤波。

把连续取得的N个采样值看成一个队列,队列的长度固定为N,每次采样到一个新数据放入队尾,并扔掉原来队首的一次数据(先进先出原则),把队列中的N个数据进行算术平均运算,获得新的滤波结果。

从这个原理中可以感觉出这种滤波方法的平滑度会很高,所以会适用于高频震荡系统,对周期性的干扰有很好的抑制作用。但是也是有缺点的,灵敏度低,

对偶然出现的脉冲性干扰的抑制作用较差不易消除由于脉冲干扰所引起的采样值偏差不适用于脉冲干扰比较严重的场合,由于他要保存过去N个样本的数据所以说会比较浪费RAM。

(N值的选取:流量,N=12;压力,N=4;液面,N=4-12;温度,N=1-4。)

以上引用来自互联网,由于出处太多已分不清是谁的原创,如果原作者见了需版权声明请通知

本次实验是基于pyboard的,原码作者是英国一个大牛用汇编写的https://github.com/peterhinch/micropython-filters.git

这个帖子主要对其进行了测试以及用python写了个可以移植到其他micropython平台的代码。后续会贴出FIR滤波器,傅立叶变换等帖子,之前一直想发帖,无奈总是提示我有敏感词汇发不了

下图为官网pyboard的图以及本次测试用的板子图

板子是我自己画板掏钱打板手工焊的,完全兼容其他pyboard的开发板,所以尽管放心测试

截图201712261006377680.png (500.06 KB, 下载次数: 22)

2017-12-26 10:06 上传

截图201712261334343967.png (312.66 KB, 下载次数: 17)

2017-12-26 13:34 上传

英国牛人代码如下,

[AppleScript] 纯文本查看 复制代码# Implementation of moving average filter in Arm Thumb assembler

# Author: Peter Hinch

# 15th Feb 2015

# Updated to reflect support for sdiv instruction

# Timing: 27uS on MicroPython board (independent of data)

# Function arguments:

# r0 is an integer scratchpad array. Must be of length 3 greater than

# the number of values to be averaged.

# On entry array[0] must hold the array length, other elements must be zero

# r1 holds new data value

# Return value: the current moving average

# array[0] is array length, array[1] is the current sum, array[2] the insertion point

# r2 holds the length of the coefficient array

# Pointers (byte addresses)

# r3 start of ring buffer

# r4 insertion point (post increment)

# r5 last location of ring buffer

# Other registers

# r7 temporary store for result

@micropython.asm_thumb

def avg(r0, r1):

mov(r3, r0)

add(r3, 12) # r3 points to ring buffer start

ldr(r2, [r0, 0]) # Element count

sub(r2, 4) # Offset in words to buffer end

add(r2, r2, r2)

add(r2, r2, r2) # convert to bytes

add(r5, r2, r3) # r5 points to ring buffer end (last valid address)

ldr(r4, [r0, 8]) # Current insertion point address

cmp(r4, 0) # If it's zero we need to initialise

bne(INIT)

mov(r4, r3) # Initialise: point to buffer start

label(INIT)

ldr(r7, [r0, 4]) # get current sum

ldr(r6, [r4, 0])

sub(r7, r7, r6) # deduct oldest value

add(r7, r7, r1) # add newest value

str(r7, [r0, 4]) # put sum back

str(r1, [r4, 0]) # put in buffer and post increment

add(r4, 4)

cmp(r4, r5) # Check for buffer end

ble(NOLOOP)

mov(r4, r3) # Incremented past end: point to start

label(NOLOOP)

str(r4, [r0, 8]) # Save the insertion point for next call

ldr(r1, [r0, 0]) # Element count

sub(r1, 3) # No. of data points

mov(r0, r7) # The sum

sdiv(r0, r0, r1) # r0 = r0//r1

为了提高效率代码是由汇编写的直接操作寄存器。

这个函数入口主要有两个参数,第一个参数为队列的缓存,第二参数为最新的数据,关于第一个参数源码作者有说明,这个参数的长度必须比队列长度的长3,这个参数第一个元素存储着这个参数的总长度,第二元素为N个样本数据的和,第三个元素是数据的插入点(对于第二个第三个元素不需要去操心,用来给汇编提供便利)后面的元素为采样值的缓存。

作者提供了一个测试程序,主要测试了一下这个用汇编写的代码的执行用时,跑一下试试

[Python] 纯文本查看 复制代码# Demo program for moving average filter

# Author: Peter Hinch

# 12th Feb 2015

import array, pyb

from avg import avg

data = array.array('i', [0]*13) # Average over ten samples

data[0] = len(data)

def test():

for x in range(12):

print(avg(data, 1000))

for x in range(12):

print(avg(data, 0))

def timing():

t = pyb.micros()

avg(data, 10)

t1 = pyb.elapsed_micros(t) # Time for one call with timing overheads

t = pyb.micros()

avg(data, 10)

avg(data, 10)

t2 = pyb.elapsed_micros(t) # Time for two calls with timing overheads

print(t2-t1,"uS") # Time to execute the avg() call

test()

print("Timing test")

timing()

测试结果

截图201712261336544902.png (83.56 KB, 下载次数: 13)

2017-12-26 13:36 上传

队列长度为10,执行用时8微秒,效率挺高的了

那么接下来看看直接接设备进行实时测试看效果怎么样。

思路:外接一个三轴加速度计,取一个轴的数据进行滤波,同时打印原始数据和滤波后的数据做对比(当然板载一个MMA7660三轴加速度计,但是其输出的数值范围太小了,并不是说小数值不能用只是为了提高观察效果我采用了外置的加速度计)

代码如下

[Python] 纯文本查看 复制代码import MPU6050

import array

from protocol import *

from avg import *

from pyb import I2C,UART,delay

#golbal data

accx_data = array.array('i', [0]*8)

#f_acc_data = avg_filiter(accx_data)

accx_data[0] = len(accx_data)

#hardwareobject

uart_port = UART(4,57600)

iic = I2C(1,I2C.MASTER)

acc_dev = MPU6050.MPU6050(iic)

while True:

raw_data = acc_dev.read_Accel_z()

filter_data = avg(accx_data,raw_data)

send_data = data_send(raw_data,filter_data,0,0,0,0,0,0,0)

uart_port.write(send_data)

delay(20)

用串口示波器把数据显示出来效果如图

截图201712261349484095.png (145.63 KB, 下载次数: 16)

2017-12-26 13:49 上传

局部图

截图201712261350306731.png (176.56 KB, 下载次数: 15)

2017-12-26 13:50 上传

继续放大

截图201712261351009137.png (217.63 KB, 下载次数: 14)

2017-12-26 13:51 上传

红色是原始数据,蓝色是滤波后的数据,本次实验滑动的N为5,从图像来看确实对波形的毛刺有了很好的平滑效果,波形有轻微的延时

大致思路明白了,那么现在用python自己来写一个滑动滤波的函数,捋一下大致步骤就是,建立一个先入先出的队列,然后每次新的数据入列先把最前面的元素出列然后对所有的数据求平均值,由于对样本的和是一个反复的过程,所以为了提高效率,采纳原作者的思路,找一个位置来存放所求的和,每次计算只需减去最前面的样本在加上最新的样本即可,这样就省去N-2次的加法计算。(我之前用最简单最笨的方法写的试了,实在是耗时太长了,最后借鉴了源作者的方法,换句话说就是对原作者代码的汇编到python的翻译,这样也可以在其他不支持汇编的平台上无缝移植了)

代码如下,但是用时太久了,样本长度为10的情况下测试的。

[Python] 纯文本查看 复制代码import array, pyb

class avg_filiter():

def __init__(self,cache_data):

self.cache = cache_data

self.len = len(cache_data)

self.cache[0] = self.len

self.sum = 0

for item in cache_data[3:]:

self.sum += item

self.cache[1] = self.sum

def avg(self,new_data):

self.cache[1] = self.cache[1] - self.cache[3]

self.cache[1] = self.cache[1] + new_data

self.cache[3:-1] = self.cache[4:]

self.cache[-1] = new_data

return self.cache[1]//(self.len - 3)

data = array.array('i', [0]*13) # Average over ten samples

fdata = avg_filiter(data)

def test():

for x in range(12):

print(fdata.avg(1000))

for x in range(12):

print(fdata.avg(0))

def timing():

t = pyb.micros()

fdata.avg(10)

t1 = pyb.elapsed_micros(t) # Time for one call with timing overheads

t = pyb.micros()

fdata.avg(10)

fdata.avg(10)

t2 = pyb.elapsed_micros(t) # Time for two calls with timing overheads

print(t2-t1,"uS") # Time to execute the avg() call

test()

print("Timing test")

timing()

但是程序耗时整整翻了十倍

截图201712261340208536.png (76.89 KB, 下载次数: 17)

2017-12-26 13:40 上传

不过虽然时间相对汇编来说有点长,但是对于一般的AD采集的场合这个时间完全够用了,现在可以开心的移植到esp8266上了

滑动滤波相对简单一点,大概就这里吧。后面附件贴上代码,里面有mpu6050的库

mpu6050 滑动平均滤波.zip

(4.74 KB, 下载次数: 70)

2017-12-26 10:53 上传

点击文件名下载附件

代码

proteus仿真micropython_基于micropython的滑动平均滤波器相关推荐

  1. 【Proteus仿真】基于74LS148+74LS279+74LS48的四路抢答器

    [Proteus仿真]基于74LS148+74LS279+74LS48的四路抢答器 Proteus仿真 74LS148 74LS148 是8 线-3 线优先编码器,共有 54/74148 和 54/7 ...

  2. 【Proteus仿真】基于51单片机的八路抢答器

    [Proteus仿真]基于51单片机的八路抢答器 Proteus仿真 主要功能和使用介绍 采用4位数码管设计. 下排按键一一对应八位选手. 上排三个按键,从走到右依次为:开始.暂停.复位. 操作流程: ...

  3. 【Proteus仿真】基于DHT11的温度测量,LCD1602显示

    [Proteus仿真]基于DHT11的温湿度测量,LCD1602显示 测试工具 软件:Proteus8.13 仿真器件:蜂鸣器警报,按键输入,DHT11温湿度,传感器LCD1602显示. 功能叙述 利 ...

  4. freqz()计算M点滑动平均滤波器的频率响应

    函数说明(建议参考官方文档) freqz(h,w)可以用来求指定的单位脉冲响应向量 h 在一组给定频率点 w 上的频率响应值 由这些频率响应值,可以用函数 real 和 imag 计算实部和虚部,函数 ...

  5. 滑动平均滤波器与CIC滤波器

    文章目录 前言 一.传递函数 1.什么是传递函数 2.FIR与IIR在传递函数上的区别(FIR) 3.FIR与IIR在传递函数上的区别(IIR) 4.FIR的抽头系数/FIR的阶数 5.FIR滤波器的 ...

  6. matlab 滑动平均滤波,滑动平均滤波器实验报告

    滑动平均滤波器实验报告 所属分类:matlab例程 开发工具:matlab 文件大小:798KB 下载次数:19 上传日期:2018-01-27 16:12:36 上 传 者:玉玲珑 说明:  给出一 ...

  7. C语言实现滑动平均滤波器

    目录 前言 原理 代码 讨论 改进 参考文章 前言 使用电机速度做闭环控制时,发现传感器的数据受到了高频噪声的影响,于是想先对其进行滤波处理. 原理 滑动平均滤波器本质是一个低通滤波器,可以看成FIR ...

  8. 【micropython】滑动平均滤波

    滤波原理: 采用队列方式,当来一个新数据时,将队列里面的最老的数据替换掉.计算队列里面数据的平局值或加权平均值. 例如采样数据为 1,2,3,4,5,6,7,8 滑动窗口为4时: 1.滑动平均滤波算法 ...

  9. proteus仿真micropython_用Python让单片机“行动”起来——MicroPython实战入门篇

    MicroPython以微控制器作为目标,从而使得Python可以用来控制硬件.说到MicroPython,也许有人会感到陌生.而说到和它密切相关的Python,是否会恍然大悟呢?Python属于解释 ...

最新文章

  1. Spring Boot+Docker微服务分布式服务架构设计和部署案例
  2. OpenCV人脸识别LBPH算法源码分析
  3. 美团高德并不是解决快车问题的灵药,烧完钱之后只会产生新的滴滴
  4. 排序下---(冒泡排序,快速排序,快速排序优化,快速排序非递归,归并排序,计数排序)
  5. ps绿化工具_绿化消防车价位
  6. 一个实时精准触达系统的自我修养
  7. 系统仿真平台SkyEye可替代国外Matlab/Sumlink等同类软件
  8. 【亚伦博客】反方观点: 下载不是偷窃
  9. 递归创建多级文件目录(PHP)
  10. Spring Boot 2.x 自定义数据源 DruidDataSource(操作 mysql 数据库)
  11. 随手写了个android应用
  12. 科研伦理与学术规范2021秋期末考答案|网课期末考答案|学堂在线|北京师范大学印波副教授
  13. 记一次用jspdf和html2canvas导出pdf分页处理
  14. 磊科路由器信号按键_磊科怎么隐藏wifi信号 磊科路由器如何隐藏wifi信号?-192路由网...
  15. [艾兰岛]制作传送门之传送技能——kura酱长期更新
  16. Android 7.0 APN 拨号上网流程分析
  17. Android攻城狮Dialog
  18. Tyrion 中文文档(含示例源码)
  19. 论语 尧曰篇(笔记)
  20. C++中继承 —— 继承的概念及定义

热门文章

  1. 数据与计算机通信复习重点
  2. C#如何Json转字符串;字符串转Json;Newtonsoft.Json(Json.Net)
  3. 2 django系列之django分页与templatetags
  4. Xilinx实习一年总结
  5. RabbitMQ 原文译03--发布和订阅
  6. 2016030206 - mysql常用命令
  7. Mysql数据库优化技术之配置篇、索引篇 ( 必看 必看 转)
  8. Flash小玩意图案创作:新增MulCircle和圆环
  9. 减治法在查找算法中的应用(JAVA)--折半查找
  10. c语言10个数如何求最大值,C语言,输入10个数怎样输出10个数中最大值,最小值(大一计算机)...