平均串行数据流值

时间:2013-06-16 07:56:30

标签: c# stream serial-port buffer average

我有大约数据流。 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个样本,同时必须提供对其他功能的控制? 样品代码将非常感激。

1 个答案:

答案 0 :(得分: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个此实例。由于所有Seri​​alPort数据都将在同一个线程上发生,因此您只需在处理事件时进行同步。

更新

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

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;
    }

}