0%
0%

# 3D Magnetic Field Scanner

Capture interactive models of magnetic fields with your 3D printer

Similar projects worth following
There are several ways for amateur scientists and students to visualize magnetic fields, including traditional compasses, iron filings, magnetic viewing film, or even ferrofluid. None of these methods give a comprehensive picture of the field over 3D volumes, however. While commercial devices for scanning 3D magnetic fields exist, their cost puts them out of reach of individuals and many organizations.

This project will provide an open-source (MIT License, where possible) way to convert an existing 3D printer into a magnetic field scanner with which you can visualize the field surrounding permanent or electro- magnets, and explore the field's interactions with various materials.

All text and images I have created on this project write-up are released under the CC-BY-SA 4.0 license. Comments by others on this project remain the intellectual property of their respective authors.

# Concept

The basic idea is to use a cheap 3-axis magnetometer (aka compass) sensor to sample the magnetic field vector, B, at a number of 3D positions within a volume, then use interpolation to estimate the field in between these positions. An off-the-shelf 3D printer is used to scan the sensor through the volume. The scanning program uses vanilla g-code commands suitable for any industry-standard printer. Compensation for external fields, such as those produced by our planet or stepper motors within the printer can be made one of two ways. For permanent magnets, an initial baseline scan can be made without the target, then the results subtracted from the actual scan. In the case of electromagnetic targets, taking two data points at each position - one with the current on, and one off - achieves the same goal. A number of different visualizations can then provide an interactive exploration of the field. Using python for the scanning app and WebGL for the visualization should provide a relatively platform-independent experience.

The first rough prototype used off-the-shelf modules, including an Arduino and an HMC5883L breakout board from Adafruit to get a proof-of-concept result. I've now switched to using a Melexis MLX90393 magnetometer, which allows a much wider (60x more) range of field strength, and am designing a custom scanning head using this part.

# Show Me Something

Here's a sneak-peek from the proof-of-concept (with a hard-coded/pre-computed visualization of actual data). More details on this first test can be found in the first project log. The viewer is a WebGL app hosted on my server, since I can't embed it here:

This may or may not work on your platform: at least WebGL is required. I've tested it on linux (Firefox, Chromium), my Android phone, and a friend's iPad and Windows 7 machine, and it worked on all of those. It bugs me that this has to be off-site: I'm offering a one-skull bounty to anyone who can get embedded WebGL to work directly in hackaday.io :-)

# Project Phases

I've divided planned development into four basic phases, intended as rough guidelines on which to base releases:

## Phase 0

The proof-of-concept that generated the results above. This code is truly hacked together, and a release would cause more problems than it solved, so it's not going out. More details of this effort can be found in the first project log.

## Phase 1

First planned release. The goal is to have two programs, a python scanner and a WebGL browser-based visualizer. Features to possibly include:

Scanning

• Manual scan limits - scanning above an object only, and it's up to the user to specify the 3D coordinates of the bounds

Visualizations

• Field Lines (interactively generated based on user parameters)
• |B| axis-aligned intensity cross-sections
• Image mapping an overhead image of the object into the 3D visualization, with program-assisted registration

Sensor

• MLX90393 evaluation board on 3D printed probe

## Phase 2

Scanning

• Scan limits based on user-supplied 3D model of target. This is very convenient for printed targets (coils, etc), and rough bounding volumes can easily be created for arbitrary targets. The scanning software calculates the scanning paths to avoid striking the target.

Visualizations

• Iso-lines (2D axis-aligned iso-B lines in 3-space)
• Iso-surfaces (from Marching Cubes)
• User-supplied target model in 3D visualization

Sensor

• First pass at miniaturized custom probe using MLX90393

## Phase 3

This phase is the full-custom hardware step, incorporating everything learned in the first [three]. As such, it's subject to radical change as we go.

Scanning

• Automatic scan limits based on machine vision or "bump" sensors. These might include optical proximity detectors, microswitches, or wire-in-coil contacts (what are those "whisker" feelers called, anyhow?). The idea is to drop in a target and press the button to scan. The printer doesn't destroy the target or itself during scanning.

Visualizations

• Who knows, I'm sure there's some cool things to be done

Sensor

• Fully...

### board_sketch.zip

work-in-progress sensor PCB ideas

x-zip - 70.46 kB - 07/01/2016 at 22:41

• ### MLX90393 Breakouts Commercially Available

Ted Yapo02/18/2017 at 21:04 0 comments

Sparkfun has made an MLX90393 breakout board the first in their new SparkX series of products, as mentioned recently on the Hackaday blog. I'm not going to make this log an advertisement for them, but if you wanted to get started with this sensor, this is a reasonable way to do it.

I haven't used one of these breakouts personally, but they seem to have the basics covered. There's no mention if the board contains nickel (ENIG finish) or if the capacitors are special non-magnetic types (I can pick up Adafruit's HMC5883L breakout with a magnet due to the ferrous terminals on their SMD capacitors! - but that probably doesn't matter if you use it as a compass and perform hard iron calibrations). If you are using these things inside variable magnetic fields (especially over very wide dynamic ranges), any ferromagnetic material like that can cause problems as it becomes slightly magnetized in the strong regions of the field, then is mis-calibrated in subsequent weak regions. But, even if it has nickel on the board and iron in the capacitors, it should work well enough for almost all practical uses.

Anyway, Sparkfun said nice things about this project and my driver code, so they must know what they're doing :-)

• ### Scramble Winding: Take Two

Ted Yapo07/28/2016 at 18:01 0 comments

@peter jansen had an interesting take on my earlier Monte Carlo simulations exploring the effects of scramble-winding coils vs neatly layered windings. He wondered how the angle of the field was perturbed by the random windings - my previous simulations had all examined just the magnitude of a single component of the field (in the axial direction). It turns out that the framework I'd put together for the earlier analysis just needed a little tweaking to examine angles.

Here's a representation of the field vectors at each point, Pk, in space:

Br is the field vector in the center of the reference coil - in this case, a 40mm radius Helmholtz coil with two single-loop windings, while Bf is the field vector for a particular sample of scramble-wound coil. The angle between the fields can be calculated by:

I already had the code to draw contour areas based on thresholding scalar values, so I substituted this angle for the previous magnitude criterion. As before I ran 10,000 randomized simulations of scramble-wound coils, then used symmetry for an equivalent 40,000 samples. I'll skip presenting the individual images here, and jump right to the probability distributions:

The left image is the magnitude distribution from before: the colors indicate the probability of achieving less than 1% error in the x-axis component of the field. On the right, we see the new analysis: the probability that the angle of the generated field vector is within 0.5 degrees of the reference field direction (equivalent to a 1-degree wide cone around the reference). Note that the reference here is the field in the center of the reference coil; not the field at the the corresponding spatial point in the reference field. The shapes of the level curves look complementary or "dual" in some vague but satisfying way.

Like the magnitude version, the angle plot is difficult to read; to get a better view, I again thresholded the probability. This plot represents the area in which you have a 99.9% chance of the field being within 0.5 degrees of the reference (I have to figure out why the title text is getting cut off):

Of course, you might care about both magnitude and direction. Here's a similar pair of plots for the logical and of the conditions: P(magnitude error < 1% and angle error < 0.5 degrees):

In this plot, I've used the total magnitude of the B field, instead of just the x-component magnitude as in the others. The right image is again thresholded at 99.9%. The thresholded region encloses a sphere of 15mm diameter, just a little smaller than the 16mm using the magnitude criterion alone.

I'm planning to add a version of this code to the GitHub repository, but I have to clean it up a bit, and make a decent API for the two pieces. Another thing to add to the to-do list :-)

• ### Arduino MLX90393 Library

Ted Yapo07/23/2016 at 22:19 0 comments

I'm probably not going to use an arduino as the controller for this project, but I realize a lot of people do use them, so I wrote what I think is a pretty comprehensive arduino library for interfacing with the MLX90393 over I2C. The code is here on GitHub. If you use it with a 5V arduino board, remember to include level translators to avoid damaging the MLX90393, which doesn't have 5V-tolerant I/Os. You have the option of connecting the DRDY line to one of the arduino inputs for the end-of-conversion signal or using a timed-conversion mode based on the timings in the datasheet.

So far the code has just a little mileage on it, so watch for anything funny. The basic functions all seem to work.

After having to deal with the way the arduino build system handles includes, I feel like I need a shower. Ick.

• ### Scramble vs Layered Winding

Ted Yapo07/20/2016 at 16:08 2 comments

I wind a lot of coils. Mostly, they're for RF use and either on toroids, or just simple free-standing air-core coils. I'm always careful to wind them neatly. When I started winding coils for testing magnetometers, however, I found I couldn't easily wind neat, layered coils on these particular spools by hand. @peter jansen solved this problem by building a nice coil winder. Being the impatient type, I took the other approach - scramble winding (aka jumble winding). We've all seen this done on on electric motors and other "electromagnet" components, and I even remember seeing some RF chokes from the vacuum tube era wound like this. What does this type of "random" winding do to the magnetic field? I decided to run some Monte Carlo simulations to find out.

Unfortunately, the tool I had at my disposal, the python loopfield package I wrote earlier, was painfully slow - each simulated coil took about two minutes to run on my laptop. If you've looked at the code, you know the dirty little secret - the first version was not vectorized. An evening of coding, and the newest version (on github and pipy) is vectorized over the field points, greatly speeding execution. Simulations on my laptop went from two minutes to about 1.6 seconds each (and a decent portion of that is for writing output images) - much better for doing thousands of Monte Carlo runs.

While I remember - the bug in matplotlib I stumbled into with the field-line plotting is known, fixed, and closed and will be rolled into the next point release. For now, the linked bug report has a better patch than my earlier suggestion.

Here's the model I used for scramble-wound coils. If you can think of a better one, let me know. I tried to capture the constraints that go into an actual coil:

The 100 turns are still organized into 10 rough "layers" - each of the 10 turns within a layer is assigned a nominal radius, then this value is perturbed by a uniform random floating point value between -5 and 5 winding spacings (the coil form is 10 "spacings" high). The idea is to capture the fact that turns may not have a well-defined radius, but constraints of winding the coil onto the spool still enforce an approximate layering. Similarly, in the axial direction, the turn position within the winding is perturbed uniformly between -5 and 5 row widths. These perturbations allow a loop nominally in the exact center of the winding to end up anywhere within the coil form. Since the coil really is in 3D, the off-axis tilt is moved into a random radial direction instead of remaining in the plane as the diagram might suggest. The center position (which may now be off the central axis) and the loop normal (which is generally no longer in the z-direction) are calculated from the nominal coil locations and offsets. This model assumes infinitely thin current loops, so there's no allowance for minimum spacing between windings - it's possible the model could place loops in exactly the same space (certainly closer than finite-diameter wire would allow). This perhaps isn't the best physical model for scramble-wound coils, but I think it's on the conservative/pessimistic side, and should at least give a qualitative feel for how the field uniformity is affected by "random" windings.

I ran 10,000 simulations of coils randomly generated in this way (using the numpy.random.random_sample() function, which I believe uses Mersenne Twister underneath). To analyze the results, I plotted the 1%-error contour area (relative to the two-loop reference coil) to a series of PNG images. Here are some representative images generated by the random sampler (the left image has the smallest area of the 10,000 samples, the right image has the largest, and the middle was arbitrarily chosen):

I think the left-most image is a pathological case; my simple model for random coils can easily generate non-physical arrangements of windings. Until I come up with a better model, I'll have to rely on a statistical approach.

I wrote a second...

• ### Duh! and Scans!

Ted Yapo07/10/2016 at 14:39 1 comment

# Offset Calibration (Duh!)

Sometimes it takes me a while to "get it." Unfortunately, in this format "a while" may be several build logs. This is one of those cases. The original sensor I was using, the HMC5883L, is intended as a compass sensor. Calibration of compass sensors is a well-studied problem, and information about how it works and how to perform it abounds. I had initially dismissed using a compass calibration procedure for the scanner since it only calibrates ratiometric accuracy (the relative scaling of the x-, y-, and z-axes) - exactly what you need for a compass, but not terribly useful for absolute field measurements. In the usual procedure, a large number of measurements are taken with the sensor in random orientations in the geomagnetic field. Plotted in 3-space, the measured field vectors lie on an off-center ellipsoid. Calculating the transformation required to make it a sphere gives you the relative sensitivities of the three axis sensors, while centering the sphere yields the offset. Exactly the offset I need to program the MLX90393 temperature compensation. I think combining a modified "compass calibration" for offsets with some field-coil measurements for scale calibrations will probably work. I'll be exploring this, and will post the results once I have something usable.

# Scans!

I got the original demo code re-factored to the point that I can make new scans now. I also wrote field-line integration code in JavaScript so it can run live in a browser, and performance really isn't too bad. For now, I'm using simple Euler integration, but I found this paper on particle tracing in vector fields which explains a higher-order Runge-Kutta method which I will implement going forward. Then there's the topic of interpolation method; for now, I'm just using a simple trilinear interpolation, but I'm going to look into other methods to see if they can provide more accurate results. In any case, here's a low-resolution test scan of a small permanent magnet, captured with only 7x13x13 samples:

This visualization was done with no calibration whatsoever - no baseline scan, and no offset or scaling from the raw MLX90393 data. It's not numerically accurate, but qualitatively it looks like I'd expect - field lines in loops from north to south. I made a quick model of the magnet in OpenSCAD - this kind of model will be useful when scanning around items: the path-planning code can use such models to avoid collisions with the scanning probe. You can see me sneaking in to measure the magnet during this video of the scan. Remember, don't put your hands inside the printer while it's running. The video is sped up - for now, the scanning is very slow, taking about 20 minutes for this scan, but I think this can be improved quite a bit.

Watching the scan is a little like watching grass grow. I wanted to show it, however, to illustrate the type of magnetic "clutter" one typically finds in a 3D printer: stepper motors and steel rods and frame. How much does that affect the scan? I'm starting to find out. Here's an identical baseline scan taken with the magnet removed:

The colors aren't on the same scale between the two plots; the code currently stretches for maximum dynamic range. The baseline, which should consist just of sensor offset and the geomagnetic field, has a range of 141-228 μT, while the bar magnet shows a range of 13-11,485 μT. The interesting thing about the baseline scan is that the field appears to be fairly uniform, except for a slightly stronger field on the negative-x (left) side of the volume. Is that the influence of the stepper motor on the upper left of the video? I'm not sure yet. What appears to be the case is that this baseline is repeatable - I've seen similar fields with each "empty" scan. I haven't diff'ed baseline scans yet to get a quantitative comparison, but so far, it looks like you could correct for this quite easily. The code isn't quite where it needs to be to apply such a correction, but that's...

• ### MLX90393 Temperature Compensation Tests

Ted Yapo07/08/2016 at 17:14 0 comments

After some discussion with the application engineer at DigiKey and a bit of hacking, I think I understand how temperature compensation on the MLX90393 works well enough to incorporate it into the driver. It will take some time to re-write the code incorporating what I've learned, but I wanted to get this documented while it's still fresh. I might be wrong about any or all of this; if you notice an error, or have different information about this part, please let me know. Part of the problem is that the factory-supplied parameters just seem to give lousy results, so for a long time I figured I was using the part incorrectly. I don't think so anymore.

# Temperature Sweeps on the Cheap

To test temperature compensation, you need to have a way to sweep temperature. I actually have a cobbled-together environmental chamber consisting of a thermoelectric heater/cooler controlled with a decent thermostat. However, using it for these experiments was inconvenient, so I used a simpler technique. Since the MLX90393 has an on-die temperature sensor, you can generate temperature sweeps by heating (or cooling) the part and collecting data while it drifts back to ambient. This technique has a few potential problems, including the accuracy of the on-die temperature sensor and the exponential temperature curve. The later causes the temperature to move too quickly at the beginning (hot or cold) of a sweep, and too slowly as the part equilibrates to ambient. You might improve the technique with an insulating blanket (say of Styrofoam) slipped over the part after the initial heating/cooling, then removed once the sweep rate drops. I didn't bother.

Here are the tools of the trade:

The "canned air" is actually 1.1-Difluoroethane, a refrigerant with a boiling point of -25C. The label explicitly tells you NOT to spray with the can upside down, so don't do it! But when you do, you get a stream of liquid coolant instead of the gas. A brief shot of liquid on the device-under-test brings it below 0C to start the cold sweep. This is much cheaper (and more widely available) than official "cooling spray." The hair dryer (which I could use in my youth, but is unnecessary now) is self-explanatory. I didn't use a heat gun since it would be too easy to harm the PLA printed components, epoxy, or even solder joints. Here's a plot of a typical temperature profile for the part mounted in my epoxy potting:

The datasheet lists -20 to 85C as the operating temperature range, but I'm going to assume people can make do with a more narrow range in the magnetic field scanner.

# Configuring Temperature Compensation

As far as I can glean from the available documentation, the on-chip temperature compensation algorithm is controlled by 7 parameters:

• TCMP_EN : boolean which enables temperature compensation
• TREF : breakpoint for piecewise-linear compensation algorithm. Factory trimmed
• Sens_TC_HT : high-temperature compensation coefficient. Factory trimmed
• Sens_TC_LT : low-temperature compensation coefficient. Factory trimmed
• Offsets (x, y, z) : "offsets" for x, y, and z

TCMP_EN is self-explanatory, and TREF and the two coefficients are programmed into nvram at the factory (more about this later...), leaving just the offsets to figure out. The datasheet is not exactly lucid about the offset parameters:

OFFSET_i[15:0] : Constant offset correction, independent for i = X, Y, Z

Probably realizing this, Melexis was kind enough to write a simplified "getting started" document explaining how to use this part. Here's the section concerning the offset parameters:

OFFSET_X, OFFSET_Y & OFFSET_Z
These parameters are used to compensate the offset in case the temperature compensation is enabled. They are not used with TCMP disabled. Please refer to the application note on the temperature compensation for more info. These values can be blindly programmed to the values given in this document (if not already programmed).

The values come programmed to zero in the nvram, and no values are actually given...

• ### 3-Axis Coil Design and Interesting Tangents

Ted Yapo07/07/2016 at 00:12 4 comments

I got temporarily obsessed with designing a 3-axis field coil to calibrate the MLX90393 sensor. A 3-axis coil would allow all three axes to be calibrated with the sensor in a single position. This allows for easy detection and compensation of angular errors: not aligning the sensor exactly with the coil axes. In addition, a 3-axis coil would make it easy to register the magnetic coordinate system of the sensor into the spatial coordinate system of the printer - this is sure to be slightly different each time you mount/detach the sensor head.

I started playing with 3-axis Helmholtz designs, but for multi-turn windings, the required spacing makes for a clunky design. Here's one of the mock-ups I was playing with:

The size of the windings also allows only a very small active volume, and the nested configuration complicates the mechanical design (which I didn't complete). I started to wonder how important the spacing was in the Helmholtz design. If the spacing constraints could be relaxed, I could use something like this:

Here, the windings are farther apart than in the Helmholtz design. This allows the windings to be on the cube faces, which are all the same shape, and all the parts can be conveniently printed "flat" on the printer bed. I printed a few of these, and they're fun to snap together (the spool caps have to be glued). Mechanically, this is a win, but I had no idea what this does to the field, so some simulations were in order.

Unfortunately, the math I'd done so far could only calculate the field along the coil axis; the field in the full volume of the coil was unknown. I downloaded some finite-element software ( Elmer, a general-purpose package, and MaxFEM, aimed solely at magnetics) and played around a bit. These are powerful tools with steep learning curves, and while I'm going to keep at it and learn to use them eventually, using them for my immediate needs feels like slicing bread with a chainsaw. So, I decided to write the "bread knife" of field coil design.

I lucked out and found the paper Simple Analytic Expressions for the Magnetic Field of a Circular Current Loop on the NASA Technical Reports server. This paper provides equations for the full vector field surrounding a loop of current, and the equations are fairly simple, in part because the required elliptic integrals are conveniently hidden. To my great joy, I found that the python scipy package contains routines for numerical evaluation of these integrals, greatly simplifying field calculation. Since the field obeys superposition, these equations can be used to calculate the field surrounding any 3D configuration of circular current loops - which covers just about any coil I might think of using. I was able to create the core of a python simulation fairly quickly; it's less than 100 lines of code. Having the simulation as a library is very convenient - you can program all sorts of analyses and what-if's easily.

Here's the model for the "filamentary" current loops simulated:

The loop is assumed to be a conductor of infinitesimal diameter, centered in 3-space at position p, of radius a, with normal n, and carrying a magnetizing current NI. For normal "magnet wire" in relatively large loops, this model will work very well.

The "loopfield" code is here on GitHub, as well as on PiPY ('pip install loopfield' gets you a copy, but check out the examples on GitHub). It requires matplotlib for the plotting functions, but the core engine just uses numpy and scipy. Usage is very easy - here's code to calculate the vector field for a single-turn coil:

#!/usr/bin/env python3
import loopfield as lf
# create empty field with specified units
field = lf.Field(length_units = lf.cm,
current_units = lf.A,
field_units = lf.uT)
# single-turn 10 cm x-oriented coil at origin
position = [0., 0., 0.]
normal = [1., 0., 0.]
current = 1.
c = lf.Loop(position, normal, radius, current)
# evaluate vector field at origin
B = field.evaluate([0.,...

• ### Hand-soldering QFN Packages

Ted Yapo07/01/2016 at 16:35 0 comments

You occasionally see some questions about whether it's possible to hand-solder SMT parts in QFN packages. This usually refers to mounting them on a PCB. In my case, I didn't feel like waiting for PCBs to come back to start testing the MLX90393 on a smaller scanning head, so I soldered wires directly to the part.

I held the 3x3mm part down with a piece of upside-down Kapton tape, then used masking tape to hold lengths of 30 gauge kynar-insulated wire-wrap wire on the pads. The wire is almost a perfect fit for the 0.5mm pitch. A pair of tweezers under the 10x (and occasionally 30x) inspection microscope allowed for fine positioning of the wires:

To solder the wires, I first coated them in a blob of solder paste using a 25-gauge needle on a 1cc syringe, which allows for much finer application than the larger syringes:

You can see the individual particles of solder in the paste. I then held the (very large) soldering iron tip near the paste until it melted. A gentle tug on each wire with tweezers ensured that it was really connected.

This is the second part I've done this way. The first assembly was broken twice, the second time proving fatal. The first mishap occurred while stripping the loose ends of the wires after soldering. The stripper produced too much "pull" on the wire, and tore it off the part. For the second version, I stripped both ends of the wires first, printed a small cup from PLA, and potted the part and wires in epoxy:

Here's the completed probe after a second glop of epoxy along side the over-sized evaluation board:

Much better. And, it works! It's delivering field measurements to my python code as I write this. I'll be more careful with this one. The first attempt worked for a few minutes until I tried to re-align the axes and pulled a wire out of the meager epoxy on that version.

Making this was a little bit of a pain, but it gives me three things immediately - another sample of the MLX90393 to test, a part not mounted on an ENIG-finish board, and obviously a much smaller probe. It's clearly no substitute for a PCB, but it will allow me to do something now.

• ### Yet Another Calibration Log

Ted Yapo06/30/2016 at 19:27 2 comments

I've been in contact with Melexis regarding calibration and temperature compensation of the MLX90393. They're evidently rationing their application engineers and suggested I contact DigiKey, where I purchased the eval board. DigiKey immediately put me in touch with one of their engineers, who was very eager to help, but set my expectations that he may not have much more luck with Melexis than I had. We shall see. This calibration issue is keeping me up nights, so I'm charging ahead anyway.

# Helmholtz Coil

While the Maxwell coil I wound previously is nifty, its better-known cousin, the Helmholtz coil, is much better documented, and using it eliminates one more variable from the experiment.

@jetty has the excellent #Highly Configurable 3D Printed Helmholtz Coil project, which is a very thorough design in OpenSCAD, but is more geared to larger designs with weaker fields, so I decided to create my own. I'll admit to a little "not invented here" syndrome, but the two applications really are different enough to warrant re-inventing the wheel (coil). Just as an example - @jetty's design as built requires about 600mA of current to produce an Earth-strength field over a large volume, while mine requires about 9mA to do the same in a smaller space. Obtaining the 2 mT fields I'm struggling to get by with would require over 60A of current in the larger design. On the other hand, [jetty's] design is perfect for high-accuracy Earth-strength fields.

Here's a picture of the two coils I made with my design. They're supposed to have 100 turns of 24 gauge wire on each winding.

I ended up winding two copies because I got interrupted while wrapping both windings of the first version. I wasn't completely sure if there were exactly 100 turns of wire on either one, so I tested them. My HP3478A meter read 2.173 and 2.223 ohms for the coil resistances, which is troubling. On the other hand, using resistance to evaluate number of turns is problematic - even using 4-wire resistance measurement - since the lead length on the windings is on the order of the length of a turn. I finally measured the inductance of the windings, which is proportional to the square of the number of turns, and relatively insensitive to lead length, so provides a much better measure. Sure enough, the coils read out at 1.524 mH and 1.622 mH, pretty conclusive that the windings are different.

For the second version, I used a python program to count the turns as I very carefully wound them. These windings measured 2.147 and 2.138 ohms and 1.539 and 1.533mH, respectively. I am confident that this coil has exactly 100 turns on each winding.

## Analysis

There is a potential problem with this design. The analysis most commonly seen for the Helmholtz coil assumes single conductors in each winding - which is a good approximation for coils like @jetty's, with "small" windings. My design has sizeable windings, however - how much does that complicate matters? I decided to model the "large" windings to find out. I model the "large" windings with m layers of n turns each in a rectangular geometry as shown in the diagram:

I used wxMaxima again to derive formulas for the field. Starting with the equation for the on-axis field for a single turn:

I first re-derived the formula for the single-turn model:

/* axial field component for a single turn coil of radius R
carrying current I at distance z */
B_z : \mu[0] * I * R^2 / (2 * (R^2 + z ^2)^(3/2));
/* check that this method produces known formula for single-turn version */
ev(2 * B_z, z = R/2);


Which yields the well-known result:

To evaluate this approximation for the larger-windings, I measured the as-built dimensions and used mean values for the radius and distance:

/* parameters of Helmholtz windings, measured as-built */
z_min : 34e-3/2   /* inner edge of winding */;
z_max : 47e-3/2   /* outer edge of winding */;
R_min : 75e-3/2 /* inner radius of winding */;
R_max : 88e-3/2 /* outer radius of winding */;
n : 10          /* turns per layer */;
m : 10          /* layers...

Ted Yapo06/29/2016 at 12:22 2 comments

First a quick note: I've re-thought my earlier log about ENIG finish. Instead of spreading fear, uncertainty, and doubt about this noble metal finish, I've decided to take a more scientific approach. I'll have my boards fabbed in HASL and ENIG, and see if I can detect any differences in performance.

# You Broke My Printer

I really don't want to hear this - ideally because it didn't happen :-) I really don't want to break my printer(s), either. I've developed three lines of defense against damaging expensive printers by using them as scanning magnetometers: kill switches, sacrificial scanning heads, and a safety-conscious scanning protocol enforced in software.

# Robot Kill Switches

I'm a firm believer in hardware kill switches. Right at the power source. No matter what coders would have you believe, no software-based kill switch is reliable enough to adequately protect life and property. This is especially true with machines built around current 3D printer controllers, whose firmware buffers up commands to accelerate printing. Sending a "stop" command just doesn't cut it when your printer is breaking itself. I've tried.

Here's a picture of the switches I use for 3D printers and other devices in the shop:

The first two are simple off-the shelf devices - a power strip and a wired remote switch. The latter is convenient because it lets you keep the switch easily reachable, but the only one I could find is 2-wire, meaning you have to lift the ground connection to use it, which is not ideal. Unable to find a suitable wired switch commercially, I built the third model from an extension cord (cut in half), a heavy-duty outdoor enclosure, and a paddle switch. The large paddle is convenient because you can hit it with your hand or foot or whatever isn't being pulled into the machine at the moment.

If you end up using the scanner being designed here, I highly recommend using a hardware kill switch of some sort. Just in case.

The idea for this project is to avoid any permanent modifications to your printer. While I'm also looking into making a dedicated scanning platform based on printer designs, for now, the focus is on adapting existing printers. In order to protect the printer during scanning, I envisioned a scanning head design combining a spring and shear-pin that would yield if struck gently, but break long before the printer if struck hard. Here are some steps along the evolution of the scanning head design:

Wanting to avoid ferrous metals in the head design, I started with springs wound of phosphor-bronze wire - the idea was to connect two lengths of wooden dowel with the springs. I soon remembered that using a 3D printer as a scanning magnetometer pre-supposes that the user has a 3D printer (duh!), so a printed design would be ideal. My first experiments with the triangular "3D" springs shown were both interesting and frustrating. Making the springs triangular in cross-section makes them easily printed without support material, but unfortunately, the "weak direction" of the print always ends up along two of the sides, making them too fragile to be useful in this design. I'll post the OpenSCAD file for them anyway, in case somebody can find a way to improve the idea. I finally settled on a flat spring design like the last two - this design keeps the spring in the "strong" printing direction, has a low profile, and prints quickly (good for a sacrificial part). The spring constant and breaking point are both easily changed (but not directly calibrated) by manipulating the shape. My daughter called the tapered version a "tornado spring" - this is the design I ended up using.

My ultimate goal is to come up with a universal mount for attaching the scanning head to any 3D printer. For now, I've settled on simply mounting it on my first test printer - a Solidoodle 3. Here's the design I'm currently testing:

The Solidoodle head has a laser-cut piece of plywood that makes a convenient attachment point; this mount is press-fit onto that...

Share

## Discussions

Anne wrote 07/12/2016 at 12:20 point

Nice idea! Some of the most interesting problems are about magnetic fields inside objects, for example, the magnetic field inside a permanent-magnet array designed to produce a spatially-constant field. Obviously getting the probe physically inside is going to be impossible for many geometries, but if you can mount a small three-axis sensor on the end of a long thin probe, you might be able to get at this. Attaching the base to force-sensitive resistors might give you a cheap way to detect when the sensor bumps into something. As for a platform, can I recommend delta-based 3D printers? In mine, the steppers are in a fixed relationship to the object and the bed, so calibrating them out should be doable. Once you take the hot end off, mine also has no ferromagnetic components anywhere very near the sensor (though some deltas are starting to use ball magnets for joints). Finally, you might look into interpolation techniques designed for magnetic fields - for example if you can interpolate the magnetic potential you'll never get monopoles. But what happens after you get measurements is a different kind of project - there are tools out there for magnetic field visualization (line integral convolution, for example) that it doesn't make sense to rewrite. What there isn't is a good way to get those measurements!

Are you sure? yes | no

Ted Yapo wrote 07/13/2016 at 22:59 point

Thanks, Anne, for the ideas and encouragement!  @peter jansen has designed a long probe board for his project:

I envision a similar arrangement, possibly using a printed probe with a smaller PCB on the end.  I've thought about strain sensors on the probe, and it's a good idea.  For now, I'm concentrating on mounting the probe on a stiff spring, and simply preventing it from breaking anything in case of collision.

Yes on the delta-bots!  I discussed it briefly in one of the logs somewhere - can't find it now - but I think a Bowden-fed delta would be the ideal candidate.  Unfortunately, I spent my money on Cartesian printers (when I was thinking of printing with them!), so will have to wait until a delta kit fits into the budget.  On the other hand, one of the things I'd like to get out of this project is how accurate you can make scans in more difficult printers - which people may already have.

I knew from early on that trilinear interpolation doesn't generally produce a divergence-free field; you could indeed "discover" monopoles as it stands with my software!  I haven't looked too hard at alternatives yet - do you have a reference that might shed some light on the issue?

Finally, I hadn't seen line integral convolution before.  Thanks for the tip! I found a copy of Cabral and Leedom's SIGGRAPH paper, and will look into it a bit.  Interesting for 2D, but resource intensive.  It's from 1993, so they couldn't just throw it on the GPU like we can today - there may be something interesting in doing so.

Graphics was/is one of my fields, so I can't help re-inventing the software wheel :-) I was thinking of a particle system to trace animated field lines...

Of course, you could simply export data collected with the scanner to your favorite visualization software.

Are you sure? yes | no

PointyOintment wrote 09/12/2016 at 06:54 point

A word of warning: Don't get the cheapest delta kit you can find on AliExpress like two guys I know did. Those will cause endless headaches until you replace 60% of the printer with quality parts and probably spend more than you would have on a good kit or custom design.

Are you sure? yes | no

Ted Yapo wrote 09/12/2016 at 14:34 point

@PointyOintment, I have my eye on a Folger Tech Kossel kit:

https://folgertech.com/products/folger-tech-kossel-2020-full-3d-printer-kit

I bought one of their 2020 Prusa i3 kits a while back, and I found it to be a good deal.

Are you sure? yes | no

Andrew Ferguson wrote 06/18/2016 at 07:09 point

Nice work. I'd be interested to see if you can map a really simple system - a single current carrying wire, with a reasonable current in it, say 1A. Your tool would be great in a physics teaching lab for undergraduates. Andrew

Are you sure? yes | no

Ted Yapo wrote 06/20/2016 at 00:07 point

I'll put it on the list to do soon.  Only a physicist would suggest a such a simple experiment sure to highlight the limitations of the technique ;-)  A very good idea. I was ready to jump straight to the Halbach arrays...

Are you sure? yes | no

# Does this project spark your interest?

Become a member to follow this project and never miss any updates