0

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

数字以格式发送<uint16>,包括“<”和“>”符号,以二进制格式传输,00111100 XXXXXXXX XXXXXXXX 00111110其中“X”构成 16 位无符号整数。

有时读取不会很好,程序使用“>”符号的二进制数据作为其数字的一部分,导致出现故障,如 2500 个样本的截图所示(忽略样本 800 到 1500 之间的下降,即我在玩 ADC 输入吗):

截屏

您可以清楚地看到,故障导致数据在每次发生时都对大致相同的值进行采样。

数据每秒发送 10 次,所以我计划做的是取 10 个样本,消除任何毛刺(值远离其他样本的地方),然后平均剩余的值以稍微平滑曲线. 输出可以从 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
}
4

3 回答 3

1

工程中常用的方法是添加阻尼函数。阻尼函数基本上作用于参数的微分,即连续值之间的差异。关于如何选择阻尼函数并没有硬性规定,而且大多数情况下都会对它们进行调整以产生合理的结果。

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

于 2016-02-18T10:12:43.943 回答
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);
于 2016-02-18T10:16:01.030 回答
1

首先,我强烈建议只修复解析问题,然后您就不必担心故障值。

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

于 2016-02-18T10:22:12.083 回答