Hello every one.
I am using the Arduino Due, with I2C connect to the 9 DOF IMU (Adafruit LSM6DS3TRC + LIS3MDL).
I am also using the AdaFruit library for the sensor.
The problem is I do not want to use the MotionCal software to calibrate the Magnetometer.
I found some code on GitHub, where the the Mag is calibrated by moving the sensor in a figure 8 pattern
void magcalMPU9250(float * dest1, float * dest2)
{
uint16_t ii = 0, sample_count = 0;
int32_t mag_bias[3] = {0, 0, 0}, mag_scale[3] = {0, 0, 0};
int16_t mag_max[3] = {-32767, -32767, -32767}, mag_min[3] = {32767, 32767, 32767}, mag_temp[3] = {0, 0, 0};
Serial.println("Mag Calibration: Wave device in a figure eight until done!");
delay(4000);
// shoot for ~fifteen seconds of mag data
if(MPU9250Mmode == 0x02) sample_count = 128; // at 8 Hz ODR, new mag data is available every 125 ms
if(MPU9250Mmode == 0x06) sample_count = 1500; // at 100 Hz ODR, new mag data is available every 10 ms
for(ii = 0; ii < sample_count; ii++) {
MPU9250readMagData(mag_temp); // Read the mag data
for (int jj = 0; jj < 3; jj++) {
if(mag_temp[jj] > mag_max[jj]) mag_max[jj] = mag_temp[jj];
if(mag_temp[jj] < mag_min[jj]) mag_min[jj] = mag_temp[jj];
}
if(MPU9250Mmode == 0x02) delay(135); // at 8 Hz ODR, new mag data is available every 125 ms
if(MPU9250Mmode == 0x06) delay(12); // at 100 Hz ODR, new mag data is available every 10 ms
}
// Get hard iron correction
mag_bias[0] = (mag_max[0] + mag_min[0])/2; // get average x mag bias in counts
mag_bias[1] = (mag_max[1] + mag_min[1])/2; // get average y mag bias in counts
mag_bias[2] = (mag_max[2] + mag_min[2])/2; // get average z mag bias in counts
dest1[0] = (float) mag_bias[0]*MPU9250mRes*MPU9250magCalibration[0]; // save mag biases in G for main program
dest1[1] = (float) mag_bias[1]*MPU9250mRes*MPU9250magCalibration[1];
dest1[2] = (float) mag_bias[2]*MPU9250mRes*MPU9250magCalibration[2];
// Get soft iron correction estimate
mag_scale[0] = (mag_max[0] - mag_min[0])/2; // get average x axis max chord length in counts
mag_scale[1] = (mag_max[1] - mag_min[1])/2; // get average y axis max chord length in counts
mag_scale[2] = (mag_max[2] - mag_min[2])/2; // get average z axis max chord length in counts
float avg_rad = mag_scale[0] + mag_scale[1] + mag_scale[2];
avg_rad /= 3.0;
dest2[0] = avg_rad/((float)mag_scale[0]);
dest2[1] = avg_rad/((float)mag_scale[1]);
dest2[2] = avg_rad/((float)mag_scale[2]);
Serial.println("Mag Calibration done!");
}
I then adapted the code to the following function
bool CalibrateMag(void)
{
int16_t mag_max[3] = {-32767, -32767, -32767}, mag_min[3] = {32767, 32767, 32767}, mag_temp[3] = {0, 0, 0};
float Average_Rad = 0;
uint16_t InnerLoop = 0, Sample_Count = 128, OutterLoop = 0;
int32_t MBias[3] = { 0, 0, 0 };
int32_t Mag_Scale[3] = {0, 0, 0};
for(OutterLoop = 0; OutterLoop < Sample_Count; OutterLoop++)
{
sensors_event_t Magnets;
MagnetoMeter2->getEvent(&Magnets);
SerialUSB.println(" ");
SerialUSB.print("Magnets X = ");SerialUSB.print(Magnets.magnetic.x, 4); SerialUSB.print(" ");
SerialUSB.print("Magnets Y = ");SerialUSB.print(Magnets.magnetic.y, 4); SerialUSB.print(" ");
SerialUSB.print("Magnets Z = ");SerialUSB.print(Magnets.magnetic.z, 4); SerialUSB.print(" ");
SerialUSB.println(" ");
mag_temp[0] = (int16_t) Magnets.magnetic.x;
mag_temp[1] = (int16_t) Magnets.magnetic.y;
mag_temp[2] = (int16_t) Magnets.magnetic.z;
for(InnerLoop = 0; InnerLoop < 3; InnerLoop++)
{
if(mag_temp[InnerLoop] > mag_max[InnerLoop]) mag_max[InnerLoop] = mag_temp[InnerLoop];
if(mag_temp[InnerLoop] < mag_min[InnerLoop]) mag_min[InnerLoop] = mag_temp[InnerLoop];
}
digitalWrite(RedLED, HIGH);
delay(162);
digitalWrite(RedLED, LOW);
delay(162);
}
//Calculate - Hard iron correction
MBias[0] = ((mag_max[0] + mag_min[0])/2);
MBias[1] = ((mag_max[1] + mag_min[1])/2);
MBias[2] = ((mag_max[2] + mag_min[2])/2);
MyMag_HardIron[0] = (float) (MBias[0]) * Mag_sensitivity;
MyMag_HardIron[1] = (float) (MBias[1]) * Mag_sensitivity;
MyMag_HardIron[2] = (float) (MBias[2]) * Mag_sensitivity;
Mag_Scale[0] = ((mag_max[0] - mag_min[0])/2);
Mag_Scale[1] = ((mag_max[1] - mag_min[1])/2);
Mag_Scale[2] = ((mag_max[2] - mag_min[2])/2);
Average_Rad = (Mag_Scale[0]+ Mag_Scale[1] + Mag_Scale[2]);
Average_Rad /= 3.0;
MyMag_SoftIron[0] = (Average_Rad / (float)Mag_Scale[0]);
MyMag_SoftIron[1] = (Average_Rad / (float)Mag_Scale[1]);
MyMag_SoftIron[2] = (Average_Rad / (float)Mag_Scale[2]);
}
The problem is the values of Magnets.magnetic.x, Magnets.magnetic.y and Magnets.magnetic.z do not change they stay the same. Even with a magnet moved close to the Magnetometer the values do not change
I am also not sure what the value of Mag_sensitivity should be#define Mag_sensitivity 1.499389499
in the Github code that how its defined, for the MPU9250. Does the value stay the same for the ST accelerometers.
I will appreciate any help!!!