【问题标题】:C# Signal Processing Plotting Rapid DataC# 信号处理绘制快速数据
【发布时间】:2013-10-11 08:42:07
【问题描述】:

我有一个电路,可以从传感器向我发送两个不同的数据。数据以数据包的形式出现。第一个数据是“$”,用于将一个数据包分隔到另一个数据包。在“$”之后,它发送 16 个字节的麦克风数据和 1 个字节的脉冲传感器数据。我有一个数组来存储传入的数据,在每 20 毫秒绘制一次数据后,我开始从数组的零索引写入新字节。我需要使用 ZedGraph 将这些数据绘制到不同的图表中。但是我无法正确分离这些数据。有时,一个或多个音频数据会显示在其他图表中。这是我的代码:

        for (int i = 0; i < 4; i++)
        {
            if (data[i * 18] == Convert.ToByte('$'))
            {
                for (int x = ((i * 18) + 1); x < ((i * 18) + 17); x++)
                {
                    listAuido.Add(time, data[x]);
                }
                for (int a = ((i * 18) + 17); a < ((i * 18) + 18); a++)
                {
                    listPulse.Add(time, data[a]);
                }
            }
        }

我该如何解决这个问题?

电路设置:波特率:38400,频率:200hz,通信类型:RS232。

端口设置:ReadTimeOut=5 WrtieTimeOut=5;

在读取数据时,我使用以下代码。 Read_Data1 引用 data[] 上面的代码。我有一个计数器,在绘制数据后它的值为零,我阻止了我的缓冲区index out of range exception

    byte[] Read_Data1 = new byte[1000];
    private void myPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
    {
        if (!myPort.IsOpen)
            return;
        if (myPort.BytesToRead > 0)
        {
            byte[] buffer = new byte[myPort.BytesToRead];
            myPort.Read(buffer, 0, buffer.Length);
            DataConversion.bytetobyte(Read_Data1, buffer, buffer.Length, count);
            count += buffer.Length;
            DataRecord.SaveBytesToFile(buffer, save.FileName);
        }
    }

    public static void bytetobyte(byte[] Storage, byte[] databyte, int datacount, int count)
    {
        int abc;
        for (abc = 0; abc < datacount; abc++)
        {
            Storage[abc + count] = databyte[abc];
        }
    }

【问题讨论】:

    标签: c# plot signal-processing zedgraph data-processing


    【解决方案1】:

    如果没有看到数据流,很难准确理解发生了什么,但是当你乘以 18 时,偏移量会随着 i 的增加而不同。为了使其工作,您需要确保此时缓冲区中实际上正好有 4 个数据包,否则事情可能会变得很奇怪。在使用 rs232 连接的测量硬件进行了大量工作后,我经常发现他们的软件并不是那么一致,所以我会小心假设数据在那里:)

    查看您将数据读取到data 缓冲区的方式和时间,您确定每次调用代码时它都包含新数据吗?

    循环看起来是正确的,但它有点难以阅读,我会重写它

        for (int i = 0; i < 4; i++)
        {
            if (data[i * 18] == Convert.ToByte('$'))
            {
                for (int x = 0; x < 16; x++)
                {
                    listAuido.Add(time, data[(i * 18) +1 + x]);
                }
                for (int a = 0; a < 1; a++) // this doesn't really need to be a loop
                {
                    listPulse.Add(time, data[ ((i * 18) + 17)+ a]);
                }
            }
    

    我查看了您添加的代码,但不清楚第二个代码如何调用第一位代码。我仍然认为缓冲区处理存在问题导致您的问题,但您可以消除它,但使用串行端口内置的缓冲区并且当时只有一个字节:

    while(true){  //you could do this on a separate thread or on a timer
        if(port.ReadByte() == Convert.ToByte('$')){
            for (int x = 0; x < 16; x++)
                listAuido.Add(time, port.ReadByte());
            listPulse.Add(time, port.ReadByte());
        }
    }
    

    【讨论】:

    • 频率为 200 赫兹,因此 1 秒/200 赫兹 = 5 毫秒。数据每 5 毫秒出现一次,但我每 20 毫秒绘制一次数据。所以我认为一定有偏差。此外,当我放置一些断点时,缓冲区大小看起来比数据包大小更大。
    • 如果不了解您如何读取数据,很难对此发表评论,但端口会缓冲所有进入其中的数据
    • 感谢简化我的代码。我编辑了我的代码以显示我是如何读取数据的。如果你能看一下,我会很高兴。
    猜你喜欢
    • 1970-01-01
    • 2014-02-19
    • 1970-01-01
    • 2015-04-28
    • 2011-09-30
    • 1970-01-01
    • 1970-01-01
    • 2021-09-07
    • 1970-01-01
    相关资源
    最近更新 更多