0

我正在研究一个 MC68HC11 微控制器,并有一个模拟电压信号输入,我已经对其进行了采样。该场景是一台称重机,当物体撞击传感器然后它稳定(这是我想要的样本)然后在物体角色关闭之前再次达到峰值时,会出现大峰值。

我遇到的问题是想办法让程序检测到这个稳定点并对其进行平均以产生整体权重,但无法弄清楚如何:/。我考虑过的一种方法是比较以前的值,看看它们之间是否有很大的差异,但我没有取得任何成功。下面是我正在使用的C代码:

#include <stdio.h>
#include <stdarg.h>
#include <iof1.h>

void main(void)
{
/* PORTA, DDRA, DDRG etc... are LEDs and switch ports */

unsigned char *paddr, *adctl, *adr1;
unsigned short i = 0;
unsigned short k = 0;
unsigned char switched = 1; /* is char the smallest data type? */

unsigned char data[2000];

DDRA = 0x00; /* All in */
DDRG = 0xff;
adctl = (unsigned char*) 0x30;
adr1 = (unsigned char*) 0x31;

*adctl = 0x20; /* single continuos scan */

while(1)
{
    if(*adr1 > 40)
    {
        if(PORTA == 128) /* Debugging switch */
        {
            PORTG = 1;
        }
        else
        {
            PORTG = 0;      
        } 
        if(i < 2000)
        {
            while(((*adctl) & 0x80) == 0x00);
            {
                data[i] = *adr1;
            } 
                            /* if(i > 10 && (data[(i-10)] - data[i]) < 20) */
            i++;
        } 
        if(PORTA == switched)
        {   
            PORTG = 31;
            /* Print a delimeter so teemtalk can send to excel */
            for(k=0;k<2000;k++)
            {
                printf("%d,",data[k]);
            }
            if(switched == 1) /*bitwise manipulation more efficient? */
            {
                switched = 0;
            }
            else
            {
                switched = 1;
            }
            PORTG = 0;
        }
        if(i >= 2000)
        {
            i = 0;
        }
    }
}
}

期待听到任何建议:)

(下图显示了这些值的外观,红色框是我要识别的区域。

结果

4

4 回答 4

2

当您的采样序列出现故障(短暂的瞬变)时,请尝试改进硬件,即更改布局、添加去耦、添加过滤等。

如果该方法失败,那么一个中值滤波器 [1] 说五个位置长,它获取最后五个样本,对它们进行排序并输出中间的一个,因此瞬态的两个样本对其输出没有影响。(七处……三瞬)

然后是计算效率高的指数平均低通滤波器 [2]

                     y(n) = y(n–1) + alpha[x(n) – y(n–1)]

选择 alpha(1/2^n,右移除法)以产生小于基础响应(~50 个样本)的时间常数 [3],但仍滤除噪声。增加有效小数位将避免量化问题。

通过这种改进的采样序列、阈值和循环计数,可用于检测静止持续时间。

此外,如果静止期结束后总是伴随着大的突然变化,那么使用采样延迟“阵列”,可以检测到突然变化,但仍然有最后一个静止样本可用于记录。

[1] http://en.wikipedia.org/wiki/Median_filter

[2] http://www.dsprelated.com/showarticle/72.php

[3] http://en.wikipedia.org/wiki/Time_constant

注意为上述过滤操作添加代码将降低最大可能的采样率,但 printf 可以替换为更快的东西。

于 2013-03-03T01:20:35.553 回答
1

连续存储当前值和与前一个值的差值。

注意 delta 何时随着重量应用到秤的开始而减小 注意当 delta 何时随着重量应用到秤
的结束而增加
取 X 个具有小 delta 的值并将它们平均

顺便说一句,我确信这已经完成了 100 万次,我在想搜索scale PIDweight PID会找到很多信息。

于 2013-02-28T18:39:47.980 回答
0

如果您要与前一个值进行比较,请不要忘记在读数值之间的某个位置使用 ___delay_ms(XX) 函数。如果代码不断循环,每一步的差异显然很小。

于 2013-02-28T19:01:27.313 回答
0

看看你漂亮的图表,我会说你应该只寻找下降沿,它比前沿更一致。

换句话说,让样本累积,以预定义的窗口大小一直计算运行平均值,记住以前值的偏差仅供参考,检查值中是否存在较大的负值(例如绝对值比当前值小十倍)运行平均值),您的运行平均值就是您的价值。您可以稍微返回一点(忽略平均值中的最后几个值,然后重新计算)以补偿每个负凹凸之前图片中可见的小的正凹凸......这里不需要繁重的数学,你无法更好地模拟现实那么你的图片就显示出来了,只要确保你的代码检测到每个样本的结尾。您必须以足够快的速度使用样本以确保没有遗漏任何负面影响(否则您的数据平均会出现很大的时间错误)。

而且您不需要那么大的阵列,在您检测到负碰撞时,基于较小的窗口大小,较小的残余误差,运行平均值会更好。

于 2013-03-18T18:14:11.090 回答