MotionFX Azimuth Detection Issues with ISM330DHCX - Seeking Configuration Guidance
Problem Summary
I'm experiencing challenges with MotionFX library for azimuth rotation detection using the ISM330DHCX sensor. While MotionDI works well for altitude detection, MotionFX shows inconsistent behavior for azimuth (rotational) measurements.
I have done a test where I have collected samples over the entire weekend (about 65 hours). I am aware of the difficulties in detecting rotational movement using only accelerometer and gyroscope, however, the issues below do not seem to stem from this, but rather with issues in the MotionFX library or parameters.
Hardware Setup
- Sensor: ISM330DHCX (accelerometer + gyroscope)
- Orientation: WDS mounting (X-West, Y-Down, Z-South)
- Sample Rate: 104Hz
- Application: Rotational motion detection system that detects motion over longer periods in time. (No real time updates needed)
Current Configuration
MotionDI Parameters (working well for altitude):
mdi.move_thresh_g = 0.25f; mdi.cal_type = 1; mdi.acc_thr_g = 0.01f; mdi.gyro_thr_dps = 0.01f; mdi.max_gyro_dps = 15.0f; mdi.gyro_cal_type = 2; mdi.sf_atime = 2.0f; mdi.sf_frtime = 2.0f; mdi.modx = 1; mdi.output_type = 1;
MotionFX Parameters (issues with azimuth):
mfx.atime = 2.0f; mfx.mtime = 0.01f; // not used in 6X mode mfx.frtime = 2.0f; mfx.lmode = 1; // static learning - if we put this to 2, I see immediate drift/changes mfx.gbias_acc_th_sc = 0.00153f; // from library mfx.gbias_gyro_th_sc = 0.1f; // library had 0.004f mfx.modx = 1; // AN suggests setting it to 2, but this is causing issues as well (does this change the refresh rate?) mfx.output_type = 1;
Observed Issues
1. Gyroscope Bias Drift
- MotionDI: Shows significant X-axis bias drift (0-60+ dps over time)
- MotionFX: Maintains stable bias (~-0.42 dps constant)
- Question: Is this normal behavior, or should I adjust calibration parameters?


2. Angle Calculation Method
Currently extracting angles from quaternion differences:
Quaternion relative = QuaternionMath::relativeRotation(current, reference); float roll, pitch, yaw; QuaternionMath::toEulerAngles(relative, roll, pitch, yaw); // Using pitch for altitude (MotionDI) altitude_angle = fabsf(pitch); // Using roll for azimuth (MotionFX) azimuth_angle = fabsf(roll); // This is the correct axis for what we are trying to detect.
3. Temperature Influence
- Temperature varies 33-35°C during operation
- Correlation with bias drift observed (very minimal changes, but changes still)
- Question: Should I implement temperature compensation? (Even though the ism has built-in compensation)

Analysis Results
From my data analysis:
- Accelerometer magnitude stable around 1000mg (1g)
- Gyroscope magnitude around 1.0-1.2 dps
- MotionFX quaternion trajectory shows more circular pattern
- MotionDI quaternion trajectory shows more linear segment\


Specific Questions
Bias Calibration: Why does MotionDI show significant X-axis bias drift while MotionFX remains stable? Should I adjust gbias_gyro_th_sc parameter?
Azimuth vs Altitude: Is my approach of using MotionFX for azimuth and MotionDI for altitude detection appropriate, or should I use a single library? The reason I am using both libraries is because during initial testing, I found MotionDI to be way more reliable in altitude angle tracking than MotionFX, but MotionFX showed good results for altitude.
WDS Orientation: Are there specific considerations for WDS mounting that affect MotionFX performance?
Library Parameters: Given my 104Hz sample rate and WDS orientation, are my current parameters optimal?
Temperature Compensation: Should I implement additional temperature-based bias correction?
Expected Behavior
I need to detect:
- Altitude changes: ±5° threshold (working with MotionDI)
- Azimuth changes: ±10° threshold (struggling with MotionFX)
Code Initialization
// MotionFX initialization MotionFX_initialize(static_cast<MFXState_t>(_mfx_state_buffer)); MotionFX_getKnobs(static_cast<MFXState_t>(_mfx_state_buffer), &_mfx_knobs); // Set knobs... MotionFX_setKnobs(static_cast<MFXState_t>(_mfx_state_buffer), &_mfx_knobs); MotionFX_enable_6X(static_cast<MFXState_t>(_mfx_state_buffer), MFX_ENGINE_ENABLE);
[EDIT]: I have now also done some extra testing. I found the following "noise floor" for my sensor:
accel_x_mg - Mean: -62.39, Std Dev: 0.61, Median: -62.00, Min: -68.00, Max: -57.00
3 Noise Floor accel_x_mg: 0.00182749 mg
accel_y_mg - Mean: -1010.81, Std Dev: 0.54, Median: -1011.00, Min: -1015.00, Max: -1005.00
3 Noise Floor accel_y_mg: 0.00161997 mg
accel_z_mg - Mean: -16.90, Std Dev: 1.12, Median: -17.00, Min: -30.00, Max: -12.00
3 Noise Floor accel_z_mg: 0.00335705 mg
gyro_x_dps - Mean: 0.38, Std Dev: 0.04, Median: 0.42, Min: 0.14, Max: 0.70
3 Noise Floor gyro_x_dps: 0.00227631 mg
gyro_y_dps - Mean: -0.78, Std Dev: 0.04, Median: -0.77, Min: -1.05, Max: -0.49
3 Noise Floor gyro_y_dps: 0.00209153 mg
gyro_z_dps - Mean: -0.60, Std Dev: 0.04, Median: -0.63, Min: -0.91, Max: -0.35
3 Noise Floor gyro_z_dps: 0.00204885 mg
Magnitude of Acceleration: 1012.88 mg
Magnitude of Gyroscope: 1.06 dpsAnd have used these settings in the parameters for MotionFX, however, I still see a steady drift overnight (21 degrees of change in 16 hours)



If anyone would want to check out the full code, I can definitely share some snippets later on.
Any insights on proper MotionFX configuration for azimuth detection in this setup would be greatly appreciated!
ST Library Versions: Using latest MotionDI and MotionFX libraries from X-CUBE-MEMS1 package.
