cancel
Showing results for 
Search instead for 
Did you mean: 

Trying to use magnetometer II2SMDC to get angle of rotation of a plan

SimonF
Senior

Hello,

I'm using the mems II2SMDC from where I get X, Y and Z values.

  • I set ODR to 100Hz, COMP_TEMP_EN to 1 and MD_CONTINOUS to 1 for CFG_REG_A (note that low power is disable)
  • I set DRV_IIS2MDC_LPF to 1 for CFG_REG_B
  • I set DRV_IIS2MDC_BDU to 1 for CFG_REG_C
  • I also enable offset cancelation (DRV_IIS2MDC_OFF_CANC) in CFG_REG_B because otherwise values are completly random / wrong.

I'm using X and Y to get an angle on the plan (X, Y) using atan2.

(In fact I'm using X and Z because I attached the mems to a door to detect opening, closing but it does not matter)

My algorithm is a lot inspired from this post : https://arduino.stackexchange.com/questions/18625/converting-three-axis-magnetometer-to-degrees)

Here is my function which converts from X, Y and Z raw values to angles in degrees :

static double main_calculate_angle_degree(int16_t x, int16_t y){

double angle;

angle = atan2((double)y, (double)x);

if (angle >= 0) {

angle = angle * (180 / M_PI);

}

else {

angle = (angle + 2 * M_PI) * (180 / M_PI);

}

return angle;

}

Here is my algorithm :

I have an offset which makes x = 0 in default position. This offset is applied to all axes ( I tried without this offset and it makes no difference )

Some observations :

When angle = 0° : X² + Y² = 2² + 35² = 1229 (X is the average of 5 X values and the same for Y) Then I rotate my mems of 90°, the angle displayed by my device is around 70° : X² + Y² = 300² + 103² = 100609. I guess the value should always be the same because I am just rotating the magnetometer.

Moreover the result is wrong because East (0°) is not "aligned" with West (180°) . What I means is that when my algorithm says 180° I have rotate my mems from lots less or lots more. In fact there is not an angle of 90° between any "axes" (N, S, E or W).

My real problem is that my angle is not moving "linearly". For example, in the image below, between North and East, with atan2 I get 270° which is obviously wrong regarding to the direction.

I added the image of what I see.

diagram starts with East : angle = 0°. South is draw when angle = 90°.

1 ACCEPTED SOLUTION

Accepted Solutions
SimonF
Senior

Hi @Eleon BORLINI​ ,

Thank your for pointing out the hard-iron effect ! This was my mistake !

I looked at the (X, Y) graph and indeed the center of the circle was not, well, centered.

I now understand that I need to use a calibration step like phones do. Indeed, you need to rotate your device to get current center position and then use an offset to center you magnetometer values. (this offset is the average of max and min value)

Pictures I link show the before and after hard-iron effect.

To all people finding this post, I suggest your to read this blog which is quite clear on how to compensate the hard-iron and soft-iron effect : https://www.fierceelectronics.com/components/compensating-for-tilt-hard-iron-and-soft-iron-effects

( Sorry but the design tips link you give @Eleon BORLINI​  with Matlab algorithm is too complex / not easily physically understandable when you try to figure out "why")

Hope this post will help others.

Simon

View solution in original post

4 REPLIES 4
Eleon BORLINI
ST Employee

Hi @SimonF​ ,

I see you are performing the offset cancellation procedure. After this step, you have to run the so called hard-iron compensation, that occurs when a magnetic object is placed near the magnetometer and appears as a permanent bias in the sensor's outputs. The hard-iron correction consists of compensating magnetic data from hard-iron distortion (see application note AN5080, p. 19)

Then the algorithm (the atan2 formula and the degree conversion), although quite rough, seems ok, but I suggest you to have a look also to these design tips, if they can improve your code (for the magnetic section, even if it is intended for a full eCompass, i.e. with the acceleration data too).

-Eleon

SimonF
Senior

Hi @Eleon BORLINI​ ,

Thank your for pointing out the hard-iron effect ! This was my mistake !

I looked at the (X, Y) graph and indeed the center of the circle was not, well, centered.

I now understand that I need to use a calibration step like phones do. Indeed, you need to rotate your device to get current center position and then use an offset to center you magnetometer values. (this offset is the average of max and min value)

Pictures I link show the before and after hard-iron effect.

To all people finding this post, I suggest your to read this blog which is quite clear on how to compensate the hard-iron and soft-iron effect : https://www.fierceelectronics.com/components/compensating-for-tilt-hard-iron-and-soft-iron-effects

( Sorry but the design tips link you give @Eleon BORLINI​  with Matlab algorithm is too complex / not easily physically understandable when you try to figure out "why")

Hope this post will help others.

Simon

Hi @SimonF​ ,

thank you for you feedback and your solution report.

You are right, the "figure of 8" shown by smartphone apps is for the magnetometer calibration.

0693W0000059anlQAA.png 

-Eleon