high speed particle sorting using fluorescence

Status
Not open for further replies.

srtr

Member
Hello PJRC forum! I just joined :)

I have a new project, and I'm considering using the Teensy 3.6. I don't have much experience with microcontrollers... could I get some help with feasibility/planning/design?

The project is to build a scientific instrument that sorts cells/particles based on fluorescence, detected using a microscope. These particles are suspended in liquid and are flowing rapidly through the optical path (0.1 to 1 kHz), where they get excited by a laser and emit fluorescence. The fluorescence is then picked up by three photon multiplier tubes (PMTs).

The Teensy picks up the signals from three PMTs, performs some analysis, and then decides whether that particle should be sorted or not. If the particle is not sorted, nothing happens. If the particle is sorted, the Teensy should output a waveform which is sent to a high-voltage amplifier (output up to 1 kV, max freq. 100 kHz). The HVA signal diverts the particles in mid-flow, performing the sorting action. (If you're curious how this works, the phenomenon is called "dielectrophoresis".)

A second job for the Teensy is to communicate with a computer via USB, with two purposes. First, the operator needs to be able to visualize the signal from the PMTs in real-time, or near real-time. Second, the operator needs to transfer to the Teensy the parameters required for sorting (thresholds, etc... more on this later) and those defining the output waveform (which is sent to the HVA).

Lastly, the third job for the Teensy is to control the gain of the PMTs (with a control voltage of 0.5 to max 1.1 V), which is again defined by the operator on the computer.

How does this sound so far?

Here are some key performance parameters:
- particles are sensed at a frequency of 0.1-1 kHz.
- the output from the PMTs is just a voltage, 0-5V. The sampling rate should be above 50 kHz (I think up to 500 kHz is ideal).
- the output signal to the HVA needs some flexibilty; it could be anything from 0.1-100 kHz, depending on the particles (since dielectrophoresis is frequency dependent). The HVA in put is 0 to +/- 10 V DC or peak AC.
- The operator should be able to visualize the signal waveform from the PMTs over a period of 10-50 ms.

OK, I think that's long enough for a first post.. I'll put together a follow-up with more details soon. As a first set of questions:
- Does this project look feasible with the Teensy 3.6?
- What method for communication with the computer should I use? (USB Serial or USB Raw HID?)
- Any other thoughts, questions, comments?

Many thanks!!
 
The sensor data rate should be achievable, probably even via polling. Driving the amp may get tricky, 100khz square waves are certainly possible, doing it as a since wave is more problematic, depends on what it needs. There are probably ways to abuse the SPI or i2C hardware to do this but from the sounds of the task sequence you can afford to have the code 'halt' while it produces the drive burst so pure bit banging may do it, at least as far as getting a proof of concept (and if all else fails add a second Teensy just for the transducer drive). Getting 100khz at +/-10 V will require some op amp design work, since the Teensy output is 0-3.3V. This amp driver is probably the most electrically complex part of the job so would suggest starting there with whatever micro controller you already have and make sure you can drive the power amp using your amp stage before getting into the code/buying major hardware.

Coms would be via USB serial unless you want to do a custom PC side driver.

Note that the Teensy 3.6 does not like inputs over 3.3V so you would need to manage any 5V inputs to avoid that.
 
Thanks GremlinWrangler

Actually, in this application the amplifier is typically driven with a square wave (lucky me). I'm not sure if that's because dielectrophoresis works better with square waves, or simply because it's easier to implement. (Previous implementations of similar systems that I am familiar with use FPGAs and LabView/Matlab on the PC. I think a microcontroller and a C++ program on the PC will perform better, hence the choice to try it with the Teensy.)

I'm not an electronics guy, so I don't think I can design the op amp myself... (any help here will be greatly appreciated!) For the time being, I will limit myself to the 0-3.3V output, since that should be enough to perform sorting in a few cases. After I get the whole system up and running I can come back to this and figure out how to get the full 0-10V range.

My priority now is the input signal processing, so I'm very glad you confirm that the sensor data should be achievable.

What pins on the Teensy 3.6 would be best suited for the three PMT inputs, the PMT gain control (0-1.1V), and the output signal to the HVA?
 
I also have some questions regarding my code design for the analysis. My preferred plan is as follows:

1. Put the PMT signals into a matrix of arbitrary width. This matrix updates at every sampling cycle, first-in-first-out.
2. The user defines a template matrix and sends it to the Teensy by USB serial.
3. Using matrix logic, compare the PMT signal and user template matrices at each cycle.
4. If step 3 results in a positive match, send a sorting pulse.

Does this sound like a good concept? In principle, does it look feasible on the Teensy?

Assuming this is feasible, are there any code suggestions for performing the signal acquisition of step 1 above?

EDIT - Just to clarify step 1:
The "PMT matrix" is arranged as follows.
- i vector corresponds to each PMT (0, 1, 2)
- j vector corresponds to PMT signal amplitude (say, a 12 bit number)
- k vector corresponds to time (if I sample at 50 kHz for 50 ms, k will have 2500 elements)

Taking the above parameters, the PMT matrix will be 3x12x2500. At each sampling cycle the whole matrix shifts to the right and the PMT sample (i, j) is entered at k=0.
 
Last edited:
Hmm, your matrix processing is going to be interesting. If I am understanding what you are doing that would be defined as an array of 3*2500*uin32_t which is 30k of 256k RAM. Depending on the logic defining as 16bit may save RAM but complicate other things. You can have arbitrary array sizes on microcontrollers but life will be far easier if you define a large but fixed one at compile time and then write your code to only use the part of it you want at at run time 'wasting' the remainder but keeping everything in fixed RAM space.

At 180mhz You have 3600 instructions per read at 50khz, so moving 3*2500 array items up by one is not going to work unless you can find some a hardware FIFO function. In fact you will not be able to process every cell every cycle. This may be why the previous solution used FPGAs, which can sweep 3*2500 memory locations for patterns much faster than even a 4Ghz CPU. You may need to do some work looking at how many instructions your pattern extraction process needs to run, and how often it actually needs to complete a pass through the memory space. If it can be implemented as running averages, or some other method that only proccesses new and stale data you have options.

This may require getting (or faking) same data and coming up with some test code in your favorite desktop C enviroment to filter it looking at number of commands per cycle.

Actually shuffling all your ram up one every cycle is also inefficient so you may need to run across the array using a pointer and doing your matrix logic across the wrap around.

The practicality is of course
 
Thanks again for your insight, GremlinWrangler. I like the suggestion to use a pointer to run across the array instead of shuffling.

Going back to the PMT inputs:

The PMT output is 0-4V (typo in original post said 5V), and I just read on the spec-sheet that the max output frequency is 20 kHz. What would be the appropriate sampling rate for the ADC? Previous implementations I've seen start at 40 kHz and go up from there. Does that sound reasonable?

Also, I'm trying to design the circuit to connect the PMT to the analog input in the Teensy. From my searching, it seems a voltage divider circuit is a standard way to do this. I found the following post on Stack Exchange:
https://electronics.stackexchange.c...-10v-analog-signal-to-0-to-2-5v-for-adc-input

Referring to point 3 in the top-rated answer... Do you think the capacitors would be necessary in my case?

Also, in designing the divider, it looks like I need to take into account the input impedance of the Teensy ADC. Paul addresses this briefly in this post:
https://forum.pjrc.com/threads/28722-Teensy-3-1-Analog-pin-ADC-impedance
It's not a simple resistance. There is a very small leakage current, which varies with temperature, and is not well specified. But that's not the main issue.

The input looks basically like a switch to a capacitor. When the ADC samples your signal, the switch connects, suddenly shorting the internal capacitance inside the chip to your signal. A current flows momentarily, to charge the capacitor to the same voltage (or close to the same voltage, if your signal has source impedance that causes a voltage drop between the true source and the internal ADC).

The internal capacitance is in the dozen pF range, and the switch on resistance is in the 1K range... approx.

So now I'm confused - how do I design the voltage divider so that I can get exactly 3.3V at the ADC? Don't I need to know the exact values of the load resistance and internal capacitance to design the divider properly?

EDIT: I found some data on the Teensy 3.6 data sheet (https://www.pjrc.com/teensy/K66P144M180SF5V2.pdf) page 45... Input capacitance C_ADIN = 8 pF (max 10 pF) and input resistance R_ADIN = 2 kOhm (max 5 kOhm). Is that the info I need to design my divider circuit? Either way, is there a way I can measure the exact values so that I can define the other resistors/capacitors in the divider accordingly?

EDIT AGAIN: After some further reading (https://forum.pjrc.com/threads/25532-ADC-library-update-now-with-support-for-Teensy-3-1) I found that the ADC uses a reference voltage for comparison... so I guess I don't need to produce exactly 3.3V_max with my divider - I just need to make sure it's under 3.3V... right?? And then for the V_ref, would I also pass a 4 V reference through an identical divider? How do I best match the PMT output V_max to V_ref so that I get the full range of bits during conversion?

On the PMT specification sheet, the testing data reported is for a load resistance of 1M and capacitance of 22 pF. Would it be a good idea (and possible?) to design the divider circuit to give this exact load resistance/capacitance?

Any specific circuit design suggestions?
 
Last edited:
Designing your circuit to approximate the 1M input impeadance will improve the precision of your measurements but unless you are really interested in the exact levels it is probably simpler to do a restive dividers that comes in under 3.3V from a 4V input and do some calibration when finished, you will probably find you need some form of background level detection anyway simply to deal with environmental effects.

Building a precise restive divider is hard, because resistors come in fixed sizes and normally are only 5-10% tolerance. So if this was some form if absolute instrument (say measuring mass) you would be sitting down with a pile of resistors and a high quality meter and pick out combinations that give you the values you need.

Similarly the circuit will work without the capacitor, but if you have a high input impedance you may find taking readings at a high rate produces errors over lower rates. Suggestion here is to try the recomended value, then quantify the results. You have the luxury here of building a one off instrument and tweaking till it works rather than having to design a mass produced item that can work under all circumstances. Main thing is to be aware of the potential for different results as you increase your sample rate, which otherwise is a real headscratcher of a 'it works fine when I test it' bug.

If absolute precision matters you would have an op-amp stage to impedance match the 1M output to the lower ADC impedance of the Teensy. given the final state here is to pattern match a signal as long as you get enough bits between your bright and dark levels the exact process does not matter.

A lot of this comes down to intentions. If the aim is to have a perfect instrument you need to outsource a whole bunch if instrument design work to someone who specilises in instrument design. If the aim is to learn stuff then a path that gets you a minimal viable instrument quickly that you add perfection to later may be better.
 
This brings back memories. In the early 1980's Flow Cytometry instrument's primary output was basically an oscilloscope screen. Researchers exchanged data by photographing the screen. I consulted for a small start-up company and designed an interface for the FACS machine, tapping into the inputs to the Oscilloscope. The signal ran through a buffer amplifier, a peak-detector, track-and-hold, and a 10-bit ADC. The data was sent over a ribbon cable to an original IBM PC (not XT or AT, the original PC). The interface had two 8K buffers, one the PC could read and the other the instrument wrote to. The PC swapped buffers as needed. We could handle about 20,000 samples a second on four channels. All the boards were wire-wrapped. Less than a dozen were sold before the company folded.
The biggest problem was the peak detector. Some cells have multiple peaks but my circuit only found the first one, not the highest. I tried various designs to improve the performance and eventually the company decided to use a much faster ADC and a digital comparator to find the peak. The new design allowed the hardware to do bit-map gating for the sorting. The PC just set parameters and retrieved the data, over a standard HPIB bus. The company folded before the new product reached the market.
 
Status
Not open for further replies.
Back
Top