SparkFun Forums 

Where electronics enthusiasts find answers.

Have questions about a SparkFun product or board? This is the place to be.
By MostlyHarmless
#89057
sebmadgwick-
OK. I think we're converging here. I forgot to add that you need to calibrate and align your magnetometer to get a heading. In other words to get a geo-referenced heading you need some sort of geo-referenced alignment procedure! I think we're on the same page with that.

I also was not specific with regards to all these errors being time-invariant, in other words, fixed wrt the sensor.

With those 2 clarifications, I think we're on the same page. Can't wait to try out all this with my magnetometer.
Cheers,
MH
By sebmadgwick
#89079
I've finally put together and tested my calibration code. Summary:
1) I use an x-io Board for DAQ so the code initially imports a CSV file (x-io application note AN2) and formats the data correctly to generate the 'mag' data vector. The logged data is of the sensor being moved slowly through many different orientations for 2mins. It is assumed that soft-iron characteristics are constant.
2) An initial guess for senor biases and gains is specified with the magnitude of the bias scaled to be of the same order of magnitude as the gain (this is important for the optimisation algorithm performance).
3) The MATLAB optimisation tool box is then used then to find the optimal values for the sensor gains and biases (incorporating hard-iron bias) that ensures the magnitude of measured field equals the specified field strength (‘h’) for all orientations.
4) The test data is then calibrated and plotted alongside the computed vector length which should (if the sensors are probably calibrated) equal the constant pre-defined field strength (‘h’).

Note that as this calibration process is applicable to accelerometers so the code also includes my accelerometer calibration (ADXL335).

The MATLAB script ‘AccMagCal.m’ requires the objective function ‘objFun.m’ to be present. I have also made my CSV file available in case anyone wants to run the code unmodified or start from a ‘working template’.

AccMagCal.m:
http://www.x-io.co.uk/resources/misc_dump/AccMagCal.m
objFun.m:
http://www.x-io.co.uk/resources/misc_dump/objFun.m
xioDataLog.txt:
http://www.x-io.co.uk/resources/misc_du ... ataLog.txt

I hope you find this useful.
By fvaldes
#95884
Hi,

I just went through all the different posts and I am wondering if somebody can tell me how exactly the Self-Test functionality of this magnetometer can aid in the Hard Iron Calibration.

In other words, if I was to validate whether it is possible to use this nominal field strength (From the offset straps) to perform hard iron calibration, how would I do it? and why would it be beneficial?

Any help would be appreciated!
By pizza
#107987
hey guys how do i rotate the magnetic sensor in a circle to see it's X and Y outputs?

i'm trying to do calibration.

i do not have a turn table. rotating it by hand will cause errors right? u mean how can a human possibly rotate something in a perfect circle.
so how did u guys did it? please advise! :(
By sebmadgwick
#108000
pizza, I think you misunderstand what is going on. Nothing is rotated in a circle. The magnetometer is rotated (i.e. turned around, spun, twisted) 360 degrees on a 2D surface. The 2D surface does not have to be level with the earth; only constant. You don't even have to rotate the magnetometer on the spot; provided that you do not move the magnetometer through different magnetic disturbances.
pizza wrote:hey guys how do I rotate the magnetic sensor...
A fool proof guide would be:
1) Fix the magnetometer to something that is non-magnetic and has a smooth, flat bottom. For example, fixed it to a SparkFun red cardboard box. You must ensure that the magnetometer axis you are not interested in is perpendicular to the flat surface.
2) Hold the box on a wooden table so that the bottom of the box is flush with the table. Now rotate the box 360 degrees, all the time ensuring that the bottom on the box is flush with the table.
3) The logged data for the 2 magnetometer axes parallel with the flat bottom (and table) should now provide you with a centred, circle on an 2D scatter plot ONLY IF adjusted with the correct gains and biases.
By pizza
#108019
ahh thanks for clarifying..

i'm planning to mount the magnetic sensor on a quadrotor, then calibrate by turning/spinning the quadrotor on a flat wooden table. do u foresee any difference/problems?

did you use the hmc 5843? the datasheet stated some self test function that can determine the scale factor. what is the difference between gain(i.e 1300counts/gauss) and scale factor? i have been getting very different scale factors at different angles from the x axis. perhaps i should plot it out and see whether it is an ellipse or something weird.

also, the datasheet specified offset cancellation as a feature, but it doesn't elaborate on it! :?:

should we calibrate for soft iron effects first or hard iron effects first?

thanks in advance :)
By pvmellor
#108055
I've been working on a different method - not sure if its valid or not...!

I've taken sample x, y, z data from the magnetometer whilst in random operational motion and plotted the magnitude of the vector (sqrt x*x+y*y+z*z). I figure this should be constant in a perfect world. I actually get the graph below: not bad as you can see - but not totally flat.
magBefore.JPG
So i take the average value of the magnitude, and then calculate the total deviation from the average across all samples. I then add/remove offsets from each sensor until i get the smallest total deviation (i.e. error) and thus the flattest line. This is shown in the second graph below: much flatter!. Values in this example are x=73, y=-38, z=-42.
magAfter.JPG
Now i've done this manually by hand (in excel). Question is: is this a valid approach? If so, can i derive the offsets automatically that will minimise the error deviation? If so - what's the maths needed to do it?

Thanks,
Paul.
You do not have the required permissions to view the files attached to this post.
By pizza
#108082
paul i don't think so, because there is no bounds for the standard deviation(aka how long do we need to sample the data for the standard deviation?)

what you're doing is flattening the data; a "low pass filter" that attempts to remove the random noise; not doing offset cancellation which is totally different.

to remove noise from sensors, normally people do averaging; but that slows down the response of the sensor.
By sebmadgwick
#108085
Paul, I like your intuitive approach. The principles of your method are indeed valid and I have the complete solution you are looking for.

The principle that there will only exist one set of gains and biases that will ensure sqrt(x^2 + y^2 + z^2) is constant for all orientations of the sensor within a constant homogenous field (you know this already). Solving this analytically would be near enough impossible. Instead we can use methods from the field of mathematics known as nonlinear programming; more commonly understood as optimisation.

We can quantify the error of our sensor calibration as the sum-of-the-square-of-the-error (SSE) between sqrt(x^2 + y^2 + z^2) at ‘m’ at all orientations, where ‘m’ is our known magnitude of the field (e.g. 9.81 m/s/s for gravity, and let’s just say 1 Gauss for magnetic field). If we then plot the error against all possible values of gains and biases in n-dimension space to create a surface, we can then consider the peaks and troughs of this surface. Because there will only exist one set of gains and biases that will minimise the error, there will be only one global minimum of this n-dimensional surface. Nonlinear programming methods allow us to navigate this solution surface according to its gradient to find this minimum and thus find the correct gains and biases.

I have attached 2 MATLAB files and an example CSV file. You will require MATLAB and the MATLAB optimisation toolbox. If you run “AccMagCal.m”, this will import the accelerometer and magnetometer data from the CSV file, run the calibration routine, plot the results and print the calibration parameters to the MATLAB command window. The plots will show the sensor x,y,z axes against sqrt(x^2 + y^2 + z^2), the success of the calibration can be validated by observing how flat the sqrt(x^2 + y^2 + z^2) line is. “objFunc.m” is the objective function that returns the SSE.

P.S. That CSV data is not perfect so the line is not as flat as it could be, but that’s the only data I have to hand right now.
You do not have the required permissions to view the files attached to this post.
By pvmellor
#108108
Seb,
That's very interesting. I have looked around at nonlinear optimisation and there's a lot of stuff out there! Sadly i don't have MATLAB access at present, and i also would like to find a solution i can embed. Do you know of any open source (preferably Java) code that can do this kind of calcuation? Or would you recommend a commercial package?

Thanks,
Paul.
By sebmadgwick
#108113
No access to MATLAB!? I couldn't live without MATLAB or at least without some IDE; I am sure that Mathmatica, R, Python etc will have equivalent resources (?).

An embedded solution sounds ambitious. I don’t think the problem would be in its implementation, more in its use. I have found that effective calibration requires only a small dataset provided that the logged data represents specific behaviour. This is best achieved by automating the sensor movement with the calibration routine - don’t think that this is too complicated; I tested this proof of concept with 3 old R/C servos and 2 cardboard boxes which acted as non-magnetic booms. If you can only provide your calibration routine with a crude dataset (arbitrary motion by hand) then the chances are that you’ll need many more data points – perhaps more than is practical for a uC (RE: RAM).

An easy way to implement the method I described in my previous post is to use the Gauss-Newton method, this will be no way as fast (required number of iterations) as the BFGS method used in my MATLAB code but it is simple and will find the gains and biases eventually. Provided you have enough uC RAM and don't mind waiting while the poor little chip crunches through all those numbers, this should be easily implementable on an embedded system in what even langauge you like.
By jremington
#108217
Scilab is free, runs on linux, Mac, windoze and is strongly recommended! Scilab has most of Matlab's features but the syntax is slightly different. Fortunately, there is a built-in converter that will translate Matlab *.m (program) files into Scilab instruction files.

Download Scilab here: http://www.scilab.org/products/scilab/download

The conversion function is described here:
http://www.vislab.uq.edu.au/users/manua ... le2sci.htm

Scilab accepts "help" as a command at the prompt.

Cheers, Jim
By pizza
#108308
thanks! i've downloaded scilab shall try seb's code soon!
btw, my purpose is to obtain heading information from hmc5843. i do have accelerometers and gyroscopes on my platform(sparkfun 5dof), and i intend to correct the yaw drift with hmc5843.

after reading around online and what you guys have posted, i want to find max and min points, offset and scale factor for calibration.
however turning the sensor by hand tends to produce different data.

the averaged offset and scale factor does not result in a uniform sqrt(x^2+y^2+z^2).
therefore my 0 to 360degree heading is not linear~~

by the way, correct me if i'm wrong, shouldn't heading be 0degree when pin 1 is facing up, 90degree when pin 1 of facing left for example? in order to align with accelerometer and gyroscope! at least that's what the other 2axis compass (hmc6532) does!
but that doesn't happen to me even after calibration. i get 70+degrees when it's supposed to be 90degrees!

and i've noticed an anomaly in many repeated attempts of data logging, please see attached. what do you think could have caused that?
also, to filter noise, i am using 4th order runge kutta.

and one more thing: is the Z axis measurement supposed to be constant when turning the sensor on a flat 2d surface? my z axis appeared like a inverted sine wave!
You do not have the required permissions to view the files attached to this post.