Hi Everyone,
I am struggling to build a simple compass using the onboard LSMDS1 on board my nano BLE sense
here is my code, when i compile this i am getting value that compared to my phone compass just don't make sense, anything i am missing out ?
Thanks in advance for any input.
#include <NXPMotionSense.h> // For AHRS usage
#include <Wire.h>
#include <math.h>
// Sensor data variables
float xM, yM, zM, xA, yA, zA, xG, yG, zG;
// Calibrated magnetic field variables
float mx_calibrated, my_calibrated, mz_calibrated;
// Calibration parameters
const float hard_iron[3] = {6.43, 42.76, 10.51};
const float soft_iron[3][3] = {
{0.978, 0.018, 0.014},
{0.018, 0.987, -0.003},
{0.014, -0.003, 1.042}
};
void setup() {
Serial.begin(115200);
if (!IMU.begin()) {
Serial.println("Failed to initialize the IMU");
}
}
void loop() {
// Read sensor data
IMU.readMagneticField(xM, yM, zM);
IMU.readGyroscope(xG, yG, zG);
IMU.readAcceleration(xA, yA, zA);
// Apply calibration and get orientation
applyCalibrationMag();
}
void applyCalibrationMag() {
float mag_raw[3] = {xM, yM, zM};
float _calibrated[3];
// Remove hard iron bias
for (int i = 0; i < 3; i++) {
_calibrated[i] = mag_raw[i] - hard_iron[i];
}
// Apply soft iron correction
for (int j = 0; j < 3; j++) {
_calibrated[j] = (soft_iron[j][0] * _calibrated[0]) + (soft_iron[j][1] * _calibrated[1]) + (soft_iron[j][2] * _calibrated[2]);
}
// Update calibrated values
mx_calibrated = _calibrated[0];
my_calibrated = _calibrated[1];
mz_calibrated = _calibrated[2];
// Calculate heading
float heading = (atan2(my_calibrated, mx_calibrated) * 180) / PI;
// Ensure heading is within [0, 360) degrees
if (heading < 0) {
heading += 360;
}
//TODO : Add declinaison compensation
Serial.println("Calibrated Heading: " + String(heading));
}