Stanley Lio‎ > ‎

Magnetic Field Measurement


I've always wanted to play with MEMS inertial measurement units (IMU) so I got a few 9 DOF IMU breakout boards off eBay. I have used the accelerometer (ADXL345) before, but I have never used the other 6 DOF: magnetometer (HMC5883L) and gyro (ITG3200). Can't do much with the gyro (rotation) without a wireless platform (or else the power and data cables get tangled very quickly), so the magnetometer is the only sensor left I can play with.

Considering the high data rate these sensors produce, the obvious thing to do to get a feel of how they work is to hook them up to my laptop. That is easy with the LUFA USB library on an Atmega32U4. I have a Python script to dump the received readings to a text file, and some MATLAB scripts to process and plot the data.

A good test to show that it's working properly is to measure the magnetic field around neodymium magnets, since I know what the field should look like.

Just take hundreds of readings over a grid around the magnets and plot them (two repelling magnets):

Repeat another 273 times to get another graph (two attracting magnets):

(Notice in the two plots above, the influence of the Earth's magnetic field has not been compensated for yet - don't want to repeat another 273 measurements manually)

Inverse Kinematics

Manually moving the sensor around and taking thousands of measurement is not very scalable nor very "academically challenging" - need to justify my expensive education somehow. I could get three motorized linear guide rails and move the sensor in Cartesian coordinate, but that's too bulky, costly and... where's the fun without the maths.

So I got some servos and (aluminium) mounting hardware off eBay, some screws and washers from a local hardware store, a few pieces of scrap wooden floor tiles from my neighbor (they are renovating) and put together a 3-DOF arm:

With inverse kinematics, I can generate a path (a set of waypoints) in 3D space with MATLAB, have the robotic arm trace them with Python and measure the magnetic field along the way.

Now that everything is automated, why limit the resolution to a 11 by 11 grid:

That's 51 x 51 = 2601 data points. This is the same data set shown at the end of the video, except that the proper coordinate transform has been applied (see the "Minor Details" section at the bottom of page for details). The graph below shows the background magnetic field (without the magnet):

You can see the influence of the steel screws and servo at the base of the arm on the background magnetic field. The base of the arm is at the lower left corner, where the background magnetic field is strongest. Pretty cool.

If I can do a square, why not a cube:

11x11x11 = 1331 readings. Imagine measuring those by hand. Gotta love robots. The graph below shows the path the robot followed:

Since I've got the inverse kinematics worked out, why not have some fun with the bot:

Perhaps I should do some light painting with this arm later.

Minor Details

Just a few points I thought worth mentioning.

Since the magnetometer is mounted at the tip of a 3 DOF arm, the pose of the magnetometer changes as the arm moves through space. The readings from the magnetometer are with respect to the sensor, so they need to be transformed back into the world frame for the graph to make sense.

The analog servo I used in the arm is too "soft" for robotic application - it doesn't hold position well even though it is advertised as "high torque" (Hitec HS-645MG). I have also experimented with the "high resolution" digital servos (HS-7966HB and HS-5485HB), but they tend to oscillate around the setpoints under load.

So What's Next?

I have a few things in mind.
  • Characterize and improve positioning accuracy, precision and repeatability
  • Add extra redundant DOF to measure full 3D space (rather than one side of the magnet)
    • Have fun with the math

Made it on Hackaday.

All Rights Reserved. Stanley Lio, 2015