我正在尝试创建一个函数来查找Arduino上传感器值的平均值以对其进行校准,但是求和不能正常工作,因此平均值不正确。下表显示了输出示例。左列应该是显示在右列中的输出的滚动总和(负数如何进入那里?)

-10782      17112
  6334      17116
 23642      17308
-24802      17092
 -7706      17096
  9326      17032
 26422      17096
-21986      17128


calibrateSensors()函数(应该执行此功能)如下所示

void calibrateSensors(int16_t * accelOffsets){

  int16_t rawAccel[3];
  int sampleSize = 2000;


  Serial.println("Accelerometer calibration in progress...");

  for (int i=0; i<sampleSize; i ++){

    readAccelData(rawAccel);        // get raw accelerometer data
    accelOffsets[0] += rawAccel[0]; // add x accelerometer values
    accelOffsets[1] += rawAccel[1]; // add y accelerometer values
    accelOffsets[2] += rawAccel[2]; // add z accelerometer values
    Serial.print(accelOffsets[2]);
    Serial.print("\t\t");
    Serial.print(rawAccel[2]);
    Serial.print("   \t FIRST I:");
    Serial.println(i);
  }

  for (int i=0; i<3; i++)
  {
    accelOffsets[i] = accelOffsets[i] / sampleSize;
    Serial.print("Second I:");
    Serial.println(i);
  }

  Serial.println("Accelerometer calibration complete");
  Serial.println("Accelerometer Offsets:");
  Serial.print("Offsets (x,y,z): ");
  Serial.print(accelOffsets[0]);
  Serial.print(", ");
  Serial.print(accelOffsets[1]);
  Serial.print(", ");
  Serial.println(accelOffsets[2]);
}


readAccelData()函数如下

void readAccelData(int16_t * destination){
  // x/y/z accel register data stored here
  uint8_t rawData[6];
  // Read the six raw data registers into data array
  I2Cdev::readBytes(MPU6050_ADDRESS, ACCEL_XOUT_H, 6, &rawData[0]);
  // Turn the MSB and LSB into a signed 16-bit value
  destination[0] = (int16_t)((rawData[0] << 8) | rawData[1]) ;
  destination[1] = (int16_t)((rawData[2] << 8) | rawData[3]) ;
  destination[2] = (int16_t)((rawData[4] << 8) | rawData[5]) ;


知道我要去哪里错了吗?

最佳答案

您有两个问题:


您不初始化数组。它们以其中的垃圾数据开始(已分配空间,但未清除)。您可以通过执行以下操作将数组初始化为全零:


int array[5] = {};

这将导致最初看起来像[0,0,0,0,0]的数组

第二个问题是您要创建一个由16位带符号整数组成的数组。
16位整数可以存储65536个不同的值。问题在于,由于您使用的是带符号类型,因此只能使用32767个正整数值。当您尝试存储一个更大的值时,您正在溢出并得到负数。

我相信arduino支持32位整数。如果只需要正数,请使用无符号类型。

要使用显式的32位整数:

#include <stdint.h>
int32_t my_int = 0;


有关标准变量大小的一些信息(请注意,根据代码所针对的arduino模型,它们可以是不同的大小):

https://www.arduino.cc/en/Reference/Int


  在Arduino Uno(以及其他基于ATMega的板上)上,一个int存储一个
  16位(2字节)值。这样产生的范围是-32,768到32,767
  (最小值为-2 ^ 15,最大值为(2 ^ 15)-1)。在
  基于Arduino Due和SAMD的板(例如MKR1000和Zero)
  存储一个32位(4字节)值。这产生了-2,147,483,648的范围
  到2,147,483,647(最小值-2 ^ 31和最大值(2 ^ 31))
  -1)。


https://www.arduino.cc/en/Reference/UnsignedInt


  在Uno和其他基于ATMEGA的板上,未签名的整数(未签名
  整数)与int相同,因为它们存储2个字节的值。
  而不是存储负数,但是它们只存储正数
  值,有效范围为0到65,535(2 ^ 16)-1)。
  
  Due存储4字节(32位)值,范围从0到
  4,294,967,295(2 ^ 32-1)。


https://www.arduino.cc/en/Reference/UnsignedLong


  无符号长变量是数字的扩展大小变量
  存储,并存储32位(4字节)。不同于标准的多头无符号
  多头不会存储负数,范围从0到
  4,294,967,295(2 ^ 32-1)。

关于c++ - Arduino代码无法正确添加数字,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/44627894/

10-09 08:45
查看更多