Nano BLE 33 Sense lsm9ds1 sensor fusion

Hi, could anyone help me with getting reasonably accurate fused orientation data from the 9DoF LSM9DS1 on the Arduino Nano BLE 33 sense chip?

I would have thought that this is a common requirement of this sensor, but most instructions and library examples I’ve found only cover extracting the raw data, or else use very rough and drifty approximations for true orientation. Ideally I’d like to be within a degree or 2 on all 3 axes, and stable at rest.

Here is the code I’ve tried using the Madgwick filter (which I understand very little about.) Perhaps unsurprisingly my output numbers bear no resemblance to what they should. I’m not even sure the units I’m using are correct, or how I would find that out. Can anyone tell me how to fix this, or point me to a working equivalent for this sensor?

Huge thanks for any help.

#include <Arduino_LSM9DS1.h>
#include "Streaming.h" 		// needed for the Serial output
#include "SensorFusion.h"
SF fusion;

float g_x, g_y, g_z, a_x, a_y, a_z, m_x, m_y, m_z;
float pitch, roll, yaw;
float deltat;

void setup() {
  // serial to display data
  while (!Serial) {}

  // start communication with IMU
    while (!Serial);

  if (!IMU.begin()) {
    Serial.println("Failed to initialize IMU!");
    while (1);

void loop() {

    IMU.readAcceleration(a_x, a_y, a_z);    
    IMU.readGyroscope(g_x, g_y, g_z);
    IMU.readMagneticField(m_x, m_y, m_z);

    g_x = g_x * DEG_TO_RAD;
    g_y = g_y * DEG_TO_RAD;
    g_z = g_z * DEG_TO_RAD;
  deltat = fusion.deltatUpdate();
  //fusion.MahonyUpdate(g_x, g_y, g_z, a_x, a_y, a_z, m_x, m_y, m_z, deltat);  //mahony is suggested if there isn't the mag
  fusion.MadgwickUpdate(g_x, g_y, g_z, a_x, a_y, a_z, m_x, m_y, m_z, deltat);  //else use the magwick

  roll = fusion.getRoll();
  pitch = fusion.getPitch();
  yaw = fusion.getYaw();



Unless the magnetometer and gyro are calibrated, the fusion filter output data will be meaningless. The most comprehensive overview on magnetometer calibration can be found here. Calibration must be performed "in place", that is, where the sensor will be used.

Where did you download "SensorFusion.h"? Is it properly configured for the Nano BLE 33 Sense and the peculiar axial definitions in LSM9DS1? If not, the fusion filter output data will be meaningless.

Mahony sensor fusion and calibration code for the LSM9DS1 sensor can be found here, but it has not been tested with the Nano BLE 33 Sense.


I have seen things about calibration, but I’m not clear where I would plug the calibration offsets into my code. I’m also conscious that my final project will move around probably several km, so I don’t know if there is a way I can regularly update the calibration as the code runs?

I think I just got the library through the Arduino ide library manager. I’m not particularly attached to it but it was the only one of several I looked at that would let me plug my raw data in.

I will have a look at the one you linked. Thank you.

so I don't know if there is a way I can regularly update the calibration as the code runs?

No, there is not (except for the gyro).

But the magnetometer data are mostly confused by the immediate environment (nearby iron containing objects, motors, current carrying wires) and so, for example, calibration after mounting the sensor in a robot can be done once.

A problem with the LSM9DS1 is that the accelerometer and gyro axes do not form a right handed coordinate system, which is expected by all sensor fusion code. That has to be corrected for the sensor to be useful.

Hi, could you explain what you mean by that? And how should we go about solving this?

If by "that" you refer to the LSM9DS1 acc/gyro axial coordinate system problem, simply swap or reflect axes to make a right handed system. The code is posted here.

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.