2018-02-23 06:43 AM
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 0fVariables:
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 #mems2018-02-24 03:03 AM
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.
2018-02-26 04:54 AM
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.
2018-02-27 08:50 AM
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).
2018-11-23 04:16 AM
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.
2018-11-23 04:39 AM
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:
2018-11-23 06:33 AM
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!