Building a photon counter for double slit experiment

Status
Not open for further replies.

alishvadsariya

New member
Hey everyone I'm a 3rd year physics student currently on an internship at a Quantum research facility. My supervisor told me to build a program to detect and count photons using an Arduino Uno or Due and a id100 single photon detection module. The frequency of the photons can range for 10Hz to a 1,000,000Hz.

The photons should be detected when the voltage is spiked. The voltage when the photon is not detected can fluctuate from like 0 to 0.5. And when the photon is detected it might not be a proper square could be more like a parabola.
Screenshot 2021-09-13 150355.png


I've never used Arduinos before so I am a bit lost, would appreciate if i can get some advice:


1) first can the photons be detected and counted?
2) How big will the error percentage be?
3) Can someone help me with getting started with the code, I would really appreciate it?


I know it might be a lot to ask, but this project seems really interesting and would love to actually make it work. Thank you.
 
Sounds interesting indeed. Your detector generates 50ns pulses which should be long enough to trigger a pin interrupt. Voltage ranges also look OK. I'd consider to not directly connect the teensy to the detector but use a fast buffer in between. The SN74LVCXXX should be fast enough and work at 3.3V.

The interrupt latency and your processing will most probably prolong the dead time of the system. Thus, you might not be able to get to the full counting rate of the detector but that is probably not a problem for a double slit experiment. You need to understand that your count rate will go down for high frequencies since the pulses will start to overlap. And, you don't need a lot of light to get very high count rates :) Can be confusing if you never worked with those detectors...
 
Can you explain why would i need a fast buffer? Also will the code look similar to something like a pulse detector, or do I have to analyse the output voltage?

Thank you for helping.
 
Sounds like a fun project, although I am not sure how much help I would be. Also you mention using either Arduino Uno or Due and neither of these are PJRC products.

I also don't know anything about those sensors. Can not tell from it's brochure what type of output it gives you. Does it simply give you some analog output. You mention .5 (Volts I assume), but the page I looked at sort of sounded like 2V...

Also I am not much of an Analog person... So not sure of best way to detect. electrically wise, do you need to put in some for of amplifier to get it up into the 3.3v range or 5v range for Uno.
Should you detect by Analog voltages or can you detect by edges with digital...

So hopefully someone else here can give you some better advice..

Good luck
 
Can you explain why would i need a fast buffer?
Maybe I'm over cautious but one never knows what spikes are on such signals. I'd rather destroy a cheap buffer than the expensive controller.

Also will the code look similar to something like a pulse detector, or do I have to analyse the output voltage?
I'd simply count the pulses for a start. I don't see a reason to analyze the signal. If you need to discriminate dark counts (which I doubt) one usually uses an analog comparator which only passes pulses in a certain amplitude range. (low amplitude pulses often come from thermal electrons, high amplitude pulses from cosmic rays). But I assume that this is already integrated in the detector (carefully read the datasheet of course). They claim a 7cts/s dark count rate which is pretty good already.
 
From the ID100 brochure, I see on page 3 this output signal:

Capture.PNG

That looks to me as a 10ns wide pulse with a 2V amplitude.
So it needs pulse stretching if you want to use the FreqCount library [minimum pulse width 50ns] and perhaps amplification/damping. The module outputs 2V in (presumably) 50Ω. Not sure about the output level with a high impedance load.

Paul
 
Yup you're right about the 10ns wide pulse with the 2V amplitude. If i get the pulse width to about 50ns will it be possible to measure upto 100,000 Hz, with high precision?
 
Check out the FreqCount library.
The biggest hurdle is probably signal conditioning. Once that is done, counting the pulses is relatively straightforward.

Paul
 
I was interested if the T4 is able to count 10ns pulses. According to the measurements shown here: https://forum.pjrc.com/threads/57185-Teensy-4-0-Bitbang-FAST?p=212248&viewfull=1#post212248 a simple

Code:
digitalWriteFast(pin, HIGH);
digitalWriteFast(pin, LOW);

should generate a < 10ns pulse. I connected pin0 with pin1, generated 50000 randomly spaced pulses and had an interrupt on pin1 count the incoming pulses.

Code:
uint32_t count = 0;

void setup()
{
    while (!Serial) {}

    pinMode(0, OUTPUT);
    attachInterrupt(1, [] { count++; }, RISING); // attach interrupt to pin1, increment counter in ISR (connect pin 0 and pin 1 with a cable)

    for (int i = 0; i < 50'000; i++)  // generate 50k pulses
    {
        digitalWriteFast(0, HIGH);
        digitalWriteFast(0, LOW);
        delayMicroseconds(random(1, 100));
    }

    Serial.println(count);
}

void loop()
{
}

It prints exactly 50'000. So, I assume that the T4 should be fast enough to count the pulses.

The biggest hurdle is probably signal conditioning.
Yes, 10ns pulses might be difficult. On the other hand, if you have access to the detector, why not simply give it a try :). As mentioned above, I'd go for a 74LVCXX (or another fast) buffer to protect the Teensy and bring the signal to 3.3V but this is probably not necessary.

will it be possible to measure upto 100,000 Hz, with high precision?
The photons will arrive at the detector statistically. So, the maximal possible precision depends on the number of counted photons. If you count N pulses you'll get a standard deviation of sqrt(N) which gives a precision (cv) of sqrt(N)/N = 1/sqrt(N). Thus, for an ideal detector you'd expect a cv of 1/sqrt(100000) = 0.3%. For 100 pulses you'd get a cv of 10%. So, as usual, precision depends on measurement time.

Real detectors always have a dead time which will lead to non linear count rates (if pulses arrive during the dead time they can't be counted). You can estimate this by the following formula:

N=M/(1-M x td) (see https://www.hamamatsu.com/resources/pdf/etd/PMT_handbook_v3aE.pdf chapter 6)

where N is the real count rate, M is the measured count rate and td is the dead time. The data sheet states 50ns dead time for the sensor. Thus, if you see 100'000 cts/s you'll have a real count rate of N = 100'000/(1-100'000 x 50E-9) = 100'500. Which is 0.5% off. However, the teensy also introduces some dead time since it can not detect another interrupt while it handles the first. I estimate that the total dead time will be more like 500ns you get 100000/(1-100'000 x 500E-9) which corresponds to about 5% error. Still very good. In case you want/need to use the formula to linearize your measurement you should make some test to find out the correct dead time.


Hope that helps
 
For the record, I'm not a sales person for PJRC, but I highly recommend dumping Arduino and moving to a Teensy (4.0 or so). Ignoring read speeds, If you want to add a display for displaying details and readings, and add and SD card, you may run out of memory. I dumped Arduinos years ago for this very reason.

Stick with the fastest and best MCU

Keep us posted, this looks like a cool project.
 
My supervisor told me to build a program to detect and count photons using an Arduino Uno or Due and a id100 single photon detection module.
He might not be able to. but should try to prove to his supervisor that it is a good idea to swap to teensy.
 
attachInterrupt(1, [] { count++; }, RISING);

Hi Luni, thanks for your code. Wasn't aware of declaring an interrupt function this way. How did you get to know this? I googled for it but could not find anything about declaring it this way.

Paul
 
Wasn't aware of declaring an interrupt function this way
You need to google for "lambda expression". They come in handy for such short functions and usually give the compiler more optimizing options (if you call a function through a function pointer the compiler usually can't 'see' the function definition) Here some tricks you can do with lambdas: https://github.com/TeensyUser/doc/wiki/callbacks
 
Just curious, doesn't the variable [in your case count++] need to be defined as volatile?

That's definitely correct, thanks for spotting it. Without volatile, the compiler can assume that nothing was ever written to 'count' and could optimize the reading in 'println(count)' away. In this case it (luckily) didn't. I re-tested with declaring count volatile but the result is the same (it catches all 50k pulses).
 
Status
Not open for further replies.
Back
Top