识别C中的趋势 - 微控制器采样

时间:2013-02-28 18:30:22

标签: c microcontroller sampling

我正在研究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;
        }
    }
}
}

期待听到任何建议:)

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

results

4 个答案:

答案 0 :(得分:2)

当您采样序列有毛刺(短暂的瞬态)时,尝试改进硬件,即改变布局,添加去耦,添加滤波等。

如果这种方法失败,那么中间过滤器[1]说五个位置,取最后五个样本,对它们进行排序并输出中间一个,所以瞬态的两个样本对它的输出没有影响。 (七个地方......三个瞬态)

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

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

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

利用这种改进的样本序列,阈值和周期计数可用于检测静止持续时间。

此外,如果静止期结束后总是出现大的突然变化,那么使用采样延迟“数组”,可以检测到突然的变化,但仍然可以使用最后一个静态样本进行记录。 / p>

[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可以更快地替换。

答案 1 :(得分:1)

从前一个值连续存储当前值和增量。

注意当增量开始减重时,增量应用于刻度
请注意,当增量结束时,增量应用于刻度
取小数量的X数值并将它们平均值

顺便说一句,我确信之前已经完成了1M次,我认为搜索scale PIDweight PID会发现很多信息。

答案 2 :(得分:0)

如果要与之前的值进行比较,请不要忘记在读数值之间使用___ delay_ms(XX)功能。如果代码连续循环,每个步骤的差异显然很小。

答案 3 :(得分:0)

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

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

并且您不需要那么大的阵列,基于较小的窗口大小,运行平均值会更好,当您检测到负凹凸时,在您的情况下较小的残留误差。