Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/visual-studio-2012/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 简单移动平均总和/抵销问题_Algorithm_Basic_Moving Average_Embedded Control - Fatal编程技术网

Algorithm 简单移动平均总和/抵销问题

Algorithm 简单移动平均总和/抵销问题,algorithm,basic,moving-average,embedded-control,Algorithm,Basic,Moving Average,Embedded Control,我写了一个简单的移动平均值,其中温度的移动窗口读数为0到10V之间的电压 该算法似乎工作正常,但是,它存在一个问题,即根据窗口中首先填充的温度,移动平均值将有一个不接近该值的任何值的偏移。例如,使用temp运行此程序。插入室温的传感器产生4.4伏或21.3摄氏度,但如果我拔下温度。传感器电压降至1.4V,但移动平均值保持在1.6V。当我增加窗口的大小时,该偏移会变小。如何消除这种偏移,即使是小窗户尺寸,如20 REM SMA Num Must be greater than 1 #DEFINE

我写了一个简单的移动平均值,其中温度的移动窗口读数为0到10V之间的电压

该算法似乎工作正常,但是,它存在一个问题,即根据窗口中首先填充的温度,移动平均值将有一个不接近该值的任何值的偏移。例如,使用temp运行此程序。插入室温的传感器产生4.4伏或21.3摄氏度,但如果我拔下温度。传感器电压降至1.4V,但移动平均值保持在1.6V。当我增加窗口的大小时,该偏移会变小。如何消除这种偏移,即使是小窗户尺寸,如20

REM SMA Num Must be greater than 1
#DEFINE SMANUM 20
PROGRAM
'Program 3 - Simple Moving Average Test
CLEAR
DIM SA(1)
DIM SA0(SMANUM) : REM Moving Average Window as Array
DIM LV1
DIM SV2
LV0 = 0 : REM Counter
SV0 = 0 : REM Average
SV1 = 0 : REM Sum
WHILE(1)
    SA0(LV0 MOD SMANUM) = PLPROBETEMP : REM add Temperature to head of window
    SV1 = SV1 + SA0(LV0 MOD SMANUM) : REM add new value to sum
    IF(LV0 >= (SMANUM)) : REM check if we have min num of values
        SV1 = SV1 - SA0((LV0+1) MOD SMANUM) : REM remove oldest value from sum
        SV0 = SV1 / SMANUM : REM calc moving average
        PRINT "Avg: " ; SV0 , " Converted: " ; SV0 * 21.875 - 75
    ENDIF
    LV0 = LV0 + 1 : REM increment counter
WEND
ENDP
(请注意,这是Parker用ACROBASIC为ACR9000编写的)

输出-温度传感器已连接

Raw: 4.43115    Avg: 4.41926     Converted: 21.6713125
Raw: 4.43115    Avg: 4.41938     Converted: 21.6739375
Raw: 4.43359    Avg: 4.41963     Converted: 21.67940625
Raw: 4.43359    Avg: 4.41987     Converted: 21.68465625
Raw: 4.43359    Avg: 4.42012     Converted: 21.690125
Raw: 4.43359    Avg: 4.42036     Converted: 21.695375
Raw: 4.43359    Avg: 4.42061     Converted: 21.70084375
…在程序运行时卸下温度传感器

Raw: 1.40625    Avg: 1.55712     Converted: -40.938
Raw: 1.40381    Avg: 1.55700     Converted: -40.940625
Raw: 1.40625    Avg: 1.55699     Converted: -40.94084375
Raw: 1.40625    Avg: 1.55699     Converted: -40.94084375
Raw: 1.40381    Avg: 1.55686     Converted: -40.9436875
Raw: 1.40381    Avg: 1.55674     Converted: -40.9463125
Raw: 1.40625    Avg: 1.55661     Converted: -40.94915625
Raw: 4.43848    Avg: 4.28554     Converted: 18.7461875
Raw: 4.43848    Avg: 4.28554     Converted: 18.7461875
Raw: 4.43848    Avg: 4.28554     Converted: 18.7461875
Raw: 4.43848    Avg: 4.28554     Converted: 18.7461875
Raw: 4.43848    Avg: 4.28554     Converted: 18.7461875
Raw: 4.43359    Avg: 4.28530     Converted: 18.7409375
移除传感器后,原始平均值和移动平均值之间出现明显偏移

偏移也按相反的顺序发生:

输出-开始程序,温度传感器已拆除

Raw: 1.40381    Avg: 1.40550     Converted: -44.2546875
Raw: 1.40625    Avg: 1.40550     Converted: -44.2546875
Raw: 1.40625    Avg: 1.40549     Converted: -44.25490625
Raw: 1.40625    Avg: 1.40549     Converted: -44.25490625
Raw: 1.40625    Avg: 1.40548     Converted: -44.255125
Raw: 1.40625    Avg: 1.40548     Converted: -44.255125
。。。程序运行时连接温度传感器

Raw: 1.40625    Avg: 1.55712     Converted: -40.938
Raw: 1.40381    Avg: 1.55700     Converted: -40.940625
Raw: 1.40625    Avg: 1.55699     Converted: -40.94084375
Raw: 1.40625    Avg: 1.55699     Converted: -40.94084375
Raw: 1.40381    Avg: 1.55686     Converted: -40.9436875
Raw: 1.40381    Avg: 1.55674     Converted: -40.9463125
Raw: 1.40625    Avg: 1.55661     Converted: -40.94915625
Raw: 4.43848    Avg: 4.28554     Converted: 18.7461875
Raw: 4.43848    Avg: 4.28554     Converted: 18.7461875
Raw: 4.43848    Avg: 4.28554     Converted: 18.7461875
Raw: 4.43848    Avg: 4.28554     Converted: 18.7461875
Raw: 4.43848    Avg: 4.28554     Converted: 18.7461875
Raw: 4.43359    Avg: 4.28530     Converted: 18.7409375

附加传感器后,原始平均值和移动平均值之间再次出现明显偏移。

问题似乎在于,从总和中减去的值实际上不是数组中最早的值——最早的值实际上被
循环中第一行的新值覆盖。这是从总和中减去的第二个最古老的值

根据OP的建议,编辑将平均值和总和变量更改为64位浮点,以解决随时间推移的精度损失问题

确保先减去最早的值(一旦数组已满),即可得到预期的答案:

PROGRAM
'Program 3 - Simple Moving Average Test
CLEAR
DIM SA(1)
DIM SA0(SMANUM) : REM Moving Average Window as Array
DIM LV1
DIM DV2
LV0 = 0 : REM Counter
DV0 = 0 : REM Average
DV1 = 0 : REM Sum
WHILE(1)
    IF(LV0 >= (SMANUM)) : REM check if we have min num of values
        DV1 = DV1 - SA0(LV0 MOD SMANUM) : REM remove oldest value from sum
    ENDIF
    SA0(LV0 MOD SMANUM) = PLPROBETEMP : REM add Temperature to head of window
    DV1 = DV1 + SA0(LV0 MOD SMANUM) : REM add new value to sum
    IF(LV0 >= (SMANUM)) : REM check if we have min num of values
        DV0 = DV1 / SMANUM : REM calc moving average
        PRINT "Avg: " ; DV0 , " Converted: " ; DV0 * 21.875 - 75
    ENDIF
    LV0 = LV0 + 1 : REM increment counter
WEND

我没有一个运行的基本环境,但我在Python中测试了它,得到了与您的版本相同的错误代码输出,以及与我上面插入的版本相同的预期代码输出

这与VBA有什么关系?错误标记。谢谢,我已经更新了。非常感谢,这是解决方案。您是对的,当我获得新温度时,我正在覆盖最旧的值。这件事我已经忙了好一阵子了,再次谢谢你。看来我可能是逃之夭夭了。我仍然注意到原始平均线和移动平均线之间有一个小的偏移。例如:
Raw:4.55322平均值:4.42033
,约为
2.9C
关闭。明天我将做一些进一步的调查,并在这里用我的发现进行评论。你可以像我一样尝试测试代码,将一系列电压放入一个数组(比如,
V
),然后从
V(LV0)
读取每个电压。这样,我可以使
V
的前半部分的值等于(比如说)
1
,使
V
的后半部分的值等于(比如说)
5
,并观察基于输入值的一致阶梯序列输出的移动平均值。另一种方法是每次计算数组
SA0
中的值之和,并将其与
SV1
进行比较。这对于生产使用来说可能不够快,但可能有助于发现任何剩余的bug。感谢Simon,我用C#重写了算法,并确认您的答案中的窗口索引是正确的。我让基本版本在控制器上运行了一夜,并注意到偏移量随着时间的推移而增加。我怀疑sum变量SV1的精度有所下降,它随时间增加偏移量。由于这些是32位浮点数,您认为移动到64位浮点数会解决这个问题吗?这可能是一个精度损失问题,因为在温度转换中减去
75
会损失32位中的略多于8位。因此,将总和保持在摄氏度而不是原始单位可能会大大减少精度损失。或者,我希望移动到64位浮点将解决这个问题。或者,您可以每隔几百个周期从数组中定期重新计算
SV0
,这将重置逐渐丢失的精度。