Closed Ananfruit closed 3 years ago
You have to call calibrateAccel()
in a loop and move the hardware physically before each call.
Think of the hardware as a plain cube with 6 faces, each position would be one face to the touching the ground / table.
Here is an example:
#include <Arduino.h>
#include <Wire.h>
#include <MPU9250.h>
MPU9250 mpu(Wire, 0x68);
void setup()
{
Serial.begin(115200);
Serial.println("Doing calibration");
mpu.begin();
for(int n = 0; n < 6; n++)
{
Serial.print("Move the car into position ");
Serial.print(n);
Serial.println();
delay(7000);
mpu.calibrateAccel();
}
Serial.println("Calibration done");
Serial.print("bias x = ");
Serial.print(mpu.getAccelBiasX_mss(), 5);
Serial.println();
Serial.print("bias y = ");
Serial.print(mpu.getAccelBiasY_mss(), 5);
Serial.println();
Serial.print("bias z = ");
Serial.print(mpu.getAccelBiasZ_mss(), 5);
Serial.println();
Serial.print("factor x = ");
Serial.print(mpu.getAccelScaleFactorX(), 5);
Serial.println();
Serial.print("factor y = ");
Serial.print(mpu.getAccelScaleFactorY(), 5);
Serial.println();
Serial.print("factor z = ");
Serial.print(mpu.getAccelScaleFactorZ(), 5);
Serial.println();
}
void loop()
{
}
Then you use those numbers in the real code:
#include <Arduino.h>
#include <Wire.h>
#include <MPU9250.h>
MPU9250 mpu(Wire, 0x68);
const float accelBias[3] = { 0.11111, 0.22222, 0.33333 }; // Obtained through calibration scketch
const float accelFactor[3] = { 0.11111, 0.22222, 0.33333 }; // Obtained through calibration scketch
void setup()
{
Serial.begin(115200);
Serial.println("Doing calibrated reading");
mpu.begin();
mpu.setAccelCalX(accelBias[0], accelFactor[0]);
mpu.setAccelCalY(accelBias[1], accelFactor[1]);
mpu.setAccelCalZ(accelBias[2], accelFactor[2]);
}
void loop()
{
mpu.readSensor();
Serial.print("accel x = ");
Serial.print(mpu.getAccelX_mss(), 5);
Serial.println();
Serial.print("accel y = ");
Serial.print(mpu.getAccelY_mss(), 5);
Serial.println();
Serial.print("accel z = ");
Serial.print(mpu.getAccelZ_mss(), 5);
Serial.println();
Serial.println();
delay(100);
}
Hey Ananfruit,
I do have a similar issue. I have no issues running the gyro/mag calibration. The accelerometer however will not calibrate correctly.
#include "MPU9250.h"
MPU9250 IMU(Wire, 0x68);
void setup() {
// serial to display data
Serial.begin(115200);
while (!Serial) {}
// start communication with IMU
IMU.begin();
if (IMU.begin() < 0) {
Serial.println("IMU initialization unsuccessful");
Serial.println("Check IMU wiring or try cycling power");
Serial.print("Status: ");
Serial.println(IMU.begin());
while (1) {}
}
Serial.println("Calibrating Gyro... Please hold still");
IMU.calibrateGyro();
Serial.println("Gyro Calibration Complete!");
Serial.print("Gyro Bias X (rad/s): \t"); Serial.println(IMU.getGyroBiasX_rads());
Serial.print("Gyro Bias Y (rad/s): \t"); Serial.println(IMU.getGyroBiasY_rads());
Serial.print("Gyro Bias Z (rad/s): \t"); Serial.println(IMU.getGyroBiasZ_rads());
Serial.println("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%");
delay(4000);
Serial.println("Calibrating Accelerometer... Please rotate slowly");
for (int n = 0; n < 6; n++)
{
Serial.print("Move the IMU into position ");
Serial.print(n);
Serial.println();
delay(5000);
IMU.calibrateAccel();
}
Serial.println("Accelerometer Calibration Complete!");
Serial.print("Accelerometer Bias X (m*s^(-2)): \t"); Serial.println(IMU.getAccelBiasX_mss());
Serial.print("Accelerometer Bias Y (m*s^(-2)): \t"); Serial.println(IMU.getAccelBiasY_mss());
Serial.print("Accelerometer Bias Z (m*s^(-2)): \t"); Serial.println(IMU.getAccelBiasZ_mss());
Serial.print("Accelerometer Scale X : \t"); Serial.println(IMU.getAccelScaleFactorX());
Serial.print("Accelerometer Scale Y : \t"); Serial.println(IMU.getAccelScaleFactorY());
Serial.print("Accelerometer Scale Z : \t"); Serial.println(IMU.getAccelScaleFactorZ());
Serial.println("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%");
delay(4000);
Serial.println("Calibrating Magnetometer... Please move in 8-Shape slowly");
IMU.calibrateMag();
Serial.println("Magnetometer Calibration Complete!");
Serial.print("Magnetometer Bias X (uT): \t"); Serial.println(IMU.getMagBiasX_uT());
Serial.print("Magnetometer Bias Y (uT): \t"); Serial.println(IMU.getMagBiasY_uT());
Serial.print("Magnetometer Bias Z (uT): \t"); Serial.println(IMU.getMagBiasZ_uT());
Serial.print("Magnetometer Scale X : \t"); Serial.println(IMU.getMagScaleFactorX());
Serial.print("Magnetometer Scale Y : \t"); Serial.println(IMU.getMagScaleFactorY());
Serial.print("Magnetometer Scale Z : \t"); Serial.println(IMU.getMagScaleFactorZ());
Serial.println("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%");
while (true);
}
void loop() {
// put your main code here, to run repeatedly:
}
Now I will get the following output for the acceleromter:
Calibrating Accelerometer... Please rotate slowly
Move the IMU into position 0
Move the IMU into position 1
Move the IMU into position 2
Move the IMU into position 3
Move the IMU into position 4
Move the IMU into position 5
Accelerometer Calibration Complete!
Accelerometer Bias X (m*s^(-2)): 0.00
Accelerometer Bias Y (m*s^(-2)): 0.00
Accelerometer Bias Z (m*s^(-2)): 0.00
Accelerometer Scale X : 1.00
Accelerometer Scale Y : 1.00
Accelerometer Scale Z : 1.00
I do not believe the accelerometer is calibrated perfectly. 😄 Futhermore, when reading the accelerometer ( in m*s^-2), I get the followingm which obiously shows the calibration did not work at all.
X Y Z
11:34:01.459 -> -1.087023 -23.866619 9.783207
11:34:01.505 -> -1.019982 -23.971970 9.768841
11:34:01.599 -> -1.005616 -23.876196 9.893346
11:34:01.647 -> -1.019982 -23.952814 9.730532
11:34:01.695 -> -0.967307 -23.914505 9.783207
11:34:01.741 -> -1.029559 -23.904928 9.711377
11:34:01.789 -> -1.029559 -23.876196 9.706589
11:34:01.837 -> -0.972095 -23.871407 9.778418
11:34:01.884 -> -1.072657 -23.885773 9.792784
11:34:01.932 -> -1.087023 -23.847464 9.821516
Am I using the calibrateAccel()
function incorrectly? If so, could you please point me towards the right direction?
Thanks guys! 🥂
Calibration functions are no longer included as part of this library.
Hey! I am experiencing difficulty calibrating my sensor. The accelerometer values are biased and gyroscope readings are too low. I have attached a part of my code below. Please reply with an example sketch on how to calibrate the sensor. I'd be really grateful for your help. Thanks in advance
include "MPU9250.h"
// an MPU9250 object with the MPU-9250 sensor on I2C bus 0 with address 0x68 MPU9250 IMU(Wire,0x68); int status; int statusAcc; int statusGyr; int statusMag;
void setup() { // serial to display data Serial.begin(115200); while(!Serial) {}
// start communication with IMU status = IMU.begin(); //calibrating IMU statusAcc= IMU.calibrateAccel(); statusGyr= IMU.calibrateGyro(); statusMag= IMU.calibrateMag();
if (status < 0) { Serial.println("IMU initialization unsuccessful"); Serial.println("Check IMU wiring or try cycling power"); Serial.print("Status: "); Serial.println(status); while(1) {} } // setting the accelerometer full scale range to +/-8G IMU.setAccelRange(MPU9250::ACCEL_RANGE_8G); // setting the gyroscope full scale range to +/-500 deg/s IMU.setGyroRange(MPU9250::GYRO_RANGE_500DPS); // setting DLPF bandwidth to 20 Hz IMU.setDlpfBandwidth(MPU9250::DLPF_BANDWIDTH_20HZ); // setting SRD to 19 for a 50 Hz update rate IMU.setSrd(19); . . . .