gpt4 book ai didi

c - 使用循环缓冲区数组实现运行平均值

转载 作者:行者123 更新时间:2023-12-04 11:35:15 28 4
gpt4 key购买 nike

我正在尝试实现一个循环缓冲区,以便对在嵌入式 Controller 上运行的 C 语言中的压力传感器生成的数据点流进行平均。这个想法是将最后 N 个压力读数存储在缓冲区中,同时保持缓冲区的运行总和。平均值 = 总和/N。应该是微不足道的。

但是,我看到的平均值是一个开始接近压力读数的值(我用典型值预加载缓冲寄存器),但随后趋向于零。如果我也显示总和,它也会逐渐下降到零。如果压力发生变化,则平均值会沿着压力变化的方向远离零,但一旦压力稳定就会回到零趋势。

如果有人能发现我犯的错误,那将非常有帮助。

    #define ARRAYSIZE 100

double Sum; // variable for running sum
double Average; // variable for average
double PressureValue[ARRAYSIZE]; // declare value array
int i; // data array index

int main(void) {

while (1)
{
if (i == ARRAYSIZE) i = 0; // test index, reset if it reaches the upper boundary
Sum = Sum - PressureValue[i]; // subtract the old datapoint from running sum
PressureValue[i] = PRESSURE; // replace previous loop datapoint with new data
Sum = Sum + PressureValue[i]; // add back the new current value to the running sum
Average = Sum / ARRAYSIZE; // calculate average value = SUM / ARRAYSIZE
++i; // increment index
} // end while loop

} // end main

平均代码发生在中断处理程序中;我正在通过 I2C 从压力传感器读取数据,并在每个 I2C 通信阶段结束时触发中断。在最后一个阶段,在检索到包含压力数据的四个字节后,将它们组合成一个完整的读数,然后转换为 PRESSURE 变量中包含的 PSI 中的十进制读数。

显然,这不是从我的代码中直接剪切和粘贴的,但我不想让任何人费力地完成整个过程,所以我将其限制为仅与计算平均值相关的内容,并将变量名更改为更具可读性。尽管如此,我还是看不出我做错了什么。

感谢您的关注!

道格·G。

最佳答案

我没有看到您的代码有任何明显的错误,但正如您所说,您没有提供所有代码,所以谁知道其余部分发生了什么(特别是,如何/如果您正在初始化iSum),但以下对我来说工作正常,这基本上与您的算法相同:

#include <stdio.h>
#include <stddef.h>

double PressureValue[8];
double Pressures[800];

int main(void) {
const size_t array_size = sizeof(PressureValue) / sizeof(PressureValue[0]);
const size_t num_pressures = sizeof(Pressures) / sizeof(Pressures[0]);
size_t count = 0, i = 0;
double average = 0;


/* Initialize PressureValue to {0, 1, 2, 3, ...} */

for ( size_t n = 0; n < array_size; ++n ) {
PressureValue[n] = n;
}
double sum = ((array_size - 1) / (double) 2) * array_size;

/* Initialize pressures to repeats of PressureValue */

for ( size_t n = 0; n < num_pressures; ++n ) {
Pressures[n] = n % array_size;
}

while ( count < num_pressures ) {
if ( i == array_size )
i = 0;
sum -= PressureValue[i];
PressureValue[i] = Pressures[count++];
sum += PressureValue[i++];
}

average = sum / array_size;

printf("Sum is %f\n", sum);
printf("Counted %zu pressures\n", count);
printf("Average is %f\n", average);

return 0;
}

输出:

paul@local:~/src/c/scratch$ ./pressure
Sum is 28.000000
Counted 800 pressures
Average is 3.500000
paul@local:~/src/c/scratch$

还有一种可能性,当您说它们“转换为 PRESSURE 变量中包含的 PSI 中的十进制读数”时,在其他地方,就此而言,请确保您没有得到任何东西由于整数除法而被截断为零。如果您在添加更多内容时出现“趋向于零”的情况,我会立即对此表示怀疑。例如,将华氏温度转换为摄氏温度的一个典型错误是编写 c = (f - 32) * (5/9),其中 (5/9) 每次都截断为零,并且总是留给您 c == 0

此外,作为一般规则,我知道您“不希望任何人不得不费力完成整个事情”,但您会惊讶于有多少次真正的问题不在代码部分你认为是的。这就是为什么提供 SSCCE 很重要的原因。以确保您可以缩小代码范围并实际隔离和重现问题。如果您尝试缩小代码范围并发现您无法 隔离和重现问题,那么几乎可以肯定您的问题不是由您认为的原因引起的。

关于c - 使用循环缓冲区数组实现运行平均值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19602224/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com