A Third, High-Speed Magnetic Imager Tile

A project log for Iteration 8

Science in your hand. A pocket-sized instrument capable of visualizing and exploring the world around you. (Iteration 8)

peter jansenpeter jansen 02/12/2018 at 20:2211 Comments

A quick update with a new high-speed version of the magnetic imaging tile!

I've been very interested in visualizing things that are very difficult for us to normally see for a long while -- it absolutely fascinates me that there's so much around us that we just can't easily perceive, and I often wonder how much more we'd be able to understand about our worlds, and how much more interesting bits of science we'd be able to get done, if only we could easily see them as naturally as we see things like colour. 

One of the most memorable examples of this, for me, is a little more than a decade ago when I'd literally just assembled my open source science tricorder mark 1, turned it on for the first time, and started wandering around the room to see what interesting things it might detect.  A moment later I'd stumbled upon a power adapter plugged into the wall with a transformer, and the oscillating field inside being detected by the magnetometer.  That magnetometer and visualization was updating at only a few cycles per second, much slower than the 60Hz oscillations inside the transformer, but it was enough for me to watch that aliased oscillating magnetic field vector make large swings back and forth, and make me wonder what it would look like if only we could see it hundreds of times faster, and with an image instead of just a single vector.  Magnetic field visualization also seemed much like low-lying fruit -- we've been very good at producing very low cost, accurate magnetic field sensors for a long time, so this seemed possible in the near term. 

I can't say things happened as quickly as I'd hoped, or even that I was able to form an idea for what a magnetic imager might look like that evening.  But years later I ended up becoming fascinated with magnetic resonance imaging (MRI), and tried to dream up an idea of what an inexpensive desktop MRI might look like.  One of the difficulties with MRI is that it requires very homogeneous magnetic fields to be placed over a sample, in order to spatially resolve different parts of the sample (and render an image).  The normal way this is done is with a large, beautifully homogeneous, incredibly expensive superconducting magnet, but I had wanted to figure out a way to do it with a terrible, not super homogeneous, cheap electromagnet by reading all the field variations, and calibrating them out -- and I had decided to try to do this by creating a first magnetic imaging tile built out of a lot of 3-axis magnetometers in a 10mm grid.  That low-field MRI project stalled a bit (it turns out being a tenure-track professor takes a lot of your time), and along the way I was able to create a two much simpler (but incredibly slow, incredibly low resolution) desktop computed tomography (CT) scanners, but the idea of creating a magnetic imager for it's own sake (apart from the idea of building a low-field MRI) seemed very clear.  I put together an array of Hall Effect sensors that (unfortunately) lose the 3-axis vectors of many magnetometers, but have very fast updates, and built the Magnetic Imaging Tile V2.  That tile was very cool -- for the first time I had an imager with a reasonable spatial resolution (~4mm) and a large number of pixels (12x12, though I had only ever populated a smaller ~8x8 subsection).  But unfortunately my design choice of using an I2C I/O multiplexer for addressing each "pixel" (magnetometer) in the tile meant that it was limited to a framerate of about 10-30Hz.  This meant I could see very neat static fields live, but placing a transformer near the tile only showed it rapidly oscillating and unable to render a good image, because the tile was about a hundred times slower than it needed to be to sample such a fast field. 

The schematic for the new V3 tile is shown above (click here for a PDF).  

One of the critical issues I had was how to resolve was how to make the tile addressing much faster, by replacing the I2C I/O multiplexer with something else, while keeping the external pin-count for whatever microcontroller would be interfacing with the tile still low.  After a bit of brainstorming (and by this, I mean mostly doing other things for a long time until the answer suddenly came to me one day), it occurred to me that since we essentially need to move through each pixel only once per frame, and that the CD74HC4067M analog multiplexers have 4-bit binary addressing (with an active-low enable line each), the I2C I/O multiplexer could be replaced with a 6-bit binary counter, with the lower 4-bits for addressing a specific channel on each multiplexer, and the next 2-bits used for selecting which multiplexer was enabled (through a 2-to-4 decoder).  Some 1970s-era 7400 series logic later (a 74HC590A 8-bit counter, and a 74LVC1G139 decoder), I had an addressing mechanism put together that still uses only 2 lines (a clock, and a reset back to 0 -- the first pixel), but can likely be clocked at some ridiculous speed -- in the megahertz, and far faster than any ADC that I have readily available (or, possibly, the response time of the magnetic field sensors themselves). 

A quick note about the addressing, which is interesting.  Though each analog MUX has 16-channels, for routing considerations it's not easily possible to build a system that iteratively addresses the pixels in straight lines, one after another.  Instead, each analog MUX is responsible for a 4x4 array of magnetometer pixels, and still not in any easily recognizable pattern -- just a regular pattern that was (painstakingly) found to fit and be tile-able with a 2-layer board.  It's a little challenging to route this, and while it looks complicated, a little bit of software in the form of a look-up table ensures that it's still possible to read each pixel's data and place it in the right spot in a framebuffer at a very high speed. 

I also decided to go back to Eagle to do this, since they'd just advertised adding a push-and-shove router, and I wanted to test it out.  I've been using Eagle for more than a decade, but had switched to KiCad for the push-and-shove router, and when Eagle switched to a subscription based license model (In spite of having purchased two previous versions of Eagle, I will never purchase subscription-based software).  Still the free version brought me back, and it only took me 4 hours to route, versus two weeks of evenings and weekends with the KiCad router, which is mostly due to a combination of my being very new to it, and the usability issues that the KiCad folks are progressively ironing out with each iteration. 

The tile itself is intended for Iteration 8 -- a sensor package that I'd like to place on the back of a phone, since it's way more powerful at visualization than any stand-alone system that I would be able to realistically design from scratch (in spite of how enjoyable it is to design such devices, like the Arducorder Mini).  I've been tinkering away on this, very slowly, for about a year -- and the V2 tile, in addition to being unable to reach high framerates, is also a little too large to easily fit on the back of a phone while allowing room for other sensors to fit as well.  So I decided to reduce the size from 12x12 to 8x8, since this made the tile physically much smaller (53 x 35 mm), and also much cheaper/easier to make. 

The tile design itself only has 6 separate parts (1x binary counter, 1x decoder, 1x ADC, 4x Analog MUX, 10x 4.7uF 0603 capacitors, and 64x magnetometers).  I actually used the internal ADC on the Chipkit MAX32 to achieve an even faster framerate (~2000 frames per second) than the onboard 14-bit 100KSps AD7940, but I include it so that the tile could be used with a host that doesn't have an ADC (like a Raspberry Pi).  The ADC is actually very expensive (about $10 in quantity), so replacing this with a faster, less expensive 12-bit ADC might be a solid idea for a second revision.  

While the fastest I've been able to achieve is 2000 Hz on the Chipkit MAX32, it's entirely possible that much higher framerates would be possible.  I think the limiting factor is currently the ~20KHz bandwidth of the DRV5053VA magnetometers, meaning that 20KHz framerates might be possible with an ADC that has a greater than ~1.5MSPS sampling time.  I'm not sure what fields one is likely to encounter will move this quickly, and a quick Google seems to show most magnetic imagers today having updates ranging from 1-1000Hz -- but it would still be very interesting to see.  Even though the DRV5053VA is the most sensitive analog magnetometer I was able to find at this price point, my intuition is that most fields one is likely to encounter that are oscillating that fast may also be very low intensity, so having a higher sensitivity might be required.  I would still love to do this with an array of very sensitive 3-axis magnetometers, if I was able to get the density and speed up, while keeping the cost low (which I haven't been able to find yet).  But having 3-axis vector information for each pixel would allow for some incredible visualizations, similar to Ted Yapo's very cool manually translated single-magnetometer scanner and the great visualizations he's put together. 

Here's a picture of the tile assembled.  It took only about an hour to hand-place the parts with a tweezer after using an inexpensive stencil from OSH Stencils.  I really enjoy the aesthetics of the tile -- seeing a large array of the sensors on the board.  Theoretically the same method could be used for sensors of a variety of different modalities if they're available in the same package footprint. 

And the bottom of the board, with the analog multiplexers, and the connector. I had intended on using a locking pattern for the 0.1" header (since I'm still not sure what connector it will have to interface with whatever form Iteration 8 takes), but the locking pattern looked to be not quite offset enough (or the header I used was a little small), so I added a few dabs of solder.  If another revision is made, this would also be a positive (and very small) change to make. 

The source files for this version 3.0 of the magnetic imaging tile is currently available on the Gitub repository

Thanks for reading!


Rong-Hao Liang wrote 4 days ago point

Hi Peter, Great work. Thanks for sharing. 

I have been working on a similar project for years. Maybe you will feel interested in it.

Project Gauss:




Feel free to get in touch :-)

  Are you sure? yes | no

nqtronix wrote 6 days ago point

I would still love to do this with an array of very sensitive 3-axis magnetometers, too.

For a recent project at my university we've been using a single BMM150, which seems to be a reasonable candidate:

• resolution: 0.3µT

• range: ±1300µT (x,y), ±2500µT (z)

• ODR: up to ≈600Hz (they are still the fastest 3D magnetometers I could find) (*see Edit)

• noise: about 2-5µT at maximum ODR

• affordable (0.74€ @100pcs)

• tiny BGA-12 package (1.56x1.56mm), can be routed with 0.1mm traces

• SPI access up to 10MHz

• software syncronised sampling possible, so "interleaved-mode" for 4x speed at 1/4 the resolution (pixel) should be possible, too


If it was only about hardware & low-level firmware I might have given it a shot (I like that sort of thing) but

a) maintaining the high throughput with USB 1.1 (atmega32U4 w/ LUFA) seems tricky and

b) actually using the data on the PC side seems even more complicated.

I never got around to try it as usual one has more ideas than time ;)

But, to be fair, even without the 3-axis this project is freakin' impressive. I already liked the v2 version, but the higher sample frequency was definitely worth all the additional effort! Thanks for the detaild documentation :)

*Edit: I miss-calculated the ODR and forgot to include the SPI write time, I estimate a more realistic value to be around 450Hz

  Are you sure? yes | no

peter jansen wrote an hour ago point

I have been trying to figure out how to do this with 3-axis magnetometers for a few years too, and for each part there always seems to be one value that's non-ideal.  My first attempt was with an 8x8 array of HMC5883L magnetometers, which had a very low framerate (from the I2C multiplexing), and also a very low resolution (10mm x 10mm grid, since so many traces were required, and 3 external capacitors per magnetometer).  

SPI is definitely the way to go, though it does mean routing (here) 64 separate CS lines.  

After the V2 tile I had hypothesized something like 600HZ would be enough for interesting renders (about 10x the 60HZ you'd observe in a transformer -- so it should be enough to render it), but after the experiments with the V3 tile, it really looks like 1000Hz is a good minimum to observe and render the fields (and I'm not aware of any SPI magnetometers that can reach this rate just yet -- but I'd be happy to find one). 

Throughput is an issue, but you can always connect it up directly to something like a Pi to not have to worry.  I connected this one up to a Chipkit MAX32 to have enough for ~100-250 sample frames, then just slowly stream them down the serial port -- it only takes a few seconds, and you can stream them at essentially video speeds to watch them come in in slow motion!

  Are you sure? yes | no

DR wrote 7 days ago point

Quick search found the ADS7883SBDBVT, 12 bit, 3MSps, and available for $6, about half the cost of your current ADC.  Unless I'm missing something and it isn't useful, that should be plenty to max out the magnetometers.

  Are you sure? yes | no

peter jansen wrote an hour ago point

Thanks!  It turns out that Analog has a bunch in the same footprint as the 14-bit ADC that's currently on board, and so you can choose between a 12-bit 1MSPS to 16-bit 100KSPS in the same package without (I think) board revisions! But there's also an analog out pin on the tile, to attach an external ADC that meets specific requirements. 

  Are you sure? yes | no

Jacob Christ wrote 02/17/2018 at 20:31 point

Are you aware of the non-blocking ADC code added to chipKIT-core.  I documented some of it here:

and here

Its smoking fast on a MZ chip, if you have a WiFire board use the PONTECH NoFire with the WiFire Board to use this code.  The WiFire doesn't have it because I didn't want to touch the code Digilent created to support the many versions of the WiFire.


  Are you sure? yes | no

George Harkin wrote 02/15/2018 at 19:23 point

Great project. The multiplexing is wonderful.

  Are you sure? yes | no

peter jansen wrote 02/15/2018 at 19:30 point

Thanks!  Sometimes brute force massive parallelism is the way to make things happen, even in the physical world :)

  Are you sure? yes | no

vcazan wrote 02/15/2018 at 16:19 point

Great work on this! Just a quick question, does it detect any non metallic objects?

  Are you sure? yes | no

peter jansen wrote 02/15/2018 at 19:28 point

Thanks -- it senses magnetic fields, which are mostly emitted by magnetic metals or electromagnetic objects.  I have heard of exotic materials (like engineered plastics) being able to be magnetic. 

  Are you sure? yes | no

oshpark wrote 02/14/2018 at 09:11 point

We are very excited to see this new version in action.  It's fantastic!

  Are you sure? yes | no