Public Lab Research note

Updating the WheeTrometer: Code for running the CCD.

by JSummers |

Read more:


This research note is about driving a photodiode array (also called a charge capture device, or CCD) with the goal of developing an open-source spectrometer for science education. We hope to update the design of Ben Hickman's spectrometer, the WheeTrometer. Right now we are making pretty good progress and hope to have a pretty simple to use CCD / microcontroller / user interface before too long. One issue with the WheeTrometer is that the specified light sensor is no longer available. To address this, we are looking into the Toshiba TCD1304 charge capture device (CCD). This CCD is available from Mouser for about $25 ( and is used in spectrometers sold by a number of commercial sources, including Thor Labs, Ocean Optics, BWSpec and StellarNet.


Information on the TCD1304 is surprisingly hard to to get. The data on the Toshiba web site is total crap. The only way we have made progress is by following a series of posts by a guy named Esben Rossel who was able to get this running himself. The posts are found here. I thought Esben also published stuff under the name Flat Cat or Fl@C@, but apparently that is not him. Esben provides a link to the datasheet here. While it would be tempting to just copy Esben's work, he is running a Linux environment and uses a microcontroller that we are unfamiliar with (STM32F401RE nucleo). Since we run Windows and are more familiar with the TI products (specifically, the Tiva C LaunchPad, sold here for $13), we decided to go in that direction. I know that people will ask about doing this with Arduino. It has been a while since I worked in Arduino and even then I never got that involved in it. The upshot is that I don't know, but I doubt it would be possible to implement this stuff in the Arduino IDE. If you can't use the IDE, I don't see the point of using Arduino. If you still want to pursue this in Arduino, I recommend starting with the Due, not the Uno. Both the Due and the TI product have clock speed working for them. The CCD requires a pretty accurate clock running at between 0.8 and 2.4 MHz. Signals at two other pins (ICG and SH) must be synchronized with the clock at the start and finish of an acquisition. Timing requirements are described in the data sheet provided by Esben. While it may be possible to run the clock from the 16 MHz Uno, I think you will have trouble. The next question is ADC resolution. The TI product and the Due both have 12 bit ADCs. The TI ADC can acquire at 1 M samples per second. I have not seen the sample rate for the Due.

Anyway, ... This post introduces the goals of project and documents what we have learned about the firmware requirements so far. Until recently, my experience coding the microcontroller has been limited to the Energia IDE, which is very similar to the Arduino IDE. After it became apparent that this IDE would not allow us to control the microcontroller timing with sufficient timescale accuracy, we began learning the TI IDE (Code Composer Studio, available here for free). Mostly we followed the Tiva workshop labs. Code Composer Studio is a C based thing that is not intuitive if you don't know C, but allows pretty refined control.


We initially tried to run the clock using timer based interrupts, but the interrupts introduce unacceptable delays. We also tried toggling pins high and low with delays between. This also failed due to delays in the implementation.


I got on a TI online forum and described the issues we were having. The first guy responding suggested we use the PWM module to generate the clock, ICG and SH signals. That, it turns out, is a much better way of doing things. To establish the 1 MHz clock for the CCD, we set up the system clock at 80 MHz, the pwm clock at 10 MHz, set the PWM period at 10 clock cycles (1 microsecond) and set the duty cycle to 5 (half the clock period). We initially tried running the ICG and SH signals off of the pwm as well and that almost works. The problem with this approach is that all of the pwm generators share a clock and the pwm counter has a finite maximum period. It just covers too much space to have a clock with 100 ns resolution count up to tens of ms.
The next problem was to get the ICG signal synchronized with the CCD clock. We were unable to get this to work by just triggering the spectrometer after the delay. We were able to get around this by introducing a pwm based interrupt that increments a clock counter. When the clock counter hits a specified value, an initiation method is run that triggers the ICG and SH pulses. The initiation method has delays incorporated that align the initiation pulses with the clock pulses and constrain the total run time for the initiation sequence to be an integer multiple of the clock period. Since the initiation method is triggered by the pwm based interrupt, it is possible to keep the ICG and SH pulses synchronized with the CCD clock.
The figure below shows the output from the CCD read pin in the lower (blue) trace and the SH pulse on the upper (yellow) trace as read by my oscilloscope. For most of the output in this figure, the pixels are showing saturation behavior. image description


The initial code can be found in a folder titled ccd-test1 at our GitHub page ( You probably don't want the code yet but it is there if you do.


Well, first there is the issue of the ADC timing. Calling an analog to digital conversion in the software code introduces a time delay of several hundred nanoseconds and that is just not going to work. The documentation on the microcontroller says that you can trigger ADC on a timer, so that is probably the way to do it. There are also issues like (second) communicating with a host computer to write parameters to the microcontroller, (third) getting the data to the host computer and (fourth) writing the user interface code. It is also likely that we will want to (fifth) add an amplifier to the board. I think we have a pretty good start on most of these issues, but it will take a little time to get it all working.


I've found that the clock timing with the Toshiba arrays is not quite as rigorous as suggested in the datasheet (I've only tried it with the TCD1103). They can be run at a much slower clock rate which means you do not have to have a fast ADC. I have also been working with smaller arrays as I do not feel that getting anything more that 2 nm resolution is going to be desirable (or possible given limited and cheap optical components) and it means that the smaller amount of data can easily be stored in the RAM of a microprocessor. And yes you're correct the datasheets confuse rather than clarify many points regarding the timing of various pulses to the pins on the ccd.


@JSummers I find very interesting the way you drive the ccd, I do not understand the clock roll value, was it arbitrary or is it related to the integration time?

Kind Regards

Is this a question? Click here to post it to the Questions page.

Hi @iresal, you are correct about the clock roll value being related to the integration time. As the code is written, the integration time equals the clock roll in microseconds. To collect all the data, the value of clock roll has to be greater than or equal to four times the number of readable elements (4964). That makes the integration time about 15 ms. You can make the integration time longer by increasing the value of the clock roll. To get a shorter integration time requires some new code to employ the electronic shutter function of the ccd. Jack

Thank you for the mention :)

I should point out that I'm not FlatCat/Fl@C@ nor do I have anything to do with the RamanPi-project.

Dear @JSummers, thank for the reply. I assume you mean 3964 (instead of 4964) elements, and the 15 ms came from 4us (four times the clock ticks) x 3964 = 15.85 ms, the time needed to flush the ccd. I am probabaly misundestanding what you mean about integration time but in the code you states 4 ms for that, so which one is the time that the CCD is collecting ligth? 15 ms or 4 ms?

Thanks in advance, I have been trying to figure out these parameters in the datasheet, but perhaps I am stuck in a misunderstanding and Toshiba does not help.

I attach an small sketh I wrote to drive the CCD with Timers in PWM Mode, but for shorter Tint, in case someone find it useful. Thank you and @esbenrossel for sharing your work

Is this a question? Click here to post it to the Questions page.

Hi @iresal, The correct integration time is the 15 ms time. I think that is the minimum time to read the data from the output pin. The 4 ms value in the code is not ever used. I took a look at the main.c file in the code you reference. I am not sure that I understand how it works. I did not see how you drive the clock (phi M). It looks like you are using the main system clock at 80 MHz to run the SH and ICG pulses using PWM. Is that correct? It also looks like you are pulsing the SH pin at 400 microsecond intervals and the ICG pin at 40 ms intervals. If this is true, then you are asking the pwm counter to count up to 3.2 x 106. The reason I abandoned the pwm approach to pulsing the SH and ICG signals has to do with limitations on the counter in the pwm module (which I am using). This module will count to 65535 (16 bits). It looks like you are not using the pwm module. Since the timers can be configured for 32 bits, so you may not have that as a limitation. I do not know. Have you been able to hook this up to an oscilloscope and see it work? Best, Jack

Is this a question? Click here to post it to the Questions page.

Hi @JSummers, you are correct, I am pulsing the pins to these intervals,for the phi M I used other timer to generate the 1.4 Mhz signal (the 350 was meant for the adc), sorry for the comments in the code (many of them are incorrect due several debug sessions), I will update it in a GitHub repository asap. And yes, seems I do not have that problem because I am using the 32 bit Timer, but since I am interested in use the Ethernet capabilities with the 129xl board and I was not able to configure the Timers as I did with the 123 I wanna try your method, one last question, if I am not wrong I think you can increase the minimum time to read the data increasing the clock frequency to 2MHz, for example. And yes, I attach a picture of the signal I took with my code, upper signal is the ccd output with an inversor amplifier and below is the ccd output IMG_20180601_182232.jpg

In case you guys haven't already seen, Reim over at pjrc has written a driver for teensy using the arduino IDE:

how to make a kite for child? UJ

Is this a question? Click here to post it to the Questions page.

You must be logged in to comment.