05/23/2015 at 21:05 •
I've been thinking about tomographic imaging a lot lately in between nursing sore fingers from learning how to hand-wind electromagnetic coils for my attempt at a small prepolarized coded-field MRI, and I thought I'd take a moment to share some progress.
The open source computed tomography (CT) scanner that I put together last year was a lot of fun to design, having many atypical design problems in it, from the mechanical design of the rotary gantry to pairing an appropriate radioisotope source with a modified extra-sensitive radiation sensor. Something about it being essentially a radioactive desktop Stargate that lets you see inside of things also seems to get people very excited, and so I've received an eclectic bunch of e-mails asking about the scanner from folks as diverse as radiology professors and biomedical folks to makers to those hoping I'd open up Dr. Jansen's back-alley CT scans to have a look at some strange bump they have (please go see your doctor!). But I feel that for all the excitement, to quote Feynman, the current open CT design feels a bit like a dog that walks on two legs — it's not that it does it well, it's that it does it at all. It's essentially a working model of the first generation of CT scanners, and so it takes a very long time to get even a single slice of an image. I've been wondering what it would take to move it from a proof of concept into something that does the job well, or at least substantially better.
The previous design makes use of a 10uCi Barium-133 radioisotope check source, which is the strongest radioisotope source that's available without a licence. Barium-133 has strong x-ray peaks around 31kEv and 81kEv, which are low enough energy that organic water-containing materials (like apples and bell peppers) are reasonably contrastive for imaging. The silicon PIN photodiode detector in the Radiation Watch Type 5 high energy particle detector that I used is also most efficient at low (~10kEv) energies, meaning that we would need less exposure time to generate an image with sufficient signal to make things out, although there are technical challenges in detecting these lower energy photons. Imaging under these circumstances is essentially a constant battle for detecting signal over the noise, and one way to generally increase SNR is to increase the measurement time — although of course this increases how long it takes to create an image. In the extreme case when you're so signal starved, it ends up taking all night just to capture a single slice of a bell pepper.
Another alternative that's been suggested is to increase the intensity of the x-ray source. For a variety of safety reasons this isn't something that I'm willing to explore. I've heard of folks experimenting with surplus x-ray tubes and equipment, and I believe that your health is just too precious to risk for such endeavors. Pragmatically, as an open source project, using readily available radioisotope check sources is also much more repeatable than found radiography parts.
And so we're left with a few alternatives:
- Decrease the scanning volume: The current design has a source-detector distance of about 12cm. Following the inverse square law, each halving of this distance should increase the number of counts at the detector by a factor of 4.
- Detect in parallel: Starting with second-generation CT scanners, parallel arrays of detectors were used to dramatically decrease scan time. This should give linear speed gains — e.g. N detectors should reduce the scan time by a factor of N.
- Increase sensitivity: Detecting the signal from single photons requires a genuinely incredible amount of amplification, and this process is noisy. While previously recalibrating the Type 5 detection threshold to just above the noise floor yielded many more counts, it appears as though much of the signal is still buried below the noise floor of the detector.
It's likely that a solution will end up with some combination of each of these alternatives.
Where the first generation of medical CT scanners contained only a single photodetector, I've read that each generation of CT scanner after has increased the number of detectors by about an order of magnitude over the generation before it — moving from ~30 detectors in a second generation system, to ~300 in third-generation fan-beam systems, to ~2000 in modern static ring systems. Each of these improvements allowed scan times to reduce accordingly, starting from about half an hour with first generation systems, to about a minute, to now only a few seconds.
Above we can see how the current system might be parallelized with more Type 5 detectors, each arranged across an arc such that there is a constant distance between the source and each detector. The Type 5 is one of my favorite sensors of recent years, and I've had a lot of milage out of it, but unfortunately because it's about an inch across, it would be difficult to parallelize the desktop CT with more than about 6 detectors using this design. Additionally, the fantastic First Sensor X100-7 that the Type 5 uses has a 10mm x 10mm active area, which makes it great for collecting and detecting high energy particles, but a little large for the kind of spatial imaging that we're doing, so the images will be a little blurred. Having a smaller detection area will increase our spatial resolution, and decrease the detector size — so that (ideally) we'll be able to pack many more detectors in (as shown below), and decrease the scan time.
Designing an inexpensive parallel detector
High-energy particle detectors are extremely challenging to design and build, in large part because you're amplifying the signals from a single subatomic particle by many orders of magnitude in order to be barely detectable by a microcontroller. Because of this they're extremely sensitive to noise, layout, component selection, and generally must also be shielded from external interference. Given the design challenge I've been reading whatever I can find on the topic over the last few months, and meditating on layout guidelines to reach the zen-master level of low-noise layout required for such a task, or at least to get a prototype to a point that I can work from.
The design that I arrived at (schematic) is heavily based on the Maxim Appnote 2236: Gamma-Photon Radiation Detector, which uses a reverse-biased silicon PIN photodiode as the detector connected to an extremely sensitive first-stage amplifier, followed by a series of cascade amplifiers to increase the signal intensity. The photodiode is the popular BPW34, which has been used in a number of other radiation sensor projects. The active area of the BPW34 is only 7.5mm^2 (a little less than 3mm x 3mm), which is a little over 10 times smaller than the 100mm^2 of the X100-7, so this should increase the spatial resolution a good deal.
While many of the hobbyist designs for radiation sensors operate at effective noise thresholds of around 100keV or more, because here we have such a specialized application where most of the business photons are 31keV or 81keV, keeping the noise floor as low as possible to be able to detect these photons is critical. A number of academic project writeups for radiation detectors I've found suggested that the Texas Instruments LMP7721 would be an ideal choice for helping keep the first-stage amplifier as low-noise as possible, both because of its incredibly low noise characteristics (measured in femtoamps), and an uncommon footprint that includes guard pins to further reduce layout noise.
To make the boards modular and digitally addressable, I've added on a PIC24FV32KA301 microcontroller, which sports a 12-bit analog-to-digital converter (~1.2mV resolution @ 5V), and plenty of RAM to store a histogram of pulse widths to experiment with doing very crude spectroscopy as I've done with the Radiation Watch Type 5. Both the raw analog output of the photodiode amplifier as well as the digital output of a comparator serve as input to the PIC, and a digipot allows one to dynamically calibrate the comparator output based on the noise level at runtime. I've also included a small LED for debugging.
The PIC currently exposes an I2C interface (SDA/SCL) for external communication, though in retrospect while this makes communication easy, it would also require programming each detector with a unique I2C address — so future revisions might move to an SPI interface.
In terms of assembly, the memory of spending 4 days to assemble a set of fine-pitched Arducorder boards is very fresh with me, and so I've designed these to be very easily put together — a single-sided design with 0603 parts or larger on all the passives, and SOIC pitches on each of the ICs with the exception of the SOT-8 footprint for the digipot. So it's comparatively easy to build a bunch of these and pop them in the reflow oven, and with a low-quantity BOM of $20-$30 (about half of which is from the TI LMP7721), they're relatively inexpensive.
A series of guard vias on the ground plane divide the analog and digital sections. I've found that shielding the analog section and grounding the shield (like the Type 5) is absolutely essential for operation, much as the appnotes prescribe. I'm not sure what folks tend to use for the shielding tape, but I found that a wrap of electrical tape (to shield the photodiode from light and provide a non-conductive base) followed by a wrap of standard aluminum duct tape from the hardware store seems to work well as a first pass.
As an aside, for the low-field MRI project I've been looking for a USB oscilloscope or DAQ that would allow recording at at least 100KSps (ideally 1MSPS) at 12+bits of resolution for several seconds. This is a little unusual — usually scopes that are fast have very short sample memories. I'd seen an article about building a sound card oscilloscope in Make that would easily allow for such long recordings, as well as folks selling oscilloscope probes modified for sound card use, so I thought I'd give this a try before using a benchtop oscilloscope.
Above is a recording from the sound card oscilloscope with the Ba133 radioisotope source near the detector — and the detections were clearly above the noise floor. Wonderful news! The units on the axes aren't entirely clear here, and with such a slow sample rate we're right on the edge of being able to detect this signal, so on to a benchtop scope to better characterize things.
Here I've taped the 10uCi Ba-133 radioisotope source to the side of a 2 inch diameter acrylic cylinder. In this configuration I can easily rotate it to see the number of photons detected when the source is directly beside the detector, and compare this to when the source is 2 inches away, and going through a thin (1/16 inch) acrylic sample container.
The noise floor generally appears to be around +/- 40mV, which is very decent for a first try, although it did appear to increase to nearly +/-60mV after being on for a few hours. I was also doing this at Xerocraft beside a metal shop, and the noise would periodically go a little crazy when a large piece of equipment (like the mill) was turned on, so I'm not entirely confident in the noise characterization — but it's a good start.
The firmware for the PIC isn't complete, so I was using the scope to trigger on the raw analog output instead of using the PIC (either with the analog output, or the digital comparator output). With the Ba133 source very near to the detector there were far too many detections to count, and with it 2 inches away going through the acrylic cylinder, I counted approximately 20-30 counts per minute. That's not incredible, but it's also workable, especially if the noise floor can be lowered, and we gain access to more signal.
To help ground this, the bell pepper image shown earlier was captured at about 22×22 pixel resolution, with about 60 seconds of integration time per pixel, for a total of about 9 hours of acquisition. Using a parallel array of about 20 of these BPW34 detectors, the rows of such an image could be captured in parallel, so we'd only have to scan in one dimension. Assuming it takes 5 minutes of integration to capture an image with a similar baseline signal (say 100 counts) to 60 seconds of integration with the Type 5, we could capture a similar (likely sharper) image with about 20 measurement cycles using the parallel detector. At 5 minutes per measurement cycle, this would reduce the acquisition time to about 90 minutes, or a factor of 10 faster than the original device. Were we to significantly improve the noise threshold, this could further decrease the acquisition time, and really start to get low resolution images in under an hour, and complete low resolution tomographic scans (at 10 degree increments, or 36 angles) in under a day. That'd be a substantial improvement over the current system.
Given the requirement for long acquisition times (though much shorter than before), I've been sketching up a simplified mechanical design that could be entirely self-contained without any moving parts exposed, and placed on the edge of ones desk to scan away for the duration. I'd also like it to be much more compact than the original design so that it's unobtrusive, while being attractive and interesting enough that it would be a welcome addition to ones desk. The basic design would be a cylinder approximately 6-8 inches in diameter, and 8-12 inches high, with a 2-3 inch diameter aperture in the top to place in a cylindrical acrylic sample container.
Moving to a parallel detector removes the need to linearly scan both the source and detector, which removes two of the four axes, greatly simplifying the mechanical design. In this prototype, the idea is that a small sample container slides in through the top, and the sample itself (rather than the source and detectors) will rotate, also greatly simplifying the design.
The source and detectors would be mounted on a moving Z-axis (shown above), that translates them up and down to capture different slices of the sample. While here I've included two stepper motors on nylon lead screws for this purpose, in practice this doesn't appear to provide enough support to prevent the Z stage from walking, especially with an unbalanced load — and so this will likely change to three lead screws in the next revision. The drive motors are currently NEMA14 steppers, with a NEMA17 footprint for the sample cylinder support and rotation.
So far a great first set of experiments and sketches, and it'll be interesting to better characterize the detector design, make improvements and revisions, and see how it all ultimately affects acquisition time.
Thanks for reading!
06/02/2015 at 06:12 •
With the parallel radiation detector design the keystone to the whole project, I've been working to characterize the prototype detector performance, and narrow down a solid design.
Taking a step back before jumping into things — in the last post I'd noticed that the detector was reading approximately 20 counts per minute (cpm) from the Barium-133 radioisotope source at a scanning distance of about 6cm. In a way this is fantastic — the detector is working, after all, and with less than a tenth the surface area of the Radiation Watch Type 5. But if we (arbitrarily) set a ceiling of 100 counts per pixel as a baseline in order to reconstruct a good image, we would need to integrate for 5 minutes at 20cpm to reach this. Assuming we're scanning an object 6cm in height (or ~20 BPW34 photodiode-sized 3x3mm pixels tall), it would take about 100 minutes to acquire each image. For the computed tomography component, if were we to take images fairly coarsely at 10° intervals, we would end up requiring 360°/10° or 36 images per complete scan. 36 images * 100 minutes per image is 3600 minutes, which is 60 hours, or 2.5 days. That's light years ahead of the current 9 hours per image, but still a little long — ideally we'd get a complete scan to well under a day.
To help move closer to this, I remembered a trick that my Dad used to use to double the memory in old (sorry, Dad! :) ) computers, where going from 4k to 8k was a huge deal. To do this, he'd order a second set of memory ICs, and physically solder them on top of the existing memory ICs, while lifting one or two pins to hot-wire on a new address line to give access to this larger memory space. I remember this very vividly, not just because we were laughing about it a few weeks ago, but also because when I was at the age where I was taking /everything/ apart that I could get my hands on, he'd given me this sacrificial Tandy Colour Computer that he'd done this to so that I wouldn't accidentally break something more modern, and seeing those stacked chips when I opened up the case was very unusual and memorable.
In terms of radiation detection, the number of detections depends on the area of the detector, and folks often end up using either one large detector or several smaller detectors to get enough surface area for their application. And while more area means more detections, having a larger detector means that we'd sacrifice spatial resolution. But, unlike the visible radiation the BPW34 photodiode was designed to detect, only about 1% of the x-ray and gamma photons are interacting with the detector, and many of the rest are actually sailing right through the detector. Enter Dad's stacking idea — the BPW34 package just happens to be shaped such that it's amenable to stacking multiple photodiodes one atop another, and if we stack multiple detectors, then we increase our chances of detecting these x-ray photons, and should be able to increase the number of detections without sacrificng spatial solution. Sounds great!
The high-energy particle detector nominally includes three high-level components: A photodiode detector, a very sensitive amplifier, and a microcontroller for counting the detections. The microcontroller appeared to be adding some noise to the process, so I've populated a modified version without the microcontroller, and have been using a scope to characterize the detector.
The noise level (measured in counts per minute) is pictured above, for three different detection thresholds that appeared to be right around my eyeballed noise threshold of ~50mV. Here we can see empirically that the noise threshold is infact around 50mV, with a near zero number of counts at 52mV, a very small number of counts at 50mV, and many more counts at 48mV.
Interestingly, the number of photodiodes doesn't appear to affect the noise too much until we reach 4 photodiodes, where the noise level increases quite a bit. Here I've included data from 4 photodiodes at both an 18V bias (ie. two 9V batteries, red), and a 27V bias (purple). So in terms of noise, 3 photodiodes and a ~50mV trigger threshold seems to be a good balance of photodiode surface area vs noise level.
The signal story is very similar, though with a bit of a twist. Above we see the signal level (in counts per minute) with the 10uCi Ba133 radioisotope source about 6cm from the detector — enough for the 2 inch sample container with a bit of a mechanical buffer on either side. Here each line represents the difference between the number of detections minus the noise figures from above, so what we're seeing here is just signal level, without the noise.
Quite wonderfully, we see approximately linear gains when we stack the number of photodiodes, up to 3 photodiodes. Where a single photodiode detects approximately 20cpm (blue), 2 photodiodes detects just under 40cpm (orange), and 3 photodiodes detects about 55cpm (green). The story gets a little more interesting at 4 photodiodes — for 50mV thresholds and higher the detection rate goes up only a small amount to 60cpm, but for a 48mV threshold (well into the noise), the detection rate increases to approximately 80cpm. It's not entirely clear what's happening here, but it looks like 4 photodiodes would be a safe bet — approximately 60cpm at a 50mV threshold, with the possibility for increasing it a good deal lower if we venture into the noise.
How does this affect the scan time? At 60cpm, we would need only 100 seconds to reach a ceiling of 100 counts, about 30 minutes per image, and 20 hours per 36-angle (10° rotation) scan — much faster than before. In the best case if we assume that we're able to get 80cpm and integrate for only 1 minute per measurement, it would take 20 minutes per image, and 12 hours per scan. This seems to be about the limit (currently) of these radioisotope check source methods: (1) We're using a Ba133 source with emissions that are low enough energy to be most efficiently detected while being just slightly above the noise floor, (2) We're using the maximum amount of this material (10uCi) that can be purchased without a license, (3) The diodes in the detector have been stacked until the edge of diminishing returns, and (4) The scanning volume has been reduced to the minimum usable size. Without significant advances in the way we go about detecting these high-energy particles this is likely pretty close to the best that can be done with such a low intensity source, and raising the intensity of the source (say to an x-ray tube) treads into nuclear safety, regulatory, and legal issues that I'm simply not comfortable with. Given that all the limits have been pushed, 12 hours for a complete scan is much better than the original figure of several weeks, and definitely something I can live with!
Oscilloscope Traces (and measurement noise)
I've captured a few example detections using a Rigol DS1054Z oscilloscope. As near as I can tell this scope isn't capable of counting how many times it has been triggered per unit time, so I connected the trigger output to an Arduino Uno to calculate the number of detections (or counts) per minute (cpm) in the above graphs. Interestingly, I'm not sure whether it was the Arduino Uno or the USB port the Uno was connected to, but this seemed to add bursts of about +/-10mV of noise on the signal every 8 to 12 uSec (this can be seen on the two traces, above). The Arduino Uno clock is 16Mhz which would give a clock period of ~6.25uSec, and USB 2.0 is (I believe) 12Mhz which has a period of 8.3uSec, although I'm not sure why the period of the noise jitters. In either case, the actual noise floor of the system is about 10mV lower, as can be seen on the graphs below, without the Arduino connected.
This trace (above) looks typical of a high-energy particle detection, likely from one of the higher emissions of Ba133. Because of their energy (and the high magnitude of the detection peak), these are relatively easy to detect.
The lower emissions (likely around 30-35keV) are much more challenging to detect, and their amplitude is so small that they look very similar to the noise. I believe the trace above represents a noise detection — given the surrounding waveforms one might be tempted to believe that the noise floor is only around +/-20mV, but many of the peaks (on the scale of seconds and minutes) reach to 40mV, making this the effective noise floor.
And so, using this preliminary performance characterization, it looks like we're close to nailing down a final design for the detector, and one with much better performance than I was expecting. To accommodate the extra photodiodes I'll have to modify the PCB to extend out another 5mm, and include a slot and pad that the photodiodes can slide into for (ideally) relatively easy surface-mount soldering. In the worst case, if a few of these diodes do have to be hand soldered, a few seconds of soldering is a very small price for 3-4 times the performance. Still, the memory of spending days and days to solder each set of Arducorder boards is fresh in my memory, and I'm endeavoring to design these modular detectors to be as simple and inexpensive to assemble as possible. Removing the microcontroller and adding in the parallel photodiodes, the parts cost in low quantity is about $25 each, about half of which comes from the extremely low noise TI LMP7721 precision opamp. Given that the detector is currently operating right at the noise threshold, I'm hesitant to substitute this part for a less expensive opamp, but with TI as an official sponsor of the Hackaday Prize and an array of detectors to build, perhaps they'll be able to donate a tube of these parts to the cause of open source science.
With 4 photodiodes, the current detector design extends to about 40mm in length, and (after wrapping with aluminum shielding) about 4.5mm to 5mm in thickness. With a 2 inch acrylic sample container, and a ~3mm buffer on either side of the container, this allows a packing density of exactly 16 detectors over a 75° fan angle from the source.
For compactness and supply, I'd like to keep the design to within 6 inches in diameter — and 6 inch cylinders of various sizes are much more easily found (and much less expensive) than moving up to 8 inches. Home Depot even carries a fairly hefty 6 inch (~5.7 inch ID) drain pipe that's inexpensive, extremely sturdy, and would be perfect for prototyping case designs with. Unfortunately 40mm detectors are a bit too large to fit within this size — it looks like the detector would have to decrease to 30mm or less to squeeze into a 6 inch cylinder.
Another option, shown here, is to throw symmetry to the wind and slightly offset the sample container, giving the whole unit a clear "front" and "back". This is a fairly simple solution, and I'd like to include a front display panel for the device as well — so if several stepper motors and lead screws can effectively fit into this footprint, it might be a very good solution.
Thanks for reading!
06/18/2015 at 03:33 •
An update with a great deal of progress, including the design for the first revision of the imaging array, and a second iteration of the mechanical tomographic scanning framework.
From the last update, the initial characterization of the prototype modular radiation sensor looked very promising -- it's able to detect about 60-80 x-ray photons per minute at a distance of 6cm from the radioisotope source, which should be more than enough to generate an image. While characterizing the prototype detector I identified a number of revisions, and so my recent focus has been on working through everything required to build the complete imaging array.
Radiation Detector Revision 1
The prototype detector generally worked out rather well, and was designed to be amenable to a bit of wire wrap when issues came up (as an aside, I tend to use vias to attach probes and wire wraps, so my vias are often left untented for this purpose). I found a few issues that required a significant revision:
Things that worked well:
- Relatively low-noise: The detector has a very similar noise level (~+/-40mV) to what I've measured with the great Radiation Watch Type 5 (~+/-50-60mV). This is really an accomplishment for me given that I haven't designed many challenging analog systems, and low noise really enables this design.
- Detection level: The detection level was originally about 20 x-ray photons per BPW34S photodiode (@6cm) per minute, which is really very reasonable for a first pass. The Type 5 in the Arducorder Mini detects about 500 photons at this same distance, but it has a factor of 13.3x more detection area (so we'd expect the BPW34S to detect around 38 photons per minute, normalizing for detection area). Given that the beautiful First Sensor X100-7 photodiode used by the Type 5 is specifically designed for radiation detection and has a cost of about $100, while the BPW34S photodiode is a ~$1 part, we're really doing very well.
- Increasing Detection Level: The last post showed that the BPW34S photodiodes can be stacked in parallel, increasing the detection rate to ~60-80cpm, while not decreasing spatial resolution -- so we're doing very well here. A few dollars in inexpensive photodiodes is functionally getting us very similar performance to the fantastic X100-7 photodiode (for this task), and we're (again) really doing very well.
- Digitally adjustable: The comparator threshold can be digitally adjusted using an AD5160 digital potentiometer, and this is really handy to be able to adjust the detector's output to a desired noise level.
- Modest Soldering Skills: The board was designed to require only modest surface mount soldering skills (0603 passives, and SOIC ICs with the exception of the digipot), so they can be hand assembled relatively quickly.
Things that needed work:
- Microcontroller: I'd initially hoped that each modular radiation sensor would a be a "smart" detector, having it's own digital interface to ease data collection. Unfortunately even with my first pass at isolating things the microcontroller introduced too much noise into the analog portions of the system, and had to be removed.
- Analog to Digital Conversion: I've been very interested in developing a detector that can do very crude spectroscopy / energy level differentiation, to help render more informative scans. I've been crudely doing something similar to this with the Arducorder Mini, measuring the pulse widths from the Type 5, which tend to correlate with pulse height -- but of course actually measuring the pulse height should be much more accurate. To do this I'd piped the amplified analog voltage (before the comparator) to one of the ADC channels of the PIC24FV32KA301, which has a 12-bit ADC, at a 100Ksps sample speed. Unfortunately while some of the very largest peaks could reach ~10uSec (100Ksps) in duration, most of them are much shorter -- on the order of ~1uSec (1Msps). I don't have a lot of experience with fast analog signal peak detection, but I suspect one would require a significantly more complicated (and expensive) circuit to do this well. I'm very interested in this, but it will likely require more thought, and (unfortunately) likely won't make it into this iteration.
- Gain: I increased the gain on both the preamplifier and dual amplifier stages.
- Shield: A grounded foil shield surrounding the sensor is absolutely critical, but I had neglected to put a solder point on for the shield in the previous iteration -- so this was added in.
- Size: In order to fit into the 6" diameter enclosure symmetrically, the modular detectors needed to be reduced to a length of no more than 30mm, which required a bit of work (see figure below).
- Easy stacking: The photodiode stacking is giving near-linear increases in detection efficiency for low numbers of photodiodes, which is incredible, but I needed a simple way to make this compatible with surface mount soldering. I redesigned the footprint for the BPW34S to allow a stack of up to 4 photodiodes to snugly fit in a special slot, and be surface mount soldered in a normal reflow process. They'll still have to be hand placed, but a few seconds of work is easily work it for increasing the detector's performance by a factor of 3 (!).
The schematic for the modular radiation detector (revision 1) is pictured above. Most of the revisions affected component values and mechanical layout, with the exception of moving the microcontroller offboard. PDFs of the schematics (as well as the Eagle files) are available in the OpenCT2 Github repository.
With stacking the BPW34S photodiodes, the total length of the prototype detector had increased to about 40mm. With my completely arbitrary and aesthetic desire to fit the entire device into inexpensive 6 inch PVC tubes (with a 5.7" inner diameter), the detector board had to be reduced to a maximum of 30mm in length to fit symmetrically. Sacrificing a bit of height for the sake of symmetry, this first revision of the detector comes in at ~30mm x 48mm, allowing for the symmetrical design above.
Imaging Array Board
The imaging array board (above) functions to hold in place 16 of the detectors that together make up the imaging array. Here, each detector is equidistant from the source (at 2.25 inches or ~6cm), and rotated about 5 degrees with respect to the neighbouring detectors such that their photodiodes are facing straight towards the source -- the orientation where they're most efficient.
I really enjoy the shape of this board, and it's certainly one of the more unusual designs that I've had the opportunity to put together. It's functions are largely mechanical, but it also includes a header to connect a separate Microcontroller Board (below) that interfaces to each of the 16 detector modules, and performs the actual counting. While the comparator output pins of the detector modules are all brought out to the microcontroller connector, the SPI pins for the digital potentiometers are brought out to an I/O expander (a Microchip MCP23017) to handle toggling the 16 independent chip select (CS) lines. It's not entirely clear whether the digipots on each detector will all have the same calibration setting, or whether they'll each require slightly different settings, so here on this prototype the I/O expander is included to allow for the possibility of setting each one individually. It's important to make our mistakes cheaply, after all.
The Microcontroller board (above), from a functional perspective, needs to wait for detection pulses from each of the 16 detectors, count them over a period of time, and then communicate the total number of counts from each detector (after about a minute of collecting data) to another board, say a Raspberry Pi, that's controlling the whole show, and generating the images.
Nominally this is a perfect job for an FPGA, but they're a little challenging to program, and it's been a few years since I've tinkered with one. Many of the larger Microchip microcontrollers have 16 or more Change Notification (CN) I/O pins, which can trigger interrupts, and would also be very suitable for this task -- though that would require soldering a TQFP. While I would normally make this decision, I'm continually trying to be attentive to making open source projects accessible whenever possible -- I tend to design projects that are extremely challenging to assemble for the average maker. For example, the Arducorder Mini includes a fine-pitched 100-pin TQFP for the microcontroller and many other leadless fine pitched parts, and other than the handful that I've made and sent out, I've not yet heard of an Arducorder made in the wild -- although I'm very happy that parts of the design, like drivers and reference schematics for the Hamamatsu Microspectrometer, are being used. One of the best feelings that you get as an open content author is when people make, use, and modify your designs, and I'm making an effort to design the OpenCT2 such that the most complex bits could be assembled by a capable undergraduate student with very modest surface mount soldering exposure.
In light of this, I've opted to include Sparkfun's great Arduino Pro Mini, which is extremely easy to solder, inexpensive, and has *just* enough pins to cover the task. It can also very easily communicate to a Raspberry Pi (or other host computer) with an FTDI USB->Serial cable, and can be reprogrammed with the popular Arduino IDE, which should encourage tinkering, learning, and experimenting from the community and budding computed tomography students/enthusiasts.
Physical Tomographic Framework
While I've been waiting for the boards to be fabricated, I've had a bit of time to tinker with the mechanical bits of the project. Both the imaging array and the mechanical tomography machinery have physical constraints (for example, a lead screw can't go through a detector), and so the design of both the imaging boards and the linear stages had a lot of back-and-forth.
Lately I've been really interested in round/organic designs, and also in arrays of things -- and so I've tried to include these themes into this project, both with the array of detectors, and the interesting design challenges that come with making something that's round and has a lot of moving parts.
The current design is about 11 inches high and just under 5.7 inches in diameter, which allows it to easily housed in a standard 6 inch PVC plumbing pipe from a local hardware store (like Home Depot).
The design has two main axes of motion, which is greatly simplified over the original OpenCT -- a linear stage, that moves the entire imaging array up and down, as well as a rotary stage, that rotates the sample 360 degrees (here represented with the clear acrylic sample container). Previously I'd used only two lead screws to index the linear stage, but this was really wishful thinking, and the staged walked from side to side quite a bit instead of moving smoothly.
Here, I've added an extra motor to the linear stage (bringing the total up to 3), which should make the motion much smoother, and add a bit more support for the imaging array, the Barium 133 radioisotope source, as well as a generous amount of lead shielding. Not having a lot of experience with things made out of solid lead, you /know/ it's going to be heavy before you pick it up, but it's still way heavier than you expect.
The motor for the rotational stage was originally a NEMA17, but I've sized this down to a NEMA14 to match the other motors, given that it shouldn't require very much torque to get the sample moving. This also keeps the design (and the BOM) a bit simpler.
The couplers are the inexpensive aluminum flex couplers that go from the M5 stepper motor shafts to the M8 nylon lead screw. These
From the top down, here we can see the top supports for the nylon lead screws, as well as the tops of the three steel threaded rods that extend from top to bottom, and are used as a structural supports for the entire mechanism.
Imaging Array Carriage
The Imaging Array Carriage (above) houses the imaging detector array and source, and indexes up and down around the 2-inch diameter acrylic sample container. Here a mock-up of the imaging array board can be seen, to give a rough idea of fit while the boards are being manufactured.
At about 70mm in height, the imaging array carriage is a little higher than I was expecting, but it's very workable for a first pass. The height largely comes from the 48mm required for each detector, not including the connector and the Imaging Array Board itself.
Like the two linear axes inside of the original OpenCT bore, I've found that inexpensive aluminum rod (here 0.25 inch) and nylon bushings available anywhere from McMaster-Carr to a local hardware store work very well as linear slides.
I've also been using nylon lead screws lately for projects where keeping things light is an asset, and absolute precision isn't required. With traditional stages assembled using steel threaded rod, I've found that unless you're willing to use rod designed for linear motion, it often has very slight bends or otherwise generates alignment problems that can be frustrating to deal with. Here, the nylon lead screw (and nylon nut) are extremely inexpensive, light, and have a bit of give to help adjust to any alignment issues. Note that the nuts are normally sandwiched in between two pieces of MDF, but they haven't yet been installed in this picture.
It's my hope that the project will have three main contributions, each dependent upon the last:
- An inexpensive high-energy particle detector
- An imaging array and supporting hardware, composed of many detectors
- A physical mechanical platform for desktop computed tomography or scanning, whether coupled with the above imaging array, or any other sensor or imaging array a student, researcher, or enthusiast might use.
To make things accessible, I'm trying to keep each component as easy as possible for folks to assemble. While each detector (1) does require modest surface mount soldering exposure, I'm trying to design the imaging array (2) to largely require only through-hole soldering, and the mechanical CT platform and control electronics (3) to require minimal soldering and use as many off-the-shelf components as possible -- something that you might see as a set of instructions in Make Magazine rather than a laborious set of assembly instructions sent to a contract manufacturer.
With this goal in mind, I'm trying to see if a regular Arduino Uno and Motor Shield (to control the motion) coupled with a Raspberry Pi (for a Wifi-enabled user interface) will be sufficiently powerful to do everything that needs to be done, while keeping everything very off-the-shelf and accessible.
Both the Arduino Uno and Raspberry Pi currently have mount points at the bottom of the tomography platform, just under the motors. They're mounted outward to allow easy access to the various connectors, and make assembly and maintenance as easy as possible.
Thanks for reading!
06/27/2015 at 18:28 •
The revised high energy particle detector boards arrived, and I've had the chance to put one together and verify it working over the weekend — and snapped some pictures of the assembly process along the way. This (long!) post details the assembly process, and (towards the bottom) describes some initial characterization of the detector, including a histogram of detector variability.
Pictured above is one of the Radiation Sensor Revision 1 boards, coupled with the very curiously-shaped Imaging Array board. It’s not often that I find myself having to design boards in interesting shapes, and while the first goal is of course to design something that works, it’s always wonderful when you have the opportunity to make it look aesthetically pleasing, too.
The Radiation Sensor Revision 1 designs are available on Github, including the schematics, gerbers, and parts list. The boards I’ve shown have been ordered from OSH Park, and the stencil from OSH Stencils. Most of the component values are included on the board silkscreen, so it’s generally a comfortable assembly process if you have experience assembling a few surface mount boards. (Note that the detector I've assembled here has had C2 changed from a 4.7pF to 2.2pF to examine if a higher gain on the first stage significantly improves signal to noise, but so far it looks like either value should work just fine).
In addition to the normal surface mount soldering process, there are a few additional steps in the assembly process to accommodate bending the photodiode leads, creating a light-tight wrap, and applying the grounded shield. These are a bit atypical, so I’ve documented them here.
Photodiode Angling/Stacking Jig
The detector uses an array of four BPW34S photodiodes stacked one atop each other (and, laying on their side) to dramatically increase detection efficiency. Straight out of the tube these photodiodes generally come with leads that are 90 degrees from the main body, and need to be slightly angled so that they easily sit atop one another (and make contact with the surface mount pads on the board).
A small laser-cuttable jig to perform this bending is available here, and pictured above. The jig contains 10, 20, and 30 degree pin angles — I find that the 20 degree works optimally. To bend the photodiode, lightly squish it onto the jig, and the pins will spread to the appropriate angle. I have found that 3/16″ acrylic worked well for this jig, being about the same width as the photodiode.
Above we can see the difference in between the original pin angle (left) and pins angled slightly at 20 degrees (right) to enable stacking. I recommend that the photodiodes be the last components placed on the board, using tweezers, and sitting (laying?) flush one atop another.
Connector Lead Trimming
To get as high an imaging resolution as possible and increase the packing efficiency, the detectors have been designed to be as thin as possible — only 4mm (!) on the imaging dimension. To ensure that they’re as thin as possible, the main 9-pin male connector (bottom) may need to be slightly trimmed, depending on the part you use.
(The imaging array board for the “cat” scanner, with an actual cat, for size).
The connector that I’ve spec’d for the radiation sensor boards is Digikey #S1111EC-09-ND. I looked for a connector with the shortest leads that I could find, and confess that from the datasheet I had expected the pins to be a little shorter. Normally you could use a surface mount connector for this and not have to deal with through-hole leads poking out of the back of the board, but the alignment of our imaging array is important, so I’ve included the through-hole connector with slightly offset pins to encourage the connector to align properly. I’m also convinced that the through-hole connector is likely more mechanically stable than a surface-mount version.
Here (above) we can see the start of the pins being trimmed — either a standard pair of wire trimmers or right-angle trimmers should work well for this.
And here each of the pins has been trimmed. When soldering, don’t forget to warm up the pin before applying the solder — it’s important to encourage the solder to fill the hole from top to bottom, and be both mechanically rigid and a solid conductor.
The board, after soldering on the connector. Ready for wrapping!
Wrapping Part 1: Insulating light-tight layer
The detector has to be wrapped in several layers — both to shield the photodiode from any external light, and provide a grounded conductive shield to reduce the electrical noise. I do the wrap in two layers — a layer of black electrical tape (to shield from light, and insulate the board from the conductive tape), then a layer of aluminum tape for the grounded shield.
Here, I prefer to start at the the top of the back of the board…
Then wrap around the front, completely covering the photodiode stack with a single layer of electrical tape. From here, I wrap around the back again…
… and several more times, until the entire board (including all parts and vias) are covered, save the connector at the bottom, and the “shield” pad on the back of the board at the bottom (below). I try not to cover the bulk of the photodiodes in more than one layer of electrical tape, so that the photons don’t have more bulk material to go through before hitting the photodiodes (not that the electrical tape is likely to be terribly absorptive).
While the top (component side) of the board will be a little bumpy from all the components, try to wrap the back side of the board as smoothly as possible, as we’ll have a mechanical ground wire connection to place here in a moment.
Wrapping Part 2: Grounded Aluminum Shield
The second layer is a wrap of Aluminum tape that surrounds the detector and provides a grounded electrical shield that reduces electrical noise. This is a critical part of the circuit, so take your time to ensure that the shield is well crafted.
The first component of the shield is the ground wire (above). Cut a piece of stranded wire about 1.5 inches in length, with a small section stripped at the bottom, and a much larger section stripped near the top. Pre-tin the bottom section, but do not apply any solder or twist the large stripped section at the top (this will make sense in a moment).
Solder the ground wire to the ground pad on the back side of the board. I recommend holding the wire down with another piece of electrical tape (while soldering) to ensure that it’s as flat to the circuit board as possible. We’re about to cover the back of the board in aluminum tape, so try to ensure that the back is as flat as possible.
We can’t solder the ground wire to the aluminum tape, so we have to make a solid mechanical connection. The method that I’m showing here is what I’ve inferred is likely used with the Radiation Watch Type 5, after carefully examining it.
Cut a piece of aluminum tape that’s about three times as long as the detector is wide (~10cm). The aluminum tape I use is standard off-the-shelf tape from Home Depot intended for sealing ventilation conduits.
Make the first layer on the back of the board (as shown above), aligned with the edge of the board on one side, and just above the shield pad/electrical tape on the other. Remember, ensure that the electrical tape covers /all/ components and vias with a margin of a few millimeters, and ensure that the aluminum tape is seated completely on the electrical tape (with a bit of a margin) and not touching the board — otherwise it may bridge and cause a short circuit!
It’s okay (and preferred) for the tape to extend over the top of the board a little — just cut a seam along one edge,…
… and bend it over the top of the board, as above.
Place the board in a board vice, and carefully fan out the stranded wires over the back of the board, as above. The idea here is that they will be sandwiched between the conductive layer of aluminum tape below them, and the adhesive layer of aluminum tape we’re about to put overtop of them.
Note that the more stands we have in the stranded wire, the better the connection is likely to be. The wire that I’ve spec’d for this (Digikey #CN100B-25-ND) is 22awg 17 conductor strand wire, which has many more strands than the cheap 7 strand wires, and should perform much better for this task.
Wrap the aluminum tape over the front of the board. For the excess tape over the top, again cut a small slit along the seam, and fold the excess down onto the top of the board.
Now the critical fold — slowly fold the tape over the back (and the bare stranded wire), ensuring that it’s reasonably tight, and squished down such that the stranded wire is very firmly pressed into place against the underlying layer of aluminum tape. Use a meter to verify that the aluminum tape shield is effectively grounded.
And, lastly, fold any excess over the top of the board. Congratulations, the board should be light-tight, and electrically shielded! Don’t forget to use a meter to verify that the shield is grounded, and that there aren’t any electrical bridges between the shield and any of the pins on the connector.
Performance and Measurement Variability
In terms of general performance, with the 10uCi Barium-133 radioisotope source ~6cm away from the detector, the detector measures an average of 70 counts per minute (cpm).
Absorbance imaging from a weak radioisotope source is an interesting problem — if you think of another (simpler) example of absorbance imaging, holding up a film negative or slide to a lamp, assuming the lamp you’re using to backlight the slide is fairly uniform, it’s easy to make out the picture on the slide. With weak radioisotope imaging, the source is fantastically more dim, and so instead of having an enormous stream of photons backlighting the sample, we’re essentially counting single photons as they interact with the detector, about one per second. On timescales of minutes to hours the average rate that the Ba133 source emits these photons is about constant, but on the shorter timescales that we’re using for imaging, there’s much more variability (a phenomenon known as shot noise). For imaging, this is further complicated in that x-ray photons are being emitted from the source in all directions, but each pixel is very small — at a 6cm radius around the source, a sphere has a surface area of 45,238mm^2, but each detector is sensing photons from only 7.5mm^2 of that sphere (a difference of a factor of over 6,000), so there will be quite a bit more variability in our measurements. But how much?
Above I’ve plotted a histogram that helps illustrate the measurement variability using a technique called Bootstrap Resampling. Here, I’ve connected up an Arduino Uno to the detector, and set it to listen for detections for 10 seconds, and report the detection rate (in cpm). I then do this many times over the course of about 2 hours, until there are nearly 1000 of these 10 second measurements, and plot them as the blue line in the histogram. Here we can see that there’s quite a bit of variability in these short measurements — they span from about 20cpm, when few photons happened to be emitted in the direction of the detector over a given 10 second interval, to 140cpm, where there was a photon party in detector town, and everyone was invited. The bulk of the measurements show rates of between 40-100cpm, with a roughly Gaussian distribution. (For those interested, the raw data is available here, and the histogram is available on Plotly).
To simulate the variability at integration times longer than 10 seconds, I use bootstrap resampling to randomly draw a number of 10 second samples, and average them. For example, to simulate a 20 second integration time, one would randomly draw two 10 second samples, and average them. To simulate a minute long integration time, one would randomly draw six 10 second samples, and average them. If you do this random resampling many times — here about 10,000 times per integration time, then you can simulate a smooth distribution.
Integration Time 10s 30s 1m 2m 5m 10m Standard Deviation 20.3 11.7 8.4 5.8 3.7 2.6
Here we can see both on the histogram and in the table (above) that on timescales of tens of seconds, the variability is quite large compared to the average rate (over long timescales) of 70cpm. For those not familiar with statistics, the Standard Deviation is a measure of variability in a Guassian-shaped distribution. The measured value will be between +/- one standard deviation from the mean value of 70cpm about 68% of the time, and within +/- two standard deviations of the mean value 95% of the time.
Here we can see that on timescales of tens of seconds, the variability is quite large — at a sample time of only 10 seconds, we’ll measure a rate of 70 ±20cpm (or 50-90cpm) 68% of the time, and a rate of 70 ±(20*2=40)cpm (or 30-110cpm) 95% of the time. That’s very large, and so such short integration times won’t be very useful for imaging — with such a high variability, the image would look very noisy.
The integration time follows the Poisson relationship, such that measuring for N times longer decreases the variability in the measurement by sqrt(N) — so measuring for twice as long decreases the variability by a factor of about 1.4, and measuring for 4 times as long decreases the variability by a factor of 2. We can see this in the table above, where the standard deviation at a 2 min/120 sec integration time (5.8) is twice as stable as the variability at only a 30 second integration time (11.7). The target (“within the limit of patience”) integration time of 120 seconds means the signal intensity will vary from 70 ±5.8cpm (64-76cpm) most of the time, to 70 ±12cpm (58-82cpm) 95% of the time. This should be more than enough to generate a low-resolution image, and with some filtering we may be able to clean up a bit of the noise in the images as well.
The next step is to put together a partial array of detectors (about 4) to verify their performance and repeatability. If everything looks good, the imaging array can be mounted onto the tomography platform, and we can move towards collecting the first imaging data.
Thanks for reading!
07/07/2015 at 04:54 •
A few years ago, while sitting in on a grad class in computational sensing, I (a Canadian) had my first real experience with the American healthcare system, and proclaimed whilst in (billing-related) shock that one day I would create a CT scanner for less than the billed cost of one scan. While I've had to scale back a bit over my original ambitions -- it's much smaller, and much slower, given my aversion to radioactive things -- in the past week I've felt as though it's really starting to take shape, and that a few months of planning and design revision are starting to come together.
I had the chance to put together four of the modular radiation sensors, place them on the array board, populate the tiny Arduino control board -- and it all came together great. I wrote some very basic firmware that listens for pin-change interrupts, checks which pins have changed, and adds counts for the respective detector. It seems to be working wonderfully.
Like the Radiation Watch Type 5 detector in the Arducorder Mini, I added in a pulse width histogram into the driver for this imaging array, to see if it's capable of doing very crude spectroscopy. Unfortunately while pulse height is correlated with energy, pulse width with this detector is nearly always 10-20uSec, and not terribly useful for energy level discrimination. That being said, the digipot on the comparator allows one to dynamically set the detection threshold, so it's likely still possible to do energy level discrimination, but at the expense of multiple exposures. I'm looking forward to experimenting with this.
There is a bit of variance in the noise level of the detectors, and the digipots do clearly have to be set to slightly different values (a few millivolts apart) to see the same signal-to-noise characteristics on each detector. This is good to know, and really justifies having added the ability to individually set the comparator thresholds on each detector using the MCP23017 I/O expander.
I decided to make a major mechanical change, and increase the sample container size from 2 inches in diameter to 3 inches. I had originally planned to use a 3 inch container with a scan volume the size of a pop can, but lowered it both to (1) increase the signal-to-noise ratio, and (2) keep the total build size of the machine to within 6 inches in diameter.
While I had convinced myself that there'd be plenty of interesting things to scan that were less than 2 inches in diameter (like the bags of tiny peppers in the grocery store), after building the tiny 4-detector array, I simply couldn't find many things that would fit for a quick test -- everything was just slightly too big. Science is about trying not to fool yourself, when you're the easiest one to fool. I had fooled myself into thinking that the smaller diameter would work for the benefits in SNR, but when confronted with real test cases, it just isn't practical. This is a big of an expensive mistake given that it means I have to redesign the imaging array for a larger sample container size, but it's much better to make the change now and have a much more useful instrument.
Limiting the machine size to 6 inches in diameter also isn't practical for a 3 inch sample container, though I have had trouble sourcing larger 8 inch PVC tubes to use as an easy enclosure. David Forbes of Nixie Watch fame happened to know an online store that stocks a variety of PVC pipe sizes with very reasonable shipping for enormous heavy tubes, with an 8-inch diameter by 14-inch height thin-walled tube costing only about $20, shipped -- so this solved a major issue, and the size of the machine can now easily increase.
With an increase in size from 6 inches to 8 inches, this allows just enough room for more conventional linear motion systems, like the Makerslide v-wheel based aluminum extrusion. This is very easy to get ahold of through Inventables, and much more rigid than my laser cut system. Here I've cut down a large piece into two 24cm sections, and milled the faces to be completely flat after the cut.
The Makerslide attaches to the frame on edge through two M5-tapped holes at either end of the extrusion. This 3D-printable tapping jig on Thingiverse is absolutely essential for this -- a few years ago I tried tapping Makerslide without a jig, and the result was horrible. "Cut a full turn, then back off half a turn to let the material work it's way out. Keep repeating this until your tap is too dirty or the hole is deep enough. Don't forget to use tapping fluid!" -- thanks Dad.
Following the above advice can really lead to some very successfully tapped holes.
While Makerslide provides a very solid slide and carriage, we still need a way to transfer linear motion from a stepper motor to that carriage. I prefer using lead screws for this application rather than belts since the load can rest on the leadscrew, even when the stepper motor isn't powered. Here I've put together a small printable nut holder that low-profile enough to live between the Makerslide and the carriage, and attach with normal M5 extrusion bolts and t-slot nuts.
A nylon M8 nut very snugly fits into the back of the nut holder.
Allowing an M8 threaded nylon rod to be threaded through, and used to transfer linear motion.
While the nylon might seem like an unusual material to use for transferring linear motion, it tends to have a small amount of mechanical play that allows it to self-align when coupled with a rigid linear rail like the Makerslide. I've used traditional steel threaded rod before, but I've found that the small diameter rod tends to bend very easily (even while shipping), and it makes alignment and binding a constant issue. The nylon solves this issue, has a very low friction and wear without lubrication, and is very inexpensive.
Here the printed nut holder can be seen sandwiched between the carriage that it's bolted to, and the Makerslide rail.
The holder is designed to mate with the footprint on a standard wheel carriage plate, to make the linear motion system as rigid and off-the-shelf as possible.
At the bottom, the four NEMA14 motors have been replaced with three NEMA17 motors from Adafruit -- two for the two Makeslide rails, and one to rotate the table. Since the two motors for the linear rail system move in unison, all three motors can be connected to a single Arduino motor shield.
Two 10cm pieces of Misumi aluminum extrusion bridge the gap between the carriages, and provide a solid surface to mount both the detector array (on one side) and the Barium-133 radioisotope source (on the other). The table mock-up is currently just a 3 inch disk, but eventually will need a proper mechanism that couples to the sample container, as well as a bearing to restrict the motion of any off-balance samples.
And it works! With a very smooth motion, on both the linear and rotational axes.
Thanks for reading!
08/14/2015 at 07:31 •
This is probably the strangest video anyone has ever made about computed tomography scanners, or entered into the Hackaday Prize. But last year's videos were so serious, so I decided to have a little fun this year.
I had the opportunity to make four more detectors while filming the quarterfinals video, and and filmed the atypical parts of the build process, including the wrapping (both with the electrical tape and conductive tape shield), as well as the ground wire installation. I'd like to put together a longer video that illustrates these processes, to make it easier for folks working to build their own detectors.
Changing the sample container size from 2 inches to 3 inches in diameter caused a full design revision for mechanical issues, including the imaging array board. Below the new imaging array board can be seen holding four of the sixteen total detectors. A new microcontroller board should arrive in the next few days to drive this board, so that we can get back to imaging!
Similarly, to accommodate the new imaging array board, the linear motion system on the mechanical platform had to become 6mm larger. This is visually indistinguishable in the pictures, but meant the entire rig had to be disassembled and reassembled using new (slightly differently patterned) laser cut parts.
While filming, I had the opportunity to put the tomographic platform together, and hope to also put together a timelapse video illustrating this process for folks interested in constructing their own.
Just a quick update, and a little less frequent than normal (I was on vacation back home in Canada for a few weeks!), but stay tuned -- thanks for reading!
08/28/2015 at 05:27 •
One step back then two steps forward, I've captured the first one dimensional data from the detector array!
The new imaging array is now populated with 10 of the 16 total detectors, and this is very exciting. I tend to try and keep things positive, but sometimes things go well, and sometimes things happen that slow things down. It's always important to make your mistakes cheaply whenever possible, and this week several things happened -- and while they were not terribly expensive issues, they were preventable.
An incorrectly labelled footprint: The Arduino Pro Mini has exactly enough pins to monitor the output of the 16 detectors, and communicate to each detector's digipot (which calibrates that detector's sensitivity) using SPI. Because there are 16 detectors and 16 chip select (CS) lines for the digipots, the Imaging Array board also contains a Microchip MCP23017 16-bit I/O expander, connected to the Arduino Pro Mini using I2C. Exactly enough pins.
Unfortunately as it turns out, two pins on the Arduino Pro Mini (A6/A7) are not available to use as digital pins, and I discovered this only when two detector channels were silent. I revised the microcontroller board to include it's own I2C I/O expander for the extra two pins, but it turns out the open source footprint I used was incorrect, and when I powered the board the I/O expander caught fire. It was an easy mistake for whoever made the footprint to make -- and I try to make my own footprints to ensure that they're correct, but I was pressed for time. A few days later the part was swapped, and the board running again. This wasn't a big deal, but it did cost a few days of waiting for parts to arrive.
Bridging the 5V and 40V lines.
To make up the few days I lost waiting for parts to come in for the microcontroller board, I worked a little too quickly. The Imaging Array board has a polarized 4-pin power connector that connects to a power cable, and right now this cable is connected to two different supplies through alligator clips -- 5V for the analog bits on the detectors, and 40V for the photodiode bias. I usually place a little electrical tape over these alligator clips to prevent them from bridging, and while this tape was present, in my haste I didn't replace it, and kept on the older tape from a few days ago.
Unfortunately over about an hour of firmware debugging and detector testing the glue on the tape slowly let go and the tape on two alligator clips opened up, bridging the 5V and 40V lines. Nearly everything connected went up -- two detector modules, the freshly-soldered microcontroller board, and even the USB hub didn't enjoy 40V being placed through it. It's been years since I've blown anything up, and I blew up two things only a few days apart!
This was more expensive in time than anything else -- it takes about 2 hours to completely assemble and test a detector, and an hour for the microcontroller board. ("That's why I fuse everything!" -- my dad, an industrial engineer. Thanks dad -- I had planned on including a fuse on the power supply, but clearly I should have placed one on the imaging board itself!).
The laser cutter stopped working
Unfortunately our beautiful laser cutter at Xerocraft went through another tube a week ago, and at a very inconvenient time -- just as I was about to teach a laser cutter class. It'll likely be another week until a replacement is here, and I'm eagerly awaiting its arrival so that I can fabricate the mount that secures both the imaging array and Ba133 radioisotope source to the Z stage.
Assembling additional detectors
With only 6 detectors post explosions, and no laser cutter to build a mounting bracket, it was time to assemble more detectors. I have found that when hand assembling them, doing so in batches of 4 tends to maximize throughput -- it takes about 3 hours to go from 4 bare boards to pasted boards to populated boards to toaster-oven reflowed boards. After cooling down, it takes about another hour or so to wrap the boards in electrical tape, apply the aluminum shield tape, solder on the ground wires, and finally populate the 9-pin right angle connector on the bottom that allows each detector to plug into the imaging array.
With a total of 10 detectors currently populated, I snapped some pictures of the imaging array before capturing the first data. The picture above is one of my favorite from this project so far -- the crisp contrast of purples and whites/greys along with the coloured cables is really aesthetically pleasing.
One of the most wild things to me is that this is a camera. Taking a step back, It's really incredible to think that high energy particles like x-rays and gamma rays just sail right through the aluminum tape to a highly charged detector that amplifies the signal of those single photons by about a million times so that they can be individually counted, and does this with an efficiency of about 1% for the Barium 133 radioisotope photons. Of course very similar modules have been inside CT scanners for about 30 years, and the ones in use today are incredible and far more sophisticated than this -- but it's still very exciting to me, and I'm not aware of anyone else having tried to develop their own highly-efficient imaging array for very low intensity sources, or such an inexpensive array for pedagogical purposes.
An Image of the Grape
I've been itching to collect real data off the array for a while, and with the laser cutter out of commission until the new tube arrives, actually mounting the array and source in the detector will have to wait for a week or two.
To get around this, I taped the Ba133 source to a plastic tube at the same height as the detectors, and taped a delicious grape in a mount between the source and imaging array. I chose the grape because it's mostly water, which is highly absorptive to high energy particles, and so it should provide a good amount of contrast.
Above is a graph of the x-ray absorbance measured on each detector channel from the grape, with a sample time of a few minutes. The absorbance reflects the difference between sampling for a few minutes (without the grape) to get a baseline reading for each channel, and then sampling with the grape to measure the relative absorbance.
Lining up the absorbance values for each detector channel with the picture above, we can see there is clearly more absorbance on the channels that have to go through more grape. This peaks with nearly 20% absorbance at channel 6, which goes straight through the center of the grape, and is much smaller for channels 9-12, which just graze the edge and thus go through comparatively less grape. Here the variance is limited by the shot noise of the extremely low intensity radioisotope source, and decreases with increased integration time. This is why some channels with very low absorbance (like channel 11) can appear to have a negative absorbance relative to the baseline -- with this integration time there's likely to be a variance of about 4%, so an absorbance of -2% is well within the error.
Very exciting to see some first data -- with some luck I'll be able to populate the remaining detector channels shortly, mount the array to the tomographic platform, and begin to take some 2D images and tomographic slices in the next few weeks!
Thanks for reading!
10/16/2015 at 07:20 •
A very exciting (and somewhat sleepy) update -- with the very first (2D) image from the scanner, of the top of a peach!
I had the chance to complete the firmware for both the imaging array and motor controller, and acquire the very first image from the array! While I'd previously put together firmware to test the imaging array and motor controller, this past weekend I added a serial console to each that allows commands to be sent from a host computer, processed, and returned. This means that the detector array can be calibrated and used to acquire data remotely, and that (in concert with the motor controller) can be orchestrated to take full images!
I put together a quick script in Processing that would connect to both the imaging array and motor controller over usb->serial links to their respective Arduino controllers, and orchestrate the process enough to acquire the very first data, shown above!
I placed a peach in the machine on the sample table, and imaged from the center of the peach to the top. Only 10 detectors are populated, so the image is limited to 10 pixels in one dimension, but this can ultimately increase to 16 pixels after the last six detectors on the periphery are populated. Still, only 10 detectors was plenty to observe some basic structure.
A few weeks ago I had the chance to put together the basic design for a mount for the Ba133 radioisotope source, that would both allow ample shielding, and be easily removed and stored elsewhere during the debug stage. I'd accidentally cut the aperture for the radioisotope source a little small (and haven't had the chance to recut it), so in these pictures the source is secured using... tape.
While I was designing the source mount, I was also able to put together a laser cut bearing mount for the table, so it's now much more stable, and needs only another design revision or two before it can be coupled with the cylindrical sample container.
And here's the first data, overlayed upon the peach itself. It looks very good for a very first, barely calibrated image.
Due to the shot noise associated with using such an extremely low intensity source, coupled with detectors that have 11 times less (9mm^2) area than the original OpenCT using the Radiation Watch Type 5 detector (100mm^2), there is a little more noise than I was expecting, and the integration times have to be longer than I was hoping to reduce the variance as much as possible. I found that a 5-minute integration time was okay to pick up the larger contrasts, and that smoothing the image using a 3x3 box kernel helped reduce what is essentially Gaussian white noise in the image. There is clear contrast between the air (blue) and peach, but also a clear contrast between the middle of the bulk of the peach (red) and the top of the peach (yellow/green), which has much less material to go through. I'm not sure if the peach pit is visible, or whether the more absorptive region in the center is just an artifact, but a few more scans will likely sort this out.
In all, an integration time of 5 minutes per 1D row is about 2 to 3 times as long as I was hoping for. I haven't yet constructed a simulator for this machine, so it's not immediately clear to me if using many of these low-SNR images for tomographic reconstruction will functionally increase the SNR of the slice that's being reconstructed (like oversampling), or if the tomographic reconstruction process is particularly sensitive to noise, and the integration time has to be increased even further to have pristine images going in for reconstruction to be successful. It's likely I'll have a sense of this soon, as there's a fantastic looking bell pepper that I'm excited to scan as soon as time presents itself.
My apologies for taking so long to update! After five years of being a Postdoctoral Fellow, I'm very excited to have recently started a non-tenure track Research Professorship. The teaching load in addition to my normal research has been keeping me exceptionally busy, and so working on the CT scanner has been a little slower than I'd hoped -- but certainly no less exciting.
Thanks for reading!
11/22/2015 at 20:06 •
A quick update today about power supplies. It's been an incredibly busy month in the lab, and I've had precious little time to work on OpenCT2 (and even less time to write a proper update).
Essentially all of the critical pieces of the system have been designed, but right now the system takes up much of a bench when running -- the unit itself, plus several bench power supplies, a USB hub, a laptop, and a bunch of cabling. I'd like to get everything mounted into the unit, replacing (a) the bench supplies with an internal supply, and (b) the laptop with a Raspberry Pi mounted inside. This should make everything much more compact, self-contained, and allow me to easily do long calibration runs, and evaluate the system performance.
I've been focusing on prototyping the power supply, so that once I have a working design hammered out, I can send off a design to OSHPark and have a compact board that can be mounted inside the unit. The system requires four separate supplies, each with their own requirements:
- Detector Analog Supply (5V): An ultra-low noise supply to power the detectors on the imaging array, and their extremely precise opamps that amplify the incredibly small current from individual x-ray photons to voltage signals detectable by a microcontroller. Right now I'm using a low-noise bench supply for this. The total draw for the entire array will be about 200ma.
- Detector Photodiode Supply (40V): The reverse-bias voltage for the photodiodes on each detector in the imaging array. This also has to be ultra-low noise, and given it's very modest current requirements, I've been using a bank of 4 9V batteries to make sure it's a clean signal. Given the low draw the batteries seem to last quite a while, so I'm okay leaving this one battery powered for now, until an alternate supply can be found.
- Stepper Motor Supply (5V): This powers the steppers for the linear (Z) and rotational (R) axes. The draw is well under an amp, but it generates an extremely large amount of noise. I'm keeping the steppers turned off during measurements, to reduce the noise.
- Raspberry Pi USB Supply (5V): The power supply for the Raspberry Pi, plus the USB devices connected to it (which includes a WiFi dongle, the Arduino Due, and the Arduino Pro Mini). The draw should be limited to 2A, but this line will likely have a lot of high frequency noise on it.
Because one of my main goals for this project is ease of repeatability -- that is, I'd like others to be able to build it without having to source difficult-to-find components or build difficult to assemble boards -- I'm hoping to find pre-made power modules that I can just plug in to an easy-to-solder through-hole board. I'm okay at many aspects of design, but low-noise supplies are one area that I'm not terribly experienced with, so this would help save me a good deal of effort, too.
Having never sourced ultra-low noise supplies before, it's incredibly challenging to find economical pre-made modules. Pragmatically, it's also not entirely clear how ultra-low noise the detector supply has to be. In light of this, I decided to try three 5V modules from Pololu, a 2.5A for the Raspberry Pi, a 1A for the motor supply, and a 500ma for the detectors (pictured above). They're all switching supplies, so they will have plenty of ripple to them at the best of times, but I thought I'd give it a try.
It turns out the supplies are incredibly noisy, at least from the perspective of high-energy particle detectors with ultra-low noise requirements, and the detectors register thousands of false-positive counts per second with this supply. Even for the beautifully designed Radiation Watch Type 5 detector that I used in the original OpenCT, I had the most success with powering the detector from an isolated battery -- but I'm hoping that I can avoid that, given that the acquisition times are long, and the draw of an entire imaging array would make battery power impractical.
I then swapped out the switching regular for the detectors with a regular 7805 linear regulator. For all the bad press these get these days about efficiency, and the difficulty with dissipating heat over time, this $0.50 part outputs a relatively clean voltage, and successfully powers the detectors well.
I'd like to not have to relax my "easy-to-source" criterion, but I have found some supplies claiming to be ultra-low noise on eBay (here), based on the TI TPS7A4700. Unfortunately they're coming from the other side of the world, so it'll be a few weeks until I get to test them out. Still, with the results from this quick test, I'll likely end up putting together a design that uses a linear regular for the detector supply -- the supply that is most sensitive to noise -- and use the switching regulator modules for the higher-current and less noise-sensitive motor and raspberry pi supplies.
In other news, I had the chance to do another design revision for the shielded radioisotope source holder, and mount it to the carriage. It works great, and putting the source in or taking it out to store takes only a few seconds.
Thanks for reading!
02/18/2016 at 05:45 •
Here's a mega update, with a great deal of both progress and pictures!
With the successful first scan of the peach several updates ago, my focus has been on taking the design from a prototype towards a finished, complete unit. The main issues have been:
- In it for the long haul: While the first images have been captured, real performance will only come when the system has been properly calibrated and characterized. Given the long integration times associated with the very low intensity Barium-133 radioisotope, this essentially means the system has to run for between hours to days, standalone, collecting (first) calibration data, then image data once the system is calibrated. If it takes a day to acquire a solid noise profile while the system warms up, and a week to complete a scan, that's how long it takes. Imaging by counting single photons is for the patient.
- Power supplies: The first scan required several bench supplies, but ideally the final system should be stand-alone, and function on a single supply (like a brick). Noise is a tremendous issue here for the detector array -- and having a single low-profile supply that supplies the Pi and stepper motors has to deal with both high and low frequency noise -- and a fair amount of current.
- Raspberry Pi: The system needs to run standalone off the Pi, and ideally be accessible over WiFi.
Integrated Power Supply
I'd previously decided that for simplicity I'd use a separate supply for each major system (Pi, Motors, USB Hub, Detectors), both to help isolate the noise, and given that each requires a fair amount of current. While the switching supplies I'd evaluated earlier were efficient, they were very noisy -- and extreme analog filtering suitable for subatomic particle detection not being my forte, I decided to use linear supplies. It turns out the 7805S linear regular variant can supply up to 2A (with plenty of heat sinking), making it suitable for the PI, steppers, and more than enough for the hub and steppers. After breadboarding the design to verify its noise characteristics, I designed the board above to fit under the unit, in a single quarter of a pie shape.
A mystery ensued -- for some reason the design worked on the breadboard, but when using the proper board above, the detector channels showed a great deal of noise -- far more than to be usable. I disconnected the detectors from the purple supply, and connected them back to the breadboarded version, and the noise level was the expected low level. This was unusual, but such incredibly low noise supplies are new territory for me, so I'd assumed that some noise was leaking through the air, ground plane, heat sink, or some other place. I resolved that the detector supply may just have to be on it's own board, and put the above board together.
Except, the mystery continued -- after waiting two weeks for that board to arrive, I assembled it, and the noise was /still/ there. I wasn't sure what could be the cause, so I started building another board (right) piece-by-piece. Did the board need a larger input filter capacitor? Were the fuse holders acting as tiny antennas and picking up noise from the air? It ended up that the 7805S 2A variant has different noise characteristics than the 7805CV 1A variant I had populated the breadboard with while waiting for the 2A versions to arrive from Digikey, and this was the source of the issue. Swapping out the S with the CV for the detector supply on the quarter-pi-shaped board caused the noise level to return to normal. Great!
Linear supplies require a large heat sink to dissipate all the heat they generate. Mechanically, I also needed a support bracket both to rigidly support the weight of the device while also providing an anchor point to bolt the outer cylindrical housing (an 8 inch diameter PVC pipe). I ended up cutting some 20mm aluminum extrusion into the above pattern, which allows the regulators to bolt directly into the t-slots, and supplies a very large thermal mass to dissipate all the heat of running the system (and, the Pi) continuously for days on end.
Mounts for the Control Systems
I confess that figuring out a place to mount everything proved more of a challenge than I had originally anticipated. This was compounded by having to add a USB hub, given that the few USB ports on the Pi did not appear to be able to reliably deliver power to USB devices plugged directly into the board. This was especially noticeable with the wireless connection dropping out periodicially, likely through the Wifi dongle browning out.
After trying several different configurations, I settled on the one above -- The Pi and hub on one side, with the Arduino and motor controller on the other. The power supply fits below (1/4 of the pie), with two compartments for the batteries required for the photodiode bias supply (2/4 of the pie). The remaining section of the pi is reserved for a backplate, to mount the power switch, DC power connector, and other connectors.
The motor control side is shown above. In keeping with trying to have everything either off-the-shelf, or very easily assembled if an off-the-shelf solution isn't possible, here I've used an Arduino Uno and Motor Controller Shield, that should be easy for most folks to source.
I've also included a Pololu relay shield to enable or disable the 40V photodiode bias supply, in the form of the four 9V batteries, so that they don't drain unnecessarily. That being said, the draw seems to be exceptionally minimal, and I've used the same set of four batteries for the entire duration of the project without any issue, but it's still better to be safe and err on the side of having to replace batteries once or twice a year rather than every week or two.
The Raspberry Pi and USB hub mount to the other side of the cylindrical scanner. The hub mount is designed with a little flexibility, and many low profile hubs should fit, but I've designed this holder to specifically fit an easy-to-find USB hub from Best Buy. This hub also just happens to have very reasonable noise characteristics for the devices that it powers.
The extra hat on top of the Raspberry Pi connects the GPIO connector to a smaller connector for connecting to a small control panel and display (shown below).
Another angle on the power supply board. There's still some mechanical work to be done to ensure that the apertures in the structure are appropriately placed to allow cables to move through easily. The green and red USB cables are standard low-profile cables available in bulk on Amazon.
Another angle, here the back of the USB hub. The USB connection connects to the Raspberry Pi, and the DC barrel connector connects to one of the channels of the power supply board below.
And, the four 9V supplies that function as the extremely clean V_bias photodiode bias supply. The draw on these batteries is very low, so I suspect that they'll likely be good for many months without requiring being changed. Ideally these will eventually be replaced with an ultra-low-noise supply, but this is a low priority.
As it turns out, I also had issues with /this/ supply, in spite of it being only four batteries in holders! Each holder has a power switch, and two of the power switches were reversed!
And, a large milestone -- the entire device can now be supplied from a single, inexpensive, and easily available (switching) brick supply instead of a series of expensive bench supplies. It took far more work than I'd expected, but it's wonderful to be in a working state.
Control Panel / Navigation Pad
The top of the scanner is about 8 inches in diameter. I've decided that, in addition to accessing and using the device over Wifi, it would also be useful to have a status display on the device itself showing the progress of the current scan, pictures of the latest slice, common settings, and so forth. Given the simplicity of the device, the user could even setup and initiate a scan from the control panel.
Keeping with the mantra of making everything either off-the-shelf or easily assembled, I've used an Adafruit OLED breakout and combined it with a wonderful navigation button pad I found after browsing through nearly every directional pad on Digikey.
Though not shown here, I've ported the OLED Framebuffer driver from the Arducorder (itself based on the Adafruit Arduino driver for this screen) to the Raspberry Pi. The display appears to work well, and I'm hoping that like the Hamamatsu Microspectrometer reference schematic and driver for the Arducorder, that this modular screen and navigation pad may be easily reused by other folks in their projects.
One issue that's come up is that this breakout board for the OLED screen appears to emit quite a bit of noise, and raises the baseline (noisy) number of counts on the detector array by a factor of three. I'll likely have to come up with a way of isolating this board, or placing some extra filtering on the detector array and microcontroller boards to mitigate this issue.
One of the small but critical aspects still remaining is that both the linear (Z) axis (above) and rotational axis for the table require end stops/limit switches. This is both for homing each axis before a scan, as well as preventing accidental over-travel on the Z axis.
Figuring out an ideal place to mount the limit switches required some thought. I'd initially thought of mounting them on the top/bottom plates, but this would require a fair amount of travel. I'd also considered mounting them directly on the carriage, but then they'd be in motion, and require a moving cable, which increases complexity. I finally settled on this much simpler solution -- a small 3D printed bracket that mounts to the Makerslide linear rail.
The business end of the limit switch fits beautifully inside the V-groove of the V-wheels on the carriage. Being mounted on the Makerslide also allows for very easy adjustment.
While the pictures above have omited a bit of the cabling for clarity, there are still one or two cabling issues left to resolve. These are largely centered around the moving carriage, and figuring out an ideal mounting pattern that allows the 6-8 inches of cable travel without fear of the cables becoming pinched during the motion.
The two cables on the carriage include the power cable for the detectors (plugged directly into the imaging array, above), and the FTDI USB->Serial cable that plugs directly into the Arduino Pro Mini on one end, and the USB hub on the other. This cable is rather -large, and not terribly flexible, so I'd like to find a shorter and lower-profile solution.
Table and Sample Container
The final major mechanical bit that needs designing is the sample container/rotational table mechanism. The placeholder that I quickly put together is above, which is simply a 3 inch diameter circle attached to the end of a long 8mm bolt coupled to the center stepper motor. A captive bearing in the center block supported by the nylon standoffs helps keep everything relatively aligned. While this supports whatever I place ontop of it, it's been more of a rough sketch rather than a final working unit.
Ultimately this system requires:
- A keyed table and sample container, that interlock when connected together.
- A limit switch, or other way of determining a 0 degree rotational reference for the table.
- A block of lead, or another heavy absorber, blocking the majority of emissions from the source. This will allow the carriage to park here at the bottom when not actively used (and during calibration runs), blocking all emissions from the source.
I've been designing a next-iteration of a laser cut the keyed/interlocking table and sample container, but an elegant way of mounting the homing switch for the rotational axis and the blocker for the source hasn't presented itself yet. Hopefully that will be the next major addition!
Thanks for reading! And stay tuned!