我正在尝试创建一个函数来查找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/