从数据中删除噪音和极值?

时间:2016-02-18 10:00:13

标签: c# serial-port psoc

我有一个程序,可以从PSoC上的ADC读取串行数据。

这些号码以<uint16>格式发送,包括&#39;&lt;&#39;和&#39;&gt;&#39;符号,以二进制格式00111100 XXXXXXXX XXXXXXXX 00111110传输,其中&#39; X组成16位无符号整数。

有时,阅读工作不会很好,程序会使用二进制数据进行&#39;&gt;&#39;符号作为其数字的一部分导致毛刺,如2500个样本的屏幕截图所示(忽略样本800到1500之间的下降,这是我使用ADC输入):

Screenshot

您可以清楚地看到毛刺导致数据每次发生时都会采样大致相同的值。

数据每秒发送十次,所以我打算做的是取十个样本,去除任何毛刺(其中值远离其他样本),然后平均剩余值以平滑曲线有点。输出可以从0到50000+,因此我不能删除低于某个数字的值。

我不确定如何删除超出10个样本组中其他值范围的值,因为可能存在两个样本受此故障影响的情况。也许还有其他一些方法可以修复这些毛病数据,而不仅仅是解决它!

这样做的最佳方式是什么?这是我到目前为止的代码(这是在DataReceivedEvent方法中):

SerialPort sp = (SerialPort)sender; //set up serial port
byte[] spBuffer = new byte[4];
int indata = 0;

sp.Read(spBuffer, 0, 4);
indata = BitConverter.ToUInt16(spBuffer, 1);

object[] o = { numSamples, nudDutyCycle.Value, freqMultiplied, nudDistance.Value, pulseWidth, indata };
lock (dt)    //lock for multithread safety
{
    dt.Rows.Add(o); //add data to datatable
}

3 个答案:

答案 0 :(得分:1)

工程中的常用方法是添加阻尼功能。阻尼函数基本上作用于参数的微分,即连续值之间的差。关于如何选择阻尼函数没有严格的规则,大多数都是经过调整以产生合理的结果。

因此,在您的情况下,这意味着您将最新值与之前的值进行比较。如果它大于某个数量,则将最新值默认为前一个值,或者将最新值减少某个固定因子,例如10%或1%。这样你就不会丢失信息,但也没有突然的跳跃和故障。

答案 1 :(得分:1)

我怀疑你的问题可能是因为你从串口读取的字节数比你想象的少。

例如,sp.Read(spBuffer, 0, 4);不一定读取4个字节。它可以读取1,2,3或4个字节(但从不为0)。

如果您知道您应该读取一定数量的字节,请尝试以下方法:

public static void BlockingRead(SerialPort port, byte[] buffer, int offset, int count)
{
    while (count > 0)
    {
        // SerialPort.Read() blocks until at least one byte has been read, or SerialPort.ReadTimeout milliseconds
        // have elapsed. If a timeout occurs a TimeoutException will be thrown.
        // Because SerialPort.Read() blocks until some data is available this is not a busy loop,
        // and we do NOT need to issue any calls to Thread.Sleep().

        int bytesRead = port.Read(buffer, offset, count);
        offset += bytesRead;
        count -= bytesRead;
    }
}

如果在阅读过程中出现超时,则应该有TimeoutException,因此无需在此处设置超时。

然后改变这样的呼叫:

sp.Read(spBuffer, 0, 4);

对此:

BlockingRead(sp, spbuffer, 0, 4);

答案 2 :(得分:1)

首先,我强烈建议只修复解析问题,然后你不必担心毛刺值。

但是,如果你仍然决定继续修复数据的路线: 我看到所有的glitched数据都在某个值附近:~16000。事实上,从图表来看,我说它每次都几乎相同。您可以简单地忽略处于glitched值范围内的数据(您必须进行一些测试才能找到确切的边界),并使用最后一个非glitched值。