0

我大约有一个数据流。500 Hz 来自串行端口。数据由控制机器的微处理器发送。数据被一个类过滤掉并显示在不同的文本框中,该类去除了传输协议使用的标题字符。这是将我得到的四个变量分配给不同文本框的代码。

private void SetText(string text)
    {
        if (this.txtOutput.InvokeRequired)
        {
            SetTextCallback d = new SetTextCallback(SetText);
            this.BeginInvoke(d, new object[] { text });
        }
        else
        {
            txtOutput.AppendText(text + "\r\n");
            string a = "", b = "", c = "", d="";
            string invia = text.ToString();
            Stripper strp = new Stripper();
            strp.Distri(invia, out a, out b, out c, out d);
            if (a != "")
            {
                textBox7.Text = a; //currentRes
            }
            if (b != "")
            {
                textBox2.Text = b; //temperature
            }

            if (d != "" )
            {
             textBox3.Text = d; //motor current
            }

            if (c == "1\r") //motor RPM
            {
                timer3.Start();
            }
        }
    }

我面临的问题是我每秒得到数百个值“a”、“b”和“d”,显然相关的文本框正在闪烁。此外,我想平均每个变量的值,每个变量取 100 个样本,然后在相关文本框中显示它们。这将避免闪烁并给出更准确的读数。

如何在不冻结同时必须为其他功能提供控制的应用程序的情况下将每个变量“a”、“b”和“d”平均到 x 个样本?示例代码将不胜感激。

4

1 回答 1

1

取 100 个样本的每个变量的平均值……会给出更准确的读数

那么这个数字 100 是从哪里来的,仅仅是来自 GUI 设计还是与数据有某种关联?

您是要平均独立(相邻)块还是需要移动平均线?

一个简单的方法:

class Accum
{
    private int sum, count;

    public event AverageChanged; 

    public void Add(int value)
    {
       sum += value;
       count += 1;
       if (count >= 100)
       {
           OnAvarerageChanged(sum/count);
           sum = 0;
           count = 0;
       }
    }

    ....

}

您将需要在表单上创建 3 个此实例。由于所有 SerialPort 数据都将发生在同一个线程上,因此您只需要在处理事件时进行同步。

更新:

最简单但不太通用的方法:

class Accum
{
    private int sum, count;

    //public event AverageChanged; 

    public void Add(int value)
    {
       sum += value;
       count += 1;
       if (count >= 100)
       {
           OnAvarerageChanged(sum/count);
           sum = 0;
           count = 0;
       }
    }

    public Label MyLabel { get; set; }

    private void OnAvarerageChanged(int av)
    {
        SetTextCallback d = new SetTextCallback(SetText);
        string text = av.ToString();
        MyLabel.BeginInvoke(d, new object[] { text });
    }

    private void SetText(string text)
    {
        this.MyLabel.Text = text;
    }

}
于 2013-06-16T08:09:00.210 回答