Public Lab Research note

CCD Photodiode Array Spectrometer

by bhickman | October 12, 2013 00:23 | 21,504 views | 24 comments | #9442 | 21,504 views | 24 comments | #9442 12 Oct 00:23


The goal was to make an affordable spectrometer with a resolution that is comparable to some lower end commercially available spectrometers. The current design give approximately 0.6 nm wavelength resolution and around 12 bit intensity resolution.


The spectrometer is made from a Texas Instruments Stellaris LaunchPad microcontroller (programmed with Energia which is nearly identical to the Arduino IDE), a TSL1406R 768 X 1 element photodiode array (pda), a light source (white 5mm LED, or incandescent lamp), a 5mm LED holder, a collimating lens, a diffraction grating (1000 lines/mm), two project boxes, a wooden cuvette holder, and a wooded base as the optical platform. The total cost for all the parts was around $50. A general diagram of the setup is shown in Figure 1 and a more detailed diagram of the dimensions of the optical platform are shown in Figure 2.


Since making a spectrometer to read the UV range of light becomes prohibitively expensive, the target wavelength range for this spectrometer is 400 nm to 900 nm. In order to determine the geometry needed to accommodate this desired wavelength range the diffraction grating equation (Equation 1) was used. Where d is the distance between lines on the grating (0.001 mm/line), λ is the wavelength of interest being diffracted, θ is the diffraction angle of wavelength λ, and m is the order of diffraction (1 in this spectrometers design).


By solving the diffraction grating equating for θ (Equation 2), then using Equation 2 to find θ for the extreme wavelengths of interest (400nm and 900nm) the bounds of the system can be found. Plugging 400 nm into Equation 2 gives an angle of 23.58°, and plugging 900 nm into Equation 2 gives an angle of 64.16°.

Since the intensity of light decreases with distance, the distance of each photodiode should be as close to an equal distance from the diffraction gratin as possible. This further restricts the geometry of the system so that one edge of the photodiode is 23.58° from the grating’s normal a certain distance away from the grating, and that the other edge 64.16° from the grating’s normal the same distance from the grating. Using this fact, the grating’s length (1.93 in), the law of cosigns (Equation 3. d1 is the distance from the grating to the array and d2 is the length of the array), and the angles found above, the distance that each end of the photodiode should be from the grating is found to be 2.78 inches. A diagram with the angles and distances of the optical platform is shown in Figure 2.



I am using Energia to program a Texas Instruments Stellaris LaunchPad and Processing to make a GUI. The code is still very much in development but it currently offers some basic functionality.


Below are photos of the spectrometer using a 5mm white LED as the light source.

A small project box was used to house the light source,


A hole was drilled on one side to hold the LED. On the opposite side a hole was drilled for plastic collimating lens.


A cuvette holder was made by drilling a 1" hole through a block of wood (I know the hole for the cuvette should be square for absorbance measurements, but this was easier...). Then a smaller hole was drilled though the block for the light to pass though the sample.


A pice of black paper with a ~1mm slit was glued to the exit side of the cuvette holder. Then the 1000 lines/mm transmission grating was glued to the black paper.


The photodiodearray was mounted on a block of wood. Then the block of wood was secured into place so that the photodiodearray was aligned as best as cold be managed to the specifications shown in figure 2 above.


A hole was drilled in the cover of the larger project box so that it aligned with the hole in the cuvette holder.


Initial Data

The performance of the spectrometer was tested with a serial dilution of Nyquil (red type. Its all I had laying around...). This was done for both the white LED and an incandescent bulb as the light source.



Processing GUI screenshots

There is a lot that needs to be done to the GUI but it currently provides limited functionality.

Below is a screen shot of a water blank.


Below is a screen shot of the absorbance spectrum of approximately 10uM rhodamine B.


Stuff to do

Mathematically the spectrometer should operate in the 400-900 nm wavelength range. However a calibration needs to be done to get the exact wavelengths due to discrepancies between the theoretical and actual design.

I would like to use a halogen bulb as the light source, but the design need to be modified to handle the heat generated.

Develop a way to eliminate/reduce higher order light interference.


I didn't know you could buy a photodiode array for that little money. Fifty dollars for parts is a great deal. If there were explicit instructions for building and operating this type of thing I would be tempted. Is the photodiode array a single row CCD?

Does the software you use allow you to control exposure? Do you find the correct exposure by trial and error?

I have not heard of a spectrometer with the slit mashed up against the grating. Would it work better with some distance between them?

If you put a mirror at 45° into the cuvette hole, you could shine a fluorescent lamp in there for calibration. Although the light would not be collimated. It would work if there was some distance between the slit and grating.

Congrats on getting it working.

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

Reply to this comment...

I am working on a more detailed write up on how to make one of these. Also I am trying to figure out GitHub so I can upload the code I used on the Stellaris LaunchPad microcontroller.

The photodiode array is a single row (768 X 1 element). The software does allow some control over the integration time, but for the most part the exposure was figured out by trial and error and a little luck. If you notice, on the LED and incandescent raw output spectra, the maximum intensity is only 1000 and 2500 intensity units respectively. Ideally the maximum intensity would be around 4096 for the 12 bit analog to digital reading on the microcontroller, so there is still some more optimization to be done.

The distance between the slit and the grating is not something I have experimented with. This setup just seemed to work and allowed for a relatively rugged and compact design. I am definitely interested in ways to optimize the design without increasing to cost or complexity too much.

Reply to this comment... has detail about interfacing with a PIC

Reply to this comment...

Hi Dr. Brian I am sorry I have not posted my code yet but I have been trying to figure out GitHub. I think I am begin to understand GitHub and have posted the code I used to run the photodiode array here ( I am currently using Energia to program a Texas Instruments Stellaris LaunchPad as well as Processing to make a GUI.

Reply to this comment...

Wow, thanks for the interesting design. Just a comment, it looks like the photodiode array has a peak at 800nm and but continues to have some spectral sensitivity down to 1000nm, according to the specifications sheet here. By contrast, the white LED source is basically zeroed between 700 and 800nm, while by contrast incandescent lamps have high radiant flux far into the infrared . It looks like your components could be good for a spectrometer with a spectral range down to 1000nm--with the caveat that I don't know what are the spectral limitations of the your diffraction grating, and wasn't been able to find a source for this specification for the diffraction gratings I could find online, e.g. at Amazon

Reply to this comment...

Hi Taylor. Your right that the LED is limited in the wavelengths it emits. I have made another design that uses a halogen bulb which covers ~350nm to far in the IR region and has a long working life. The only drawback is the heat it produces. I am collaborating with Dr. Summers ( on improving the design and hope to have some stuff written up soon (a project at work has been slowing me down).

The diffraction grating I am using comes from here:

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

Reply to this comment...

great work... I am also thinking about building a spectrometer with linear ccd... however I scavenged the ccd from an old scanner and donot know anything about its pinout to interface with a pc... initial thoughts are to solve out the pinout and use an Arduino to interface with this ccd... I do not plan to invest anything into this as a "DIYer" and willing to find a way to get this thing work... there is a small mirror in front of the ccd inside the scanner which is already placed 45deg in front of it, I can mount a blank dvd piece as the grater as usual and test it like that if I can capture a single line with it... any help from you experienced makers is highly appreciated...

Reply to this comment...

Very good project! I also want to build up my own spectrometer for analysing LEDs. I want to use it with an arduino. Can you tell me how you connect it with the CCD array? Which Pins of the CCD array are needed?

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

Reply to this comment...

Hi MaikB85. Sorry for the late reply. I wired the TSL146RS CCD exactly how they suggest in the data sheet for serial operation. This requires a power, ground, two digital write, and one analog read pin. I believe the wiring diagram is on page 9 of the data sheet. If you need more info. then that just let me know.

Reply to this comment...

Hi I have problems get it working correctly. I tried your code with an Arduino MEGA 2560 (with changing the Pins in your code to mine). on the first run with using the Serial Monitor it seems to get valid values. Next run always get full 5V signal from all diodes. Anyone an idea why?

It also didn't accepts the values I type in Serial Monitor. Here is what I get when entering 50ms for Integration Time:

Mode (1:Absorbance, 2:Transmitance, 3:Series)


Intergration Time (ms)


Run Interval (sec)

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

Reply to this comment...

Get it working now :) The only problem was my setting for integration time. I have always chosen a to high value for that. And I tested it directly under daylight. It's very sensitive and I have to choose a very small value for integration time to not get the max voltage

Reply to this comment...

Hi MaikB85. Glad you got it working. Sorry the code I posted was messy. I need to clean the code up and re-post it when I get a chance. If you have any more trouble let me know and I'll try and help.

Reply to this comment...

Hi bhickman. I tried your code for my arduino uno. It worked, but GUI have a error ( the function "Controler(string)" is not exist.). And, if i want display on another GUI, such as labview, is it ok?and How?

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

Reply to this comment...

Hi dddnoob. The code on GitHub was only compatible with Processing 2, which I believe is the cause of the above error. I uploaded a folder to GitHub ( This folder has a Processing 3 compatible GUI. If you still have trouble with it just let me know.

As for a LabView or other GUI, I don't have one made right now. If you do have access to LabView it would be pretty easy to get a GUI working. You would simply have to set up a serial port to communicate with the microcontroller. Next you would have to send the run parameters to the microcontroller (mode and integration time), next send the go signal ( * ). After that the microcontroller will repeat back the run parameters. Once the parameters are repeated, the microcontroller send an "&" character to make the start of data, then it starts transmitting the raw CCD data. From there you would just have to parse the incoming serial feed and plot the data.

Reply to this comment...

Hi ddoob. If you follow the link on DigiKey ( to the data sheet, on page 17 there is a wiring diagram. For the spectrometer you will want to wire it according to the "Serial" schematic. Once the CCD is wired correctly, on page 13 of the data sheet there is a timing diagram. It may seem overwhelming at first, but its not too bad. The basic idea is you apply a clock pulse to one of the CCD's pins (CLK pin). To another pin (SI pin) you apply a pulse to start a acquiring new data as well as start reading the previous data on each pixel (AO pin), and to another pin you apply a pulse to stop the reading (SO pin). Does this help any?

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

Reply to this comment...

hey - i was wondering if I was the only one not being able to get the link to work


Reply to this comment...


Reply to this comment...


Reply to this comment...

I updated the link. Thanks.

Reply to this comment...

Dear bhickman, I have 2 questions: 1.How is resolution of the spectrometer? 2. Can you change resolution of this spectrometer?

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

Reply to this comment...

Hi ddnoob. I have not quantified the resolution, but by my estimate, the wavelength resolution is around 1nm when everything is optimized. The intensity resolution is set by the microcontroller you are using. If your using the Texas Instrument Tiva Launch Pad, like I am, then the intensity resolution is 12 bit.

If you want to increase the resolution there are a number of things you can do. First, use a narrower slit. This will decrease your signal intensity, but increase your resolution. Second, use a CCD with more elements. Using something like a Sony ILX511A CCD, which has 2048 pixels rather then the 768 the current CCD uses, will give you more pixels per wavelength hitting the CCD. Thirdly, you can use a grating that has more grove per inch. This will also increase your resolution, but with the cost of decreased signal intensity. To my knowledge these are the only ways to increase the resolution without redesigning the entire spectrometer. Hope this helps.

Reply to this comment...

Thank you very much, bhickman

Reply to this comment...

I found that you have 2 CCD Photodiode Array Spectrometer projects here and was wondering of the 2 which one would be better to work on


thanks and Marry Christmas/New Years

Reply to this comment...

Hi tekno. I would definitely go with the 3D printed version if thats available for you. The 3D printed version makes alignment much easier.

Reply to this comment...

Login to comment.