Magnetometer Calibration

Hello...
Sorry if this is silly but it seems i am realy stuck.

I am Creating theater Mask that rotates on head of actor and is always hiding his head independetli of his facing direction.

I have stepper motor with gearbox and Magnetometer (HMC5883L) to scan for direction of mask.
Everything is working fine exept for HMC5883L is very inaccurate in horizontal rotation.

I read many articles about calibrating thease things and i managed to get some numbers out of "Magneto v1.2" but i have absolutli no idea how to use them.

I am using standart "Adafruit_HMC5883_U.h" library for controling senzor but theres just Magnetic Declination corection which doesnt do much.
Using Arduino NANO.

Thank you for any replay ... or if you have any other idea how to monitor direction of mask please let me know (optical flow senzor is WAAaay out of my league). Or if theres any other Magnetometer which doesnt need calibrating.

Thank you sooo much. Czech Republic.

What effect does an operating stepper motor and control and power supply have on your magnetometer?
Paul

In this stage none ... ist on long wire far from anything that could intefeer.

The best and most comprehensive tutorial on magnetometer calibration is this: Tutorial: How to calibrate a compass (and accelerometer) with Arduino | Underwater Arduino Data Loggers

Thank you very much ... i tried some of thease tutorial but i get to the point where i get all the information i need but i have no idea how to use them. cant get my head around it.

thats all i got ... how do i punch this think to work for me?
thank you again.

In the Arduino program that collects the magnetometer data, you add code to apply the correction factors that are produced by Magneto.

Post your code, using code tags.

An example from one of my projects:

// correction constants from Magneto

float M_B[3]
{ -922.31, 2199.41,  373.17};

float M_Ainv[3][3]
{ {  1.04492,  0.03452, -0.01714},
  {  0.03452,  1.05168,  0.00644},
  { -0.01714,  0.00644,  1.07005}
};
float Mxyz[3],temp[3];

...  
// get magnetometer data

  Mxyz[0] = imu.mx;
  Mxyz[1] = imu.my;
  Mxyz[2] = imu.mz;

//apply mag offsets (bias) and scale factors from Magneto

  for (int i = 0; i < 3; i++) temp[i] = (Mxyz[i] - M_B[i]);
  Mxyz[0] = M_Ainv[0][0] * temp[0] + M_Ainv[0][1] * temp[1] + M_Ainv[0][2] * temp[2];
  Mxyz[1] = M_Ainv[1][0] * temp[0] + M_Ainv[1][1] * temp[1] + M_Ainv[1][2] * temp[2];
  Mxyz[2] = M_Ainv[2][0] * temp[0] + M_Ainv[2][1] * temp[1] + M_Ainv[2][2] * temp[2];

Ok ..i been experimenting with this for some time ... reading alot and the only think i can say for sure is that people are just realy confused from this ... this topic is not rare.

I am realy sure Jremington that you are smart and educated man in this stuff ... but everybody canot remeber mathematical matrixes or some people didnt studdy math/computer school at all.

i realy cannot make anything from your suggestions, and not just from my Topic ...but about Calibrating at all.

sorry .. i am not trying to be rude , realy ... but i have this feeling that one Magnetometer is not realy that huge rocketScience and Arduino as a project is trying to be accessible to artists and hobbyists that lack your level of skill.

So i am sorry again ... but i realy dont understand ... can you please be more explaining?

Still using Adafruit exaple code.

#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_HMC5883_U.h>

/* Assign a unique ID to this sensor at the same time */
Adafruit_HMC5883_Unified mag = Adafruit_HMC5883_Unified(12345);

void displaySensorDetails(void)
{
  sensor_t sensor;
  mag.getSensor(&sensor);
  Serial.println("------------------------------------");
  Serial.print  ("Sensor:       "); Serial.println(sensor.name);
  Serial.print  ("Driver Ver:   "); Serial.println(sensor.version);
  Serial.print  ("Unique ID:    "); Serial.println(sensor.sensor_id);
  Serial.print  ("Max Value:    "); Serial.print(sensor.max_value); Serial.println(" uT");
  Serial.print  ("Min Value:    "); Serial.print(sensor.min_value); Serial.println(" uT");
  Serial.print  ("Resolution:   "); Serial.print(sensor.resolution); Serial.println(" uT");  
  Serial.println("------------------------------------");
  Serial.println("");
  delay(500);
}

void setup(void) 
{
  Serial.begin(9600);
  Serial.println("HMC5883 Magnetometer Test"); Serial.println("");
  
  /* Initialise the sensor */
  if(!mag.begin())
  {
    /* There was a problem detecting the HMC5883 ... check your connections */
    Serial.println("Ooops, no HMC5883 detected ... Check your wiring!");
    while(1);
  }
  
  /* Display some basic information on this sensor */
  displaySensorDetails();
}

void loop(void) 
{
  /* Get a new sensor event */ 
  sensors_event_t event; 
  mag.getEvent(&event);
 
  /* Display the results (magnetic vector values are in micro-Tesla (uT)) */
  Serial.print("X: "); Serial.print(event.magnetic.x); Serial.print("  ");
  Serial.print("Y: "); Serial.print(event.magnetic.y); Serial.print("  ");
  Serial.print("Z: "); Serial.print(event.magnetic.z); Serial.print("  ");Serial.println("uT");

  // Hold the module so that Z is pointing 'up' and you can measure the heading with x&y
  // Calculate heading when the magnetometer is level, then correct for signs of axis.
  float heading = atan2(event.magnetic.y, event.magnetic.x);
  
  // Once you have your heading, you must then add your 'Declination Angle', which is the 'Error' of the magnetic field in your location.
  // Find yours here: http://www.magnetic-declination.com/
  // Mine is: -13* 2' W, which is ~13 Degrees, or (which we need) 0.22 radians
  // If you cannot find your Declination, comment out these two lines, your compass will be slightly off.
  float declinationAngle = 0.22;
  heading += declinationAngle;
  
  // Correct for when signs are reversed.
  if(heading < 0)
    heading += 2*PI;
    
  // Check for wrap due to addition of declination.
  if(heading > 2*PI)
    heading -= 2*PI;
   
  // Convert radians to degrees for readability.
  float headingDegrees = heading * 180/M_PI; 
  
  Serial.print("Heading (degrees): "); Serial.println(headingDegrees);
  
  delay(500);
}

Thank you again fro your time. I am just desperate.

If you want to understand how to do this stuff, you have to learn that math. Otherwise, ask or hire someone to write it for you. The HMC5883L is no longer manufactured, so you might have a tough time doing that.

Adafruit has a calibration tutorial and ready made code on their web site, for the magnetometers they sell, so you don't need to write anything (just buy their product).

Edit: it is possible that Adafruit's calibration code supports the HMC5883L, which they used to sell. Take a close look at it and/or inquire on the Adafruit forum. Magnetometer Calibration | Adafruit SensorLab - Magnetometer Calibration | Adafruit Learning System

Thank you again ...

problem with Adafruit's guides are that they dont work for NANO (Error compiling for board Arduino Nano.)

problem with MagMaster guides is that for some reason senzor outputs nonchanging value (like i am not moving it)
https://www.instructables.com/Easy-hard-and-soft-iron-magnetometer-calibration/

and problem with any other guide is that it dosnt explain the last step how to get Bias and Matrix into the code itself ...

i gues my best bet is to buy different arduino tomorow.

Hi,

What code and what errors?

Thanks.. Tom... :smiley: :+1: :coffee: :australia:

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