Help reading data from a linear photodiode array with a timing chart

Hello all,

I am currently working on a project trying to get fast readings from a linear photodiode array (Hamamatsu S4111-16) and its driver circuit (Hamamatsu C9004) using an Arduino. The ultimate goal is to get peaks from 16 channels then get the slope of those peaks, but right now I'm stuck on just getting the 16 channels of data in the first place. The timing chart is attached here:

Basically, I need to read 16 evenly spaced signals that occur once every 20 us and last for 10 us, then there is a break between sets of signals. Each set of readings from the sensor takes 360 us. (As a side note I tested out all of the timing with an Oscilloscope and they are all very stable and consistent to the timing chart above)

The current plan is to use digitalReadFast() (from the digitalWriteFast library) on the falling edge of the TRIG with an interrupt and storing it in a 16 wide array of double variables. Then in the time between the 16 channels being read out I would 'unpack' the array to be able to print it out (for now and later to put it on an SD card and/or take a linear regression and store the slope).

This seems reasonable to me, but then trying to keep those 16 variables together and resetting them with the START or END signals have proved challenging to wrap my head around. From what I understand you can't put a timer inside of an interrupt, so using the START signal as my interrupt beginning, then waiting an appropriate amount of time with micros() doesn't work.

Then on the other hand if I use TRIG as my trigger for the interrupt, how do I put the signal into the right position in the array without overwriting data?

Can I somehow use both inside of each other? Or is there a better way to use the internal timers on the Arduino (I know there's three and that I would have to use registers but got a bit overwhelmed when I couldn't find an example that had an inconsistent timer like I need. This definitely seems like a more elegant solution than layered interrupts but I need some more help to get there).

I do not have much of a background in 'actual' programming, so everything I've found online about clock and/or external interrupts has been slightly confusing and I may be misinterpreting it. Part of the problem is System.print is really slow so I haven't been able to print out my data iteratively to have an understanding of what's happening under the hood, so some suggestions about how to get readable intermediate data from this would also help.

Also, if the current frequency is simply too fast for the Arduino to handle I can slow down the driver circuit on the hardware side until I get a faster microcontroller, but I need this to run as quickly as possible in the meantime. Thanks in advance for any help!

You have picked quite a challenge for an Arduino beginner, and much more information is needed. People have much better luck getting help on this forum after reading and following the instructions in the "How to get the best out of this forum" post.

Forum members want to see data sheets for the parts (post links), a complete schematic diagram and the code, posted using code tags, plus a clear description of the problems encountered.

Although other photodiode arrays have been successfully used with Arduino, such as the TCD1304, no one seems to have posted related projects with the one you chose.

2 Likes

This doesn't make much sense. The output of digitalReadFast() is 0 or 1. You need an ADC to measure the voltage level output by the driver for each photodiode, and that will be much slower than digitalRead() of any flavor.

1 Like

Thank you for your replies. The link you sent looks pretty helpful, so I will try to implement that and come back with a better post if I still end up needing help. And that also makes sense for the digitalReadFast() command. I will try just using digitalRead() instead for now.

Just looking at the timing diagram you have presented, I'd say there are 3 signals which are important for this:

  1. /EOS: on the transition from high to low you store the data (16 element array), if any, from previous session and initialise the next session, setting the array index to zero etc.
  2. Trigger: On the falling edge you capture the analog value of signal_out in an array element and increment the array index in preparation for the next trigger. You'd do this in an interrupt service routine. You probably can't use analogRead() because it would be too slow. You might be able to use the ADC in free running mode and just take its value at this instant.
  3. Signal_out: analog value as mentioned above.

The timings are quite tight. You will probably not be able to print each batch of 16 samples as they occur. The SD card might work. You may have to do some low level configuration of the ADC. This will also depend on which Arduino board you choose.

That driver runs on 12V and the analog output (Vout) can be as high as 10V. High enough to destroy any Arduino. Are you taking precautions to protect the Arduino?

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.