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!