【问题标题】:Getting an average from values obtained by a sensor using C使用 C 从传感器获得的值中获取平均值
【发布时间】:2011-12-10 00:05:17
【问题描述】:

好的,我得到这段代码来做平均:(用 C 编写)

.
.
        int sum[3];
        int j;
        int avg;
      for(;;) //infinite loop
      {
       for(j=0;j<3;j++){
        i = ReadSensor(); // function that keeps saving sensor values as int i
        sum[j]=i;
        }
       avg=sum[0]+sum[1]+sum[2]+sum[3]; 
       printf("Sonar: %d \r \n", avg >> 2);
      }
.
.

这是正确的吗?我移动 2 以除以 avg / 2^(2) 即 4 问题是我期望值约为 15,但我得到约 8--9 .. 我不知道为什么会这样?

基本上传感器的读数在 15-17 之间波动,我想获得平均值而不是打印噪声值。我的代码正确吗?那为什么我会得到错误的输出!?

【问题讨论】:

  • 虽然使用 shift 确实是除以 2 的幂的一种有效方法,但您应该注意,几乎所有现代编译器都会自动处理这种替换,提供与您编写的相同的性能更明显的 avg/2
  • 谢谢,那我就用除法运算符了。
  • @TJD 一些嵌入式 C 编译器的优化有限。 Fendi,你打算用什么编译器编译?你打算在什么硬件上运行它(PC、PIC、AVR、Arduino 等)?也将这些添加为标签。

标签: c arrays sensors average


【解决方案1】:

您的脚本似乎只捕获 三个 值(j=0、j=1、j=2),然后除以 4。

【讨论】:

  • 哦!它应该是 for(j=0;j
  • 或 for(j=0;j
  • 好的,谢谢。我会在这里尝试所有答案,并将最佳答案标记为正确。
【解决方案2】:

你有一些问题,这里有一些建议:

  • 您正在迭代内部循环 3 次,但是您说您有 4 个传感器,您应该将您的 for 循环更改为:for (j = 0; j &lt; 4; j++)
  • sum 是一个包含 3 个元素的数组,但在计算 avg (sum[3]) 时,您正在访问数组末尾之后的元素 1。这将导致未定义的行为。由于这个原因和上述原因,sum 应声明为 char sum[4]
  • (可选)sum 在上面的例子中不需要是一个数组,它可以简单地是一个int
  • (可选)如果要将int 除以4,请使用除法运算符。编译器应该比你更擅长为你的特定架构优化代码。

这就是您的代码现在的样子,具体取决于您是否需要保留一个数组:

int sum[4];
int total, j;

for (;;)
{    
   total = 0; /* reset at every iteration of the outside loop */   

   for (j = 0; j < 4; j++) {
      sum[i] = ReadSensor();
      total += sum[i];
   }

   printf("Sonar: %d \r \n", total / 4);
}

int total, j;

for (;;)
{    
   total = 0; /* reset at every iteration of the outside loop */   

   for (j = 0; j < 4; j++)
      total += ReadSensor();

   printf("Sonar: %d \r \n", total / 4);
}

【讨论】:

  • 感谢您的回复,我一到实验室就试试这个。
【解决方案3】:

这不是

avg=sum[0]+sum[1]+sum[2]+sum[3];

应该是

avg=sum[0]+sum[1]+sum[2];

作为循环以及声明 int sum[3]; 意味着我们试图只存储 3 个值。

现在,如果您想要 4 并且可以使用除法运算符。有应该替换提到的行的新代码

int sum[4];

for(j=0;j<4;j++)

avg=sum[0]+sum[1]+sum[2]+sum[3]; // this part stays the same

【讨论】:

    【解决方案4】:

    从传感器读取的值的数量需要两次。首先,控制for循环的迭代次数。第二,作为和的除数。引入一个变量(比如N)来捕获它。

    此外,移位除法听起来也不正确,因为这会将传感器的读数数量限制为 2 的幂。

    enum { N = 4 };
    
    sum = 0;
    for( j = 0; j < N; j++) {
       i = ReadSensor(); // function that keeps saving sensor values as int i
       sum += i;
    }
    avg = sum / N; 
    printf( "Sonar average: %d\n", avg );
    

    【讨论】:

    • 感谢您的回复,我到实验室会试试这个。 im shift 的原因是因为微控制器不喜欢除法、乘法、浮点数等。所以最好使用按位运算符。但是,“将传感器的读数数量限制为 2 的幂”是什么意思。无论如何?
    • @Fendi:移位以便除法意味着您只能除以 0、1、2、4、8、16 等 - 所有 2 的幂。您不能简单地移位为了除以 5 - 这就是 ArunSaha 所说的。但是,您可以通过位移和减法除以 5,因此您可以在不使用除法指令的情况下进行操作。
    • 哦,我明白了,谢谢你的解释.. 但我只需要除以 4,所以对于这种情况来说没问题。
    猜你喜欢
    • 2015-09-11
    • 1970-01-01
    • 2021-05-30
    • 2021-09-25
    • 2011-09-20
    • 2011-06-03
    • 1970-01-01
    相关资源
    最近更新 更多