繁体   English   中英

来自传入串行数据的移动平均值 C#/.NET

[英]Moving average from incoming serial data C#/.NET

我有一个程序,它从 Arduino UNO R3 读取模拟数据并将该数据发送到其他设备,该设备读取它并相应地执行一些操作。 目前,每次我读取数据时,它都会被发送,这会创建比执行任务所需的更多的数据点。 因此,我想将数据集中在一个移动平均线中,而不是一起发送。 我的代码现在看起来像这样:

string forceAnalog = recieveData.Text;
recieveData.Clear();
var forceList = forceAnalog.ToUpper().Split(':').ToList();
foreach (var item in forceList)
    if (item.Trim().StartsWith("X"))
    {
        textBoxX.Text = item.Remove(0, 1);
    }
    else if (item.Trim().StartsWith("Y"))
    {
        textBoxY.Text = item.Remove(0, 1);
    }
    else if (item.Trim().StartsWith("Z"))
    {
        textBoxZ.Text = item.Remove(0, 1);
    }

string forceXanalog = textBoxX.Text;
string forceYanalog = textBoxY.Text;
string forceZanalog = textBoxZ.Text;

if (double.TryParse(forceXanalog, out forceX)) ;
if (double.TryParse(forceYanalog, out forceY)) ;
if (double.TryParse(forceZanalog, out forceZ)) ;

forceXvalue = (forceX * calibrationFactorX / 1023) - 5;
forceYvalue = (forceY * calibrationFactorY / 1023) - 5;
forceZvalue = (forceZ * calibrationFactorZ / 1023) - 50;

this.forceXlabel.Text = string.Format("{0:F2}", forceXvalue);
this.forceYlabel.Text = string.Format("{0:F2}", forceYvalue);
this.forceZlabel.Text = string.Format("{0:F2}", forceZvalue);

我从接收 Arduino 序列号 stream 的文本框中读取数据,并从中创建 forceAnalog 字符串。 该字符串包含 X、Y、Z 值,类似于:X-0.44 Y-0.15 Z-0.5 然后 receiveData 被清除并再次读取值。 然后通过一些计算将其发送到标签。

我想要的是,而不是读取、存储一组 X、Y、Z 值并将其传递,我想读取例如 5,10,100... 组 X、Y、Z 值,然后创建从这些中取平均值并将其传递以进行计算。 我 go 如何做到这一点?

最简单的选择是累积 n 个项目,发送平均值,然后重置累加器和计数。 对 Vector3 使用迭代器块和 system.Numerics:

public static IEnumerable<Vector3> AverageN(
    this IEnumerable<Vector3> highFrequencySamples,
    int everNthSample)
{
    var acc = Vector3.Zero;
    var n = 0;
    foreach (var sample in highFrequencySamples)
    {
        acc += sample;
        n++;
        if (n == everNthSample)
        {
            // Output the average since we have reached the number of samples needed
            yield return acc / n;
            acc = Vector3.Zero;
            n = 0;
        }
    }

    if (n > 0)
    {
        yield return acc / n;
    }
}

虽然 Vector3 这仅限于浮点数,但使用双精度创建等效的Vector3d应该相当简单。 使用专用类型来捆绑坐标值往往会使您的代码更简单,因为您不必将每个操作重复三次。 如果他们设法发布类似通用数学的东西,您可以制作一个像这样通用的方法,并且适用于支持加法和除法的所有类型。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM