Hamamatsu mini-spec Firmware could be faster if rewritten

I emailed Sashi from GroupGets, who wrote the current Arduino firmware for the spec, and he feels it could be rewritten to be faster. Here’s his response:

I would stick to using an arm based processor for reading the samples. You will have tweak the code to get optimal speed from the sensor, perhaps using the SPI hardware to get a speed boost. Getting a faster ADC will also help.
The code on the site is for Arduino, it is just a slow CPU and it is bit banged making it even slower. It works as a proof of concept, but for higher sampling rate, I would definitely rewite it.

I think a teensy would be a good choice to get the speeds you need.

If there’s someone out there willing to do some lower level library development to speed things up, that’d be super useful.

For proof of concept this isn’t required as we can just use fixed samples so a 20 second image time is not big deal, but in the long term it’d be good.

Had a nice discussion over email I wanted to repost here with Craig Versek, who’s worked with the module. Basically he felt we could speed up the delay (currently 1us down to 100ns), and had suggestions on the limits of what we can do with the ADC…

Perfect - yes speeding up the delay’s totally makes sense. That saves a ton of time! I’ll check out that code. Can I post most of this to the forum so that others can see it also? - it’ll be helpful information I think - perhaps we could continue the conversation there also.


The ADC library is useful - when we moved to a separate 4 channel 16 bit ADC I stopped paying attention to the teensy on-board ADC so I hadn’t seen that. Also, the differential mode may be useful…

A few thoughts:

One our current design, we have a +8V line for other reasons. That line is pretty rock solid. We would benefit from using that as a voltage reference line for the ADC’s right?

As you probably know, the Teensy’s default ADC reference is the 3.3V rail, but there is also an internal, more stable reference at 1.2V which can be configured in the ADC library. The AREF pin can be used for an external reference, but I believe 8V is too high and could cause damage (probably should be at or below 3.3V). Also, if you do have an external reference at AREF it needs to be a shunt type and not a power supply (see this thread). So you could possibly hang a shunt reference off this 8V line but I’m not sure it would be worth the expense - and if it’s being used to power motors or relays, then I would avoid that because of noise interference concerns.

I measured the max output of the microspec module directly which seemed to be around 4.5V if I am remembering correctly. I decided to be a little sloppy and just let the inputs clip to the 3.3V ref if the light intensity was too high, but sometimes you see people warning that damage can happen on ADC inputs above 3.6V - I haven’t seen it, but maybe it is slowly biasing some property? If you are worried about long term performance the output can be adjusted down with a voltage divider or even better an op amp attenuator circuit that would also hopefully lower the signal impedance and make quick sampling more accurate. Mind you, I haven’t checked out what the groupgets module outputs, because I don’t have one.

Also, since there are dual ADCs we could have two separate analog lines simultaneously (near simultaneously? If so how near?) sample the minispec. ’

This might be possible, but I don’t think sampling the same voltage simultaneously will improve the result much, since the most probable noise sources would likely correlate in time over the two closely located ADC channels. If you want more accuracy at the expense of speed, then set the automatic sample averaging feature of the ADC.

That would allow us to do some averages and improve the signal and maybe drop the speed. The ADC clock is 24 MHz (40ns) at 12 bit and 12 MHz at 16 bit, so that’s pretty fast, should allow for fast ADC reads I’d think!

Yes, especially if the firmware is programmed to reduce overhead between ADC readouts. For instance you could use a continuous sampling mode with DMA, but then we would need to figure out a way to synchronize it with the pixel clock-out.

I have indeed rewritten the GroupGets firmware for the C12880MA “microspec” to be faster and easier to configure independently of this project. My main goal was to enable shorter integration times so that even bright light sources wouldn’t saturate the microspec. You can find the (poorly documented) open source repo here: https://github.com/open-eio/arduino-microspec
The Arduino code is only optimized for the Teensy 3.x boards but should work at slower speed with most other Arduino compatible boards. The optimized clock half-pulse delay is close to 100ns which allows the processor to approach the 5MHz clocking limit of the microspec, yes still using the “bit-banging” approach. But in reading out the pixel values subsequently, the overhead of Arduino’s analogRead function was still a big time sink, taking ~3500 microseconds for the 288 pixels at 16-bit and about ~2200 us at 12-bit. In talking with @gbathree I decided it wouldn’t be too hard to optimize the ADC sampling phase further, so using Pedvide’s ADC library, which is optimized for the Teensy ecosystem, I was able to get the pixel readout to complete in a total of 360 us for 16-bit and 300 us for 12-bit, both using the minimal integration time of around ~30-40 microseconds. By using a continuous sampling mode you can avoid most of the overhead of single-shot ADC reads and you can further save time by clocking out the next pixel while the native ADC peripheral is performing the conversion in parallel (assuming the sampling of the current pixel has completed). In practice the ADC sampling and conversion times might need to be slowed down a little (or not) depending on how low impedance the microspec’s VIDEO pin source is, or whether it has been buffered with further circuitry. Also, you might need to use longer integration times in low light settings.


I used https://github.com/8bar/c12880ma (because mentioned @cversek repo: https://github.com/open-eio/arduino-microspec don’t work with Uno) and wrote a script (RStudio) for the reading Arduino Uno Serial port https://github.com/AndriyHz/Hamamatsu-u-Spectrometer-C12880MA.
But, need to change the delay (100) to the delay (1000) for the correct reading of the spectrometer data using RStudio.
void loop() {


Next step, changing Arduino Uno on Teensy or Arduino Nano, NodeMcu + https://github.com/open-eio/arduino-microspec.
Interesting. Will I receive the similar result? We will see.

1 Like

Awesome Andriy - way to make progress! I’m in the thick of some work, but now that we know there’s no funding for GOSH Nodes, I’m putting some effort into getting a single pixel camera event organized here. I know I can get the space and place fairly cheap, then we just need funding for flights and some reimbursement.

I expect to post in the next month regarding this.