The Magnetometer

We have a need to detect the presence of magnets especially small grain of sand sized magnets such as those found in certain mineral samples. We needed a magnetometer with milli-Gauss sensitivity and the ability to measure the strength of static (non oscillating) magnetic fields. We also didn’t want to spend a fortune on it especially since it was not important to us to measure the field strength only detect it. After searching the likely suppliers we realized there was not a commercial solution that would fit our needs. Fortunately, there are readily available breakout boards which expose an i2c interface to an LSM303 series accelerometer/magnetometer sensor; so we can build our own.

Parts List

Assembling the Hardware

The nice thing about the Adafruit Feather line is that it is possible to stack components. This allows us to create compact devices that fit nicely in 3D printed cases. I selected the Feather 32u4 because it was cheap but plenty powerful for the task. My original idea was to connect the LSM303 to the microcontroller using the small protoboard on the 32u4 and the Feather OLED using the included “male” headers to the Feather 32u4 outfitted with female headers.

Early magnetometer sketch design

There were a few flaws in this plan. First the LSM303 breakout board stuck up above the display which was unsatisfying but could have been dealt with in the case design. Second and more importantly, both the LSM303 and the Feather OLED 128×32 use i2c to communicate. Unfortunately, the SCL/SDA lines on the Feather 32u4 are not exposed on the protoboard area so if one solders a header in to the SCL/SDA pinouts, it is difficult to attach anything else. [Adafruit: suggestion for a design revision double the pinouts for the SCL/SDA, RX/TX, digital 5&6 and maybe MISO/MOSI/SCK along the sides of the proto area then provide GND/3V along the inboard edge of the protoboard] Therefore, I changed course and chose a through hole header for the Feather 32u4 and moved the LSM303 to a Feather Wing Proto equipped with the female headers.

Magnetometer design revised on account of duplicating I2C pins.

When the parts arrived I soldered the female headers on the protoboard and connected the inboard SCL, SDA, GND and 3V pins with some scrap 28ga wire to a 4 lead header which I bent with a pair of needle nose pliers to make a right angle header. I then soldered the LSM303 to the right angle header. I soldered the Through hole headers onto the Feather 32u4 and the male headers onto the Feather Wing OLED

Tips… To solder the male headers stick them in a protoboard, place the Wing on top and solder. You can then pull the soldered board off the protoboard turn it upside down and stick the through hole or female headers on the male headers and solder the other boards onto the headers. Remember your boards will be upside down and you will be soldering on the bottom of the board when when soldering on the female and through hole headers.

Magnetometer innards assembled

The Software

You can find the software for this project on Github. It has been shared under the Apache License 2.0 so you may do as you see fit with it. Basically, the code polls the magnetometer displays the reading and if the reading goes above a set level it also displays that the sample is “Magnetic!”. It is rather cut and dry except for the bit where the reading is compared to a magical constant. On a first readthrough this should be suspect and thus it deserves a second look.

Our sensor measures magnetic field strength as a vector. It could report that as a magnitude and two angles relative to some line through the sensor in which case our code would be easy. We could simply compare the magnitude of the observed magnetic field to the magnitude of the background magnetic field and if the magnitude of the observed magnetic field is greater than the background magnetic field then we can conclude there is a magnet near our sensor. Since our magnetic field strength is however reported as the components along orthogonal unit vectors (x, y, and z components) we can use the distance formula to compute the magnitude.

d = (x2 + y2 + z2)1/2

Taking the square root of a number is however very slow on a computer and since we don’t care about the true magnitude of the vector, only if it is larger than some value we can simply square both sides of the equation and decide whether the square of the magnitude is larger than a particular value. Next there is the question of the choice of that particular value. Too low and we could read a magnet where there is not one. As we live on Earth a planet with a magnetic field, there is always at least Earth’s magnetic field as background. The strength of that field is however not constant, changing from place to place. Our sensor is sensitive enough to detect fluctuations in the field due to being in a building. Therefore the determination of the magnitude of the background magnetic field strength is not simple. I choose the constant used based on empirical observation. It is the result of polling the sensor when the sensor is as far from everything as I could get it, recording the maximum magnitude of the magnetic field (squared) and rounding up. It is therefore a suspect number and should be treated as such. It does however detect samples we know are magnetic at a bit of distance thus we have some confidence in it.

Software engineering often includes numbers picked because they work and not because they are completely justified. This can result in a playable game rendered in 3D on hardware that should not come anywhere close to being able to render 3D scenes it can also result in algorithms discriminating against people. Seemingly arbitrary constants should always be challenged in a code review and their elimination is often an easy improvement. See also below for more ideas to improve this project.

The Case

Our project is composed of four circuit boards with exposed solder work at this point. It is also just loosely stuck together. Ideally we would put it in a case of some sort to help hold it together and protect it from damage, especially from static discharges. In the dry winter weather we often build up static charges on our skin (relatively electrically insulating) which is why we feel a “zap” when we touch a door knob. Those zaps can damage electronics. Our case can not be metallic as the metal would absorb some of a magnetic field effectively muting small fields. Fortunately, the Maker-E on campus is equipped with a variety of 3D printers. I used CAD software to design a case and printed it in PLA using our Makergear M2. Thanks to Matt Lamparter for his help fabricating the case. STL files are included in the git repository should you wish to print your own.

Future Refinements

  • Make the calculation of the magic constant representing the magnitude of the background magnetic field happen automatically at startup. This would eliminate the magic constant and make the magnetometer useful outside the lab.
  • Refine the case. The PLA slumps a bit when printing even at the 3mm wall thickness used. Other materials may print with better dimensional accuracy or the design may just need tweaked to compensate. The case was also designed to be held together with some 2-56 flat head bolts and hex nuts. the bottom case is tight enought that a dot of hotmelt glue works and saves the expense of buying odd sized bolts.

Posted

in

by

Tags: