cancel
Showing results for 
Search instead for 
Did you mean: 

Inertial Sensor - How to correctly use Motion librarys

Jonattan Carvalho
Associate
Posted on February 23, 2018 at 15:43

Hello.

I am trying to build a full motion sensor software. I am using the NUCLEO-F411RE with STM32F411RE,

SW4STM IDE,

LSM9DS1 sensor with gyroscope, accelerometer and magnetometer. For this, I implemented the X-CUBE-MEMS1 library with MotionAC, MotionGC and MotionMC for sensor calibration.

I performed the gyroscope calibration successfully, but I could not calibrate the

accelerometer and magnetometer. The MotionMC library never gives me results. The MotionAC gives me results sometimes, but only in 'Dynamic Calibration' mode and they are not very accurate. I am doing circular motions trying to cover to the maximum all the points with all the axes.

Defines:

#define ADJUST_ACC_MG 0.061f //2range:0.061mg/LSB //VALUES FROM DATASHEET

#define ADJUST_ACC_G 0.000061f //2range:0.000061g/LSB #define ADJUST_GYR_MDPS 8.75f //245range:8.75mdps/LSB #define ADJUST_GYR_DPS 0.00875f //245range:0.00875dps/LSB #define ADJUST_MAG_MGAUSS 0.14f //4range:0.14mgauss/LSB #define ADJUST_MAG_UT 0.014f //4range:0.014uT/LSB

#define REPORT_INTERVAL 10

#define SAMPLE_FREQUENCY_F 0f

Variables:

SensorAxes_t ACC_Brute; // Data from sensor

SensorAxes_t GYR_Brute;

// Data from sensor

SensorAxes_t MAG_Brute;

// Data from sensor

SensorAxesFloat_t ACC_Cal; // Calibrated data SensorAxesFloat_t GYR_Cal;

// Calibrated data

SensorAxesFloat_t MAG_Cal;

// Calibrated data

uint32_t CounterStamp;

//MotionAC

MAC_input_t MAC_Input_Brute; MAC_output_t MAC_Params;

//MotionMC

MMC_Input_t MMC_Input_Brute; MMC_Output_t MMC_Params;

Initialization:

void Motion_Lib_Init()
{
//MotionAC
#define MOVE_THR_G 0.3f // Recommended between 0.15 - 0.30 g, higher value will relax condition but reduce the accuracy (moveThresh_g / 10)
MAC_calibration_mode_t CalibrationMode = DYNAMIC_CALIBRATION; // DYNAMIC_CALIBRATION or SIX_POINT_CALIBRATION
MAC_knobs_t KnobsAC;
MotionAC_Initialize(MAC_ENABLE_LIB);
MotionAC_GetKnobs(&KnobsAC);
KnobsAC.MoveThresh_g = MOVE_THR_G;
KnobsAC.Run6PointCal = (uint8_t) CalibrationMode;
KnobsAC.Sample_ms = REPORT_INTERVAL;
MotionAC_SetKnobs(&KnobsAC);

//MotionMC

MotionMC_Initialize(REPORT_INTERVAL, 1); }

Called by timer every 10ms:

CounterStamp++;

//MotionAC

uint8_t is_calibrated = 0;

MAC_Input_Brute.TimeStamp = CounterStamp * REPORT_INTERVAL; MAC_Input_Brute.Acc[0] = ACC_Brute.AXIS_X * ADJUST_ACC_G; MAC_Input_Brute.Acc[1] = ACC_Brute.AXIS_Y * ADJUST_ACC_G; MAC_Input_Brute.Acc[2] = ACC_Brute.AXIS_Z * ADJUST_ACC_G; MotionAC_Update(&MAC_Input_Brute, &is_calibrated); MotionAC_GetCalParams(&MAC_Params); ACC_Cal.X = (MAC_Input_Brute.Acc[0] - MAC_Params.AccBias[0]) * MAC_Params.SF_Matrix[0][0]; ACC_Cal.Y = (MAC_Input_Brute.Acc[1] - MAC_Params.AccBias[1]) * MAC_Params.SF_Matrix[1][1]; ACC_Cal.Z = (MAC_Input_Brute.Acc[2] - MAC_Params.AccBias[2]) * MAC_Params.SF_Matrix[2][2];

//MotionMC

MMC_Input_Brute.TimeStamp = CounterStamp * REPORT_INTERVAL;

MMC_Input_Brute.Mag[0] = (float)MAG_Brute.AXIS_X * ADJUST_MAG_UT; MMC_Input_Brute.Mag[1] = (float)MAG_Brute.AXIS_Y * ADJUST_MAG_UT; MMC_Input_Brute.Mag[2] = (float)MAG_Brute.AXIS_Z * ADJUST_MAG_UT; MotionMC_Update(&MMC_Input_Brute); MotionMC_GetCalParams(&MMC_Params);

MAG_Cal.X = ((MMC_Input_Brute.Mag[0] - MMC_Params.HI_Bias[0]) * MMC_Params.SF_Matrix[0][0])

+ ((MMC_Input_Brute.Mag[1] - MMC_Params.HI_Bias[1]) * MMC_Params.SF_Matrix[0][1]) + ((MMC_Input_Brute.Mag[2] - MMC_Params.HI_Bias[2]) * MMC_Params.SF_Matrix[0][2]); MAG_Cal.Y = ((MMC_Input_Brute.Mag[0] - MMC_Params.HI_Bias[0]) * MMC_Params.SF_Matrix[1][0]) + ((MMC_Input_Brute.Mag[1] - MMC_Params.HI_Bias[1]) * MMC_Params.SF_Matrix[1][1]) + ((MMC_Input_Brute.Mag[2] - MMC_Params.HI_Bias[2]) * MMC_Params.SF_Matrix[1][2]); MAG_Cal.Z = ((MMC_Input_Brute.Mag[0] - MMC_Params.HI_Bias[0]) * MMC_Params.SF_Matrix[2][0]) + ((MMC_Input_Brute.Mag[1] - MMC_Params.HI_Bias[1]) * MMC_Params.SF_Matrix[2][1]) + ((MMC_Input_Brute.Mag[2] - MMC_Params.HI_Bias[2]) * MMC_Params.SF_Matrix[2][2]);

}

What is necessary to perform this calibration? I plan to implement MotionTL, MotionEC and MotionFX too.

Kind regards,

Jonattan

#motionac #motionmc #magnetometer #accelerometer #calibration #mems
6 REPLIES 6
Miroslav BATEK
ST Employee
Posted on February 24, 2018 at 12:03

Concerning the MotionMC library, I don't see the library initialization and enabling: MotionMC_Initialize(SAMPLE_TIME, 1);

What do you mean by

MotionAC is not very accurate? As the MotionAC is real-time library and is able to calibrate the sensor on the fly the results are not perfect. I would say for modern sensors it is not needed.

If you want to create inclinometer with high accuracy, I would recomend you to use 6-point calibration in MotionTL library.

Jonattan Carvalho
Associate
Posted on February 26, 2018 at 13:54

Thanks for the answer.

About MotionMC initialization, I edited the post, I had copied and pasted another piece of code.

MotionAC does not seem accurate because I can not get updated results in real time. I need approximately 1000 iterations to get the first parameter result, and these parameters do not change again without software reset. The 'MAC_cal_quality_t' parameter starts at 'MAC_CALQSTATUSOK' and changes to 'MAC_CALQSTATUSGOOD' at the first result. Am I doing the wrong calibration movement? Is there a software error?

I'm working on MotionTL right now, if I have any convenient results I'll post here.

Posted on February 27, 2018 at 16:50

If the accelerometer calibration library returns MAC_CALQSTATUSGOOD than the calibration is working well.

The target of the library is difference from 1g gravity vector +/- 40mg if your sensor is in this range, the calibration parameters will remain 0 (offset) and 1 (scale factor).

kkia
Associate II

Hi, I am also using the MotionMC library and I always get MMC_CALQSTATUSUNKNOWN as the calibration quality. moreover, when I move my compass in a 3D 8 shape pattern, the code just hangs and I have to reset my chip.

Is there any specific configuration that should be done in using this library?

my sample rate is 50Hz and my data range and sample time is OK.

Thank you all in advance.

kkia
Associate II

Ow I just go the answer!

make sure of three notes:

1- calibration must be run for at least 5 seconds. before this time you always get the default values.

2- you should duplicate the heap and stack size in the assembly file, for the library probably uses dynamic memory.

3- you can use HAL_GetTick as the timestamp.

also take a look at this topic:

https://community.st.com/s/question/0D50X00009XkWyASAV/motionmc-calibration-fails-all-params-have-default-value

If the code stuck, I think your heap and stack is not big enough, the library uses dynamic memory allocation.

Next time don't post the same question in the different topics!