MPU-6050 Arduino libraries code archaeology
2025-Mar-19, Wednesday 02:40 pm![[personal profile]](https://www.dreamwidth.org/img/silk/identity/user.png)
Compare and contrast getting normalized accelerometer values, where the raw value is -13248.00. (A.k.a. Please, make it make sense.)
Library 1; jarzebski's Arduino-MPU6050 - https://github.com/jarzebski/Arduino-MPU6050/
Library 2; Adafruit's Adafruit_MPU6050 - https://github.com/adafruit/Adafruit_MPU6050
Library 3; i2cdevlib/ElectronicCats' mpu6050 - https://github.com/ElectronicCats/mpu6050
Formula for normalized acceleration value at MPU6050_RANGE_2G;
raw * rangePerDigit * gravityConst
(raw * (1.0/16384)) * gravityConst
== (raw / 16384) * gravityConst
(-13248.00 * .000061) * 9.80665 = -7.92502845
== (-13248.00 / 16384) * 9.80665 = -7.92959589
Formula for normalized acceleration value at MPU6050_RANGE_2_G;
(raw / accel_scale) * gravityConst
(-13248.00 / 16384) * 9.80665 = -7.92959589
No normalized functions in MPU6050.cpp. Can use MotionApps files, but they go through Quaternions.
Formula for normalized acceleration value at MPU6050_ACCEL_FS_2;
// jarzebski way;
raw * accelerationResolution * gravityConst
-13248.00 * 0.000122 * 9.80665 = -15.850057
// adafruit way;
// (raw * (1.0/16384)) * gravityConst
// (raw * (2.0/16384)) * gravityConst
(-13248.00 / (2.0*16384)) * 9.80665 = -15.85919
((-13248.00*2.0) / 16384) * 9.80665 = -15.85919
Result is twice that of the others.
raw * (accelerationResolution/2) * gravityConst
-13248.00 * (accelerationResolution/2) * 9.80665 = -7.9250
Library 1; jarzebski's Arduino-MPU6050 - https://github.com/jarzebski/Arduino-MPU6050/
Library 2; Adafruit's Adafruit_MPU6050 - https://github.com/adafruit/Adafruit_MPU6050
Library 3; i2cdevlib/ElectronicCats' mpu6050 - https://github.com/ElectronicCats/mpu6050
Library 1;
// in .ino setup()
mpu.begin(MPU6050_SCALE_2000DPS, MPU6050_RANGE_2G)
// in MPU6050.cpp
// in begin()
setRange(range);
// in setRange()
case MPU6050_RANGE_2G:
rangePerDigit = .000061f; // same as 1.0/16384
// in .ino loop()
// Read raw values
Vector rawAccel = mpu.readRawAccel();
// Read normalized values, in m/s^2
Vector normAccel = mpu.readNormalizeAccel();
// in MPU6050.cpp
// in readNormalizedAccel()
na.YAxis = ra.YAxis * rangePerDigit * 9.80665f;
Formula for normalized acceleration value at MPU6050_RANGE_2G;
raw * rangePerDigit * gravityConst
(raw * (1.0/16384)) * gravityConst
== (raw / 16384) * gravityConst
(-13248.00 * .000061) * 9.80665 = -7.92502845
== (-13248.00 / 16384) * 9.80665 = -7.92959589
Library 2;
// Adafruit_Sensor.h
#define SENSORS_GRAVITY_EARTH (9.80665F) /**< Earth's gravity in m/s^2 */
#define SENSORS_GRAVITY_STANDARD (SENSORS_GRAVITY_EARTH)
// in .ino setup()
mpu.begin(); // calls _init(), setAccelerometerRange(MPU6050_RANGE_2_G); // already the default
mpu.setAccelerometerRange(MPU6050_RANGE_2_G);
// in Adafruit_MPU6050.cpp
// in _read()
if (accel_range == MPU6050_RANGE_2_G)
accel_scale = 16384; // same as 16384/1.0
// setup range dependant scaling
accY = ((float)rawAccY) / accel_scale;
// in fillAccelEvent()
accel->acceleration.y = accY * SENSORS_GRAVITY_STANDARD;
// in .ino loop()
mpu_accel = mpu.getAccelerometerSensor();
/* Get a new normalized sensor event */
sensors_event_t accel;
mpu_accel->getEvent(&accel);
/* Display the results (acceleration is measured in m/s^2) */
Serial.print(accel.acceleration.y);
Formula for normalized acceleration value at MPU6050_RANGE_2_G;
(raw / accel_scale) * gravityConst
(-13248.00 / 16384) * 9.80665 = -7.92959589
Library 3;
// in .ino setup()
mpu.initialize();
// in MPU6050.cpp
// in initialize()
setFullScaleAccelRange(MPU6050_ACCEL_FS_2);
// in setFullScaleAccelRange()
case MPU6050_ACCEL_FS_2:
accelerationResolution = 2.0 / 16384.0; // == 0.000122f
float MPU6050_Base::get_acce_resolution() {
return accelerationResolution;
}
// in .ino loop()
/* Read raw accell/gyro data from the module */
mpu.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);
mpu.getAcceleration(&ax, &ay, &az);
Serial.print(ay); Serial.print("\t");
No normalized functions in MPU6050.cpp. Can use MotionApps files, but they go through Quaternions.
// in .ino
#include "MPU6050_6Axis_MotionApps20.h"
// in .ino loop()
mpu.dmpGetCurrentFIFOPacket(FIFOBuffer);
mpu.dmpGetQuaternion(&q, FIFOBuffer);
mpu.dmpGetGravity(&gravity, &q);
// gravity is used in the same way as normalizedAccel values
// by jarzebski in pitch&roll calculations.
Formula for normalized acceleration value at MPU6050_ACCEL_FS_2;
// jarzebski way;
raw * accelerationResolution * gravityConst
-13248.00 * 0.000122 * 9.80665 = -15.850057
// adafruit way;
// (raw * (1.0/16384)) * gravityConst
// (raw * (2.0/16384)) * gravityConst
(-13248.00 / (2.0*16384)) * 9.80665 = -15.85919
((-13248.00*2.0) / 16384) * 9.80665 = -15.85919
Result is twice that of the others.
accelerationResolution
itself seems to be twice the others, so half it? Not sure if this is a mistake, or I'm missing something about MPU6050_ACCEL_FS_2 vs MPU6050_RANGE_2_G.raw * (accelerationResolution/2) * gravityConst
-13248.00 * (accelerationResolution/2) * 9.80665 = -7.9250
accelerationResolution
and get_acce_resolution()
only exist in the ElectronicCats version, they're not accessible in the i2cdevlibs version. That version seems to really want you to use the Quaternion path. But you can always use the range values from the other versions yourself on the raw values.