首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >定点简单低通滤波器

定点简单低通滤波器
EN

Stack Overflow用户
提问于 2016-08-12 12:56:12
回答 3查看 2.3K关注 0票数 0

我有一个简单的电路设置,通过LDR读取光线电平到Arduino。我正在尝试实现一个简单的低通过滤器来读取数据。考虑到analogRead()返回一个未签名的int,如何最好地解决这个问题。

我试图实现一个简单的不动点表示,但我不确定这是否正确的方法。

下面是一个代码片段:

代码语言:javascript
运行
复制
#define WLPF 0.1
#define FIXED_SHIFT 4

ldr_val = ((int)analogRead(A0)) << FIXED_SHIFT;
 while (true) {
    int newval = (int)analogRead(A0) << FIXED_SHIFT;
    ldr_val += WLPF*(newval - ldr_val);
    Serial.println(ldr_val >> FIXED_SHIFT, DEC);
}

注意,ADC的分辨率是10位,我正在使用8位Arduino微芯片。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2016-08-12 16:14:23

在没有FPU的设备上,而不是乘以0.1 (在任何情况下,这都是浮点而不是定点实现),您应该除以10:

代码语言:javascript
运行
复制
#define WLPF_DIV 10

...

ldr_val += (newval - ldr_val) / WLPF_DIV;

然而,8位处理器上的分割通常是昂贵的(尽管与循环中Serial.println()的执行时间相比可能相形见绌--但这是一个不同的问题)。相反,更有效的方法是选择一个2的幂,这样就可以用右移来执行除法。

代码语言:javascript
运行
复制
#define WLPF_SHIFT 3  // divide by 8

...

ldr_val += (newval - ldr_val) >> WLPF_SHIFT ;

符号int的使用是有问题的,因为符号类型的右移是未定义的行为。在这种情况下,可以通过将代码更改为:

代码语言:javascript
运行
复制
#define WLPF_DIV 8

... 

ldr_val += (newval - ldr_val) / WLPF_DIV ;

在任何情况下,编译器都很可能会发现两个常数的能力,并使用算术移位来生成代码。但是,您可能会更好地重新考虑数据类型。

Serial.println()调用中仍然有一个右移,但这也可以被除以16来代替:

代码语言:javascript
运行
复制
#define WLPF_DIV 8
#define FIXED_MUL  16

ldr_val = (int)analogRead(A0) * FIXED_MUL  ;

for(;;)
{
    int newval = (int)analogRead(A0) * FIXED_MUL ;
    ldr_val += (newval - ldr_val) / WLPF_DIV 
    Serial.println(ldr_val / FIXED_MUL, DEC);
}

在每个样本的基础上,数据的非确定性输出不会产生一个非常精确的滤波器,而且在任何情况下都会控制时间,所以你对频率响应几乎没有控制,而且它不会稳定。它还使以前的性能优化变得毫无意义。如果这在您的应用程序中很重要,您可能会想一想--但这是一个不同的问题。

票数 3
EN

Stack Overflow用户

发布于 2016-08-12 23:15:18

我是从哈尔·钱伯林( Hal Chamberlin )的“微处理器的音乐应用”(Musical Application of微处理器)一书中引证的,第438页:

如果你在累加器中允许大数,那么你可以用一个乘法和一些右移做一个一阶低通滤波器。

代码语言:javascript
运行
复制
  out = accum >> k
  accum = accum - out + in

选择“k”以改变截止频率。移位越多,低通截止值越低,但累加器中的值越大.使用analog_read()中的10位值,您可以很容易地右移4个位置,并且在累加器中仍然有2位的空间(如上面所述的@datafiddler )。

Cypress有一些类似方程的PSOC芯片的应用程序说明,并且使用移位。我记得有一个很好的表格,与截止频率相关的移位数。近似截止频率是采样频率除以增益因子2-pi:

f0 ~ fs / (2πa)

“a”是二的力量所在。

保持平滑的信号!

票数 4
EN

Stack Overflow用户

发布于 2016-08-12 13:49:00

坚持整数运算:

代码语言:javascript
运行
复制
#define WLPF 9

filtered = ((long)filtered * WLPF + newValue) / (WLPF + 1);
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38918530

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档