Spectrophotometer design with a sensitive detector, bright light source and a sample holder. Easily and inexpensively built.

Similar projects worth following
Building on some good work by others ( and among others), this spectrophotometer has it's own bright light (White LED), and uses a lock-in amp and photodiode as a sensitive detector. A Teensy 3.1 is used as the controller and the interface to transfer data to a pc for further analysis. The LED is a high power white one chosen for it's broad light spectrum. The driver can be programmed (via a resistor) for varying power levels and the unit can be rapidly switched on and off for use with the lock-in amp. A piece from a DVD mounted on a servo motor creates the light spectrum that is moved past a slit, shines on the sample cuvette, and then on the photodiode.

Probably the first important detail is that I am currently travelling and can't get to all the design files (like schematics and board designs) that I intend to post for this project. Most of the pieces are working, but still have to be "packaged" and complete software for the Teensy 3.2 must be completed. Enough excuses, I'll try for some actual meat here.

Never mind! I'm home now and will add as much as I can in the remaining two days!

Actually, Teensy 3.0, 3.1, or 3.2 will work for this. Shown is a Teensy 3.0 because that's what I have handy.

Here is the cuvette holder which I designed in FreeCAD and 3D printed. The FreeCAD source and stl files are now attached.

Right now, the cuvette fits a bit snuggly, and the cap doesn't fit all the way down. Easily fixed by changing parameters in FreeCAD.

The lock-in amplifier, as shown above, (deserves some tutorial write-up, but wikipedia gives technical details) uses a newer part from Analog Devices, the ADA2200, as it's key component. A suitable photodiode and low-noise opamp (details to follow) complete the unit. This was originally designed for a fluorimeter, but will be used in the spectrophotometer first. A lock-in amp can be used in many other instruments as well, but let's focus. The Teensy is needed to configure the unit and gather the data from it to pass to a pc.

An Analog Devices AD8615 low-noise, low-offset opamp is used to amplify the output from the photodiode. The gain is programmable by changing the feedback resistor. Currently, I'm using a one meg resistor to provide one million x amplification. This is an area that will need tuning as the system is put into operation. Gains and losses throughout the system must be balanced for best performance.

The TLV431B provides the mid-range reference to the opamp. The system is designed for 3.3V, single-supply operation.

The 74LVC1G66 (note typo on schematic) is used to switch the LED that can be mounted on the Lock-In board. This LED was for initial testing only, but can be powered with 5 Volts. Switching is required to make the Lock-In amp work. The LED and the switch can be separated from the rest of the Lock-In if desired. Separation is best accomplished with a hack saw. Necessary signals can be jumpered using the holes provided.

The KiCAD schematic and pcb files are now attached. There is also a pdf of the schematic if you don't want to set up a KiCAD project. Please note that the guard around the sensitive input node is shown as a solid line in the pdf. This is misleading! It is shown as a proper dashed line in KiCAD.

A STCS2A from ST Microelectronics is the constant current LED driver. It can provide up to two amps, but can be programmed for less - important since the max for the LED I'm using is one amp. The current can be modulated with PWM so that the lock-in amp works properly. The circuit board is designed to mount on a heat sink. Power is supplied from a 5V wall wart.

A key component of a spectrophotometer is the light source. A little research turned up a paper (reference to be added) showing that bright white LEDs could provide the broad light spectrum needed. See the parts list (soon) for the LED, the heat sink board, and the lens that I selected. The lens focuses the LED output so that most of the light hits the diffraction grating to make the spectrum that is focused on the slit and then on the specimen being tested.

The bright light from the LED shines onto a diffraction grating to break into a spectrum (I'll try for a picture of it). An old DVD contributed a suitable grating. The servo moves the spectrum across a narrow slit to shine one color at a time on the sample being analyzed.

A sharp edged, narrow slit is formed by two razor blades. This slit can be considerably improved with a 3D printed adjustment mechanism. I'm working on that, but for the initial operation, this arrangement will do.

Here is a semi-helpful view of the system. The cardboard wall is to keep excessive light from hitting the sensor. You can see the...

Read more »


Here is the code for the actual pyqt GUI. Put it in the same directory as the code. Not in final form, but it works for testing.

x-designer - 2.78 kB - 10/03/2017 at 01:18


This is the Python code for running the Spectrophotometer. It runs on a Linux box, but can be easily modified to run with Windows. Only the command to open the serial port needs to change. This assumes that the LockIn_Spectro2.ino code is running on the Teensy. Not pretty, not final, but works for anyone who wants to play or just see the code.

x-python - 4.69 kB - 10/03/2017 at 01:15



This is the Arduino file for controlling the Teensy. This code is not well commented or especially pretty, but I provide it for those who really want to see how to control the ADA2200 and the other parts of the system.

ino - 11.28 kB - 10/03/2017 at 01:11



Slit Movable razor blade holder in FreeCAD format.

x-extension-fcstd - 71.32 kB - 01/06/2017 at 01:32



Slit Movable razor blade holder in stl format.

sla - 637.09 kB - 01/06/2017 at 01:31


View all 20 files

  • 1 × ADA2200 Synchronous Demodulator and Configurable Analog Filter Name says it all.
  • 1 × STCS2 Constant Current LED Driver LED driver that can have current level programmed and can be driven with PWM.

  • An Adjustable Slit

    doctek01/06/2017 at 01:40 0 comments

    As promised, I have created an adjustable slit for the spectrophotometer. This simple design still uses two single-edged razor blades, but makes one moveable so the width of the slit can be adjusted. Pegs on the blade holders are melted to hold the blades in place. A 3mm screw is used as the adjuster and a ball-point pen spring is used for tension. The left-hand blade holder and the screw mount are glued to the housing; the right-hand blade holder floats so the slit can be adjusted. I had to cut a groove in the floor of the housing to provide clearance for the new assembly. If you take the height of the assembly into account when you make your housing, this won't be necessary. (I'm just too lazy to make a new housing right now - maybe later?)

    The stl files are posted so you can make your own (just like the rest of this project!). The design files in FreeCAD format are also posted, in case you want to modify anything.

    Next step is to modify the control program and the data collection program to make use of the narrower slit. I'm thinking that using writeMicroseconds for fine control will work.

    As an aside, it occurs to me that the adjustable slit could be controlled with a stepper motor to provide variable resolution. A narrower slit and finer movement of the light source could be used in a region of interest, while a wider slit could be used elsewhere for faster data collection. Hmmmm.

  • Contributor Visits from Colombia

    doctek11/26/2016 at 23:19 0 comments

    The contributor on this project,[tucanae47], visited from Colombia. He was at the Hackaday conference in Pasadena and took a detour to visit Oceanside. How cool is that? What a terrific surprise. He got to see my multi-dollar lab and we nerded out over fish tacos at the beach. Adds a wonderful personal touch to our collaboration.

  • Lock-In Amplifier Design and Construction Details

    doctek09/12/2016 at 00:16 0 comments

    The Lock-in amp design is based around the ADA-2200 part. Other parts of the design provide signal conditioning of one form or another. The sensor is a photodiode, chosen (perhaps naively) for its low cost, availability, and broad light range (visible light spectrum). Since I'm experimenting and learning as I go, this seemed like a reasonable approach. The output of the photodiode feeds an AD8615 opamp configured as a current to voltage converter (transimpedance amplifier). Guarding is provided around the input to minimize noise. Note that the guard trace is tied to the common mode voltage, not to ground. The AD8615 opamp was chosen because of its very low offset voltage and low input bias current. In the configuration I'm using it has a gain of one million, but other gain values are possible with a change of the feedback resistor. Since the output of the opamp is single ended (0 to 3.3V), a TLV431B provides a 1.65V common mode voltage to center the signal. There is a footprint for a low pass filter in the path, but that hasn't been needed. The signal from the opamp is fed directly to the InP pin of the ADA2200.

    The ADA2200 requires a clock signal of 10KHz. This is provided by the Teensy3.0. The ADA2200 outputs an Rclk which is used to modulate the light source. For experimenting, I routed that signal to a 74LCV1G66 FET switch. In the current implementation, this signal routes to the PWM input of the LED driver. The ADA2200 also provides a Sync0 signal to drive an A/D converter to sample the ADA2200 output (the recovered signal). The Sync0 routes to an interrupt on the Teensy3.0 so it can do the sampling. The output of the ADA2200 is on VoutP and VoutN. These outputs can be sampled as either the raw signal, or after 10Hz LP filters. I am experimenting to see which signal is the most useful.

    My Lock-in Amp design includes an LED and drive circuitry for it. I intended this to be useful as an experiemental light source to stimulate the photodiode, snd it works for this. But I layed out the circuit board so that the LED could be removed. This takes a saw, but it can be removed. Indeed, the pictures of the spectrophotometer show it removed. Connectors P1 and P2 are not actually intended to be connectors (although they can be), but indicate where the Lock-In Amp and the LED circuitry can be separated. Use a hack saw to cut between these two connectors.

    The Lock-In Amp is designed to stand on edge so the photodiode can look directly at a light source, so the interconnects are in a row along one edge of the board. Right-angle gold square pin headers are used to mount the Lock-In Amp on a breadboard and eventually on a circuit board.

    The Teensy3.0 is used to program the ADA2200 via the SPI bus, to provide the 10KHz ClkIn signal, and to digitize the output as clocked by the SyncO signal. The software to do this has been created using the Arduino environment, so it's easy to understand and modify. The Teensy3.0, Teensy3.1, or Teensy3.2 can all be used. I used the Teensy3.0 simply because I had one and it did the job. I will make the software available on github. (TODO)

    The circuit board was designed using KiCAD and fabricated by OSHPark. (TODO: add OSHPark link to order board.) The parts list, with DigiKey part numbers, is posted above. I created a solder stencil using my Silhouette Portrait and 2.5 mil Mylalr. With the stencil, I put on solder paste, placed SMT parts, and used the Reflow Chateau oven to solder it. The through hole parts and the photodiode were added later. I couldn't convince myself that the photodiode would stand up to the reflow process, so I hand-soldered it.

    Future improvements:

    - Make the photodiode amplifier have a selectable range of gains. Plan is easy, god lives in the details - especially guarding the input.

    - The ADA2200 provides a common mode referrence signal to use to center the input (output of the opamp). I haven't tried using that.

    - There is a lot to know about the ADA2200! I have only scratched the surface and...

    Read more »

  • First Data Collection

    doctek08/09/2016 at 03:55 0 comments

    Here's the results from a bit of work with pyqt and pyqtgraph. The X axis is the angle of the diffraction grating as it sweeps the spectrum from red to blue. The Y axis is the response of the photodiode with higher values being less response.

    The bottom pair of lines in the plot are the calibration runs with plain water. The red line is a run using plain water, but through the translucent sides of the cuvette and shows a reduction in transmittance, but the same shape as the calibration runs. ("Calibration" here just means "reference" since I have no method of actually calibrating the device.) The other lines are the responses to various food colorings that I happened to have, and varying concentrations.

    I find these results very encouraging! Since I now believe this thing will actually work and may be very useful, I now plan to concentrate on getting the documentation into place so that others may duplicate the unit. Perhaps others may give me guidance on writing usable software for various applications.

  • Building a Control Interface

    doctek07/22/2016 at 22:06 0 comments

    Now that the basic hardware is working, I need to be able to collect and analyze data. While I considered using a graphics panel, and may yet do that, there are a lot of unknowns to sort out first. Seems that collecting the data with my lap top will be the most flexible way to do that.

    To that end, I'm developing a UI using Py-QT and pyserial. I considered using Processing because of its easy multi-platform capability, but python should fill the same role and has better tools for designing the interface. This effort will take a few weeks, I expect.

    Once I can easily capture and display data, I'll develop a calibration routine and evaluate the angular motion needed to sweep the spectrum appropriately.

  • New Black Enclosure

    doctek07/19/2016 at 04:01 0 comments

    Following are pictures of the new enclosure, It's made of black foam core board and has a black poster board cover. The goal is to keep out extraneous LED light. While I was at it, I mounted the cuvette holder onto the breadboard right in front of the photodiode. The cover has a lip on it to block light at the seams. Eventually, I will put tape or sealer around the edges to block as much light as possible.

    The cuvette holder is held in place with two-sided tape and a hole is cut in the cover for it. The lid blocks light from the LED, but could be improved if it were black.

    To test the enclosure, I put the grating at 27 degrees (mostly yellow light through the slot), filled the cuvette with plain water and collected 40 points. The average value was 1.03 volts. Then I put a drop of greenish-yellow food coloring in the water (partially blocking yellow) and read 1.22 volts. Next, I tried a drop of blue food coloring (which should block yellow effectively) and read 1.60 volts. Finally, I tried clear water again and read 1.03 volts.

    I find this pretty encouraging! Now I need to create a program for the pc that will sweep the LED and collect a sequence of data. Then I can try characterizing some samples.

  • Gathering Data Leads to New Structure

    doctek07/18/2016 at 04:06 0 comments

    Time to collect some data and let it guide development! I was using the setup shown in the earlier picture, and wanted to verify that I could still get a valid signal from the Lock-In Amp. Earlier experiments with a smaller LED showed things to be working.

    All the necessary functions are under control of the Teensy 3.0. The Lock-In Amp (ADA2200) needs both configuration and a clock. Configuration is done using the SPI port. The ADA2200 data sheet gives the codes for configuration. (The Arduino sketch for all of this will be attached.) The FrequencyTimer2 library is used to create a 10KHz clock.

    The ADA2200 will divide the 10KHz clock by 8 to get a Sample Clock and by 64 for the Reference Clock. The Reference Clock modulates the LED driver and the Sample Clock is fed back to the Teensy to trigger A/D sampling of the signal produced by the ADA2200.

    With all the signals hooked up, I tried collecting data. Nothing! The signal was at the maximum and nothing I could do would make it change!

    Time to get out the scope. Checking the clocks showed them all to be as expected. Probing the signal from the Lock-In Amp showed it to be pegged as expected. But then further probing made the expected signal appear. Seemed that just touching the Lock-In Amp board made the signal appear. WTFO?! At first I suspected that the capacitance of my finger was affecting things, but further tests showed this wasn't the case. To make a long story short, I realized that when I blocked light from the LED that wasn't coming through the slit, I got better results.

    And of course that makes perfect sense! Should of realized it much sooner. Any light from the LED that reaches the photodiode is sensed as signal! That's because it's modulated by the Reference Clock and measured by the Lock-In Amp as signal. That is, it's correlated noise - indistinguishable from noise. Experimenting further with a shield over the sensor showed significant improvement in getting a reasonable measurement.

    Time to build a new enclosure to properly shield the sensor!

View all 7 project logs

Enjoy this project?



jmsm357 wrote 02/16/2020 at 15:43 point

I see that these posts are pretty old, so I hope you're still working on this spectrometer project. I wanted to ask if you were aware of the TSL2591 light detector? I've been using this device with an old Jarrell-Ashe scanning spectrometer that I salvaged from a discarded instrument and I've recorded spectra for LEDs, Laser Pointers, LED Flashlights and some really unique Electrodeless Discharge Lamps (EDLs, which were once a valuable device in Atomic Absorption Spectrophotometry). The spectrometer I have was designed to operate from about 1900 Angstroms to around 9000 Angstroms and the recorded spectra show some great lines in the 6000 to 8000 Angstrom range (from the Argon and Krypton fill gas in the EDLs). I'm also using the PLX-DAQ Excel macro software to collect and plot the data. Just a few suggestions that might help you as well!

  Are you sure? yes | no

Andrej Mosat wrote 03/08/2018 at 22:55 point

When trying to quickly test the GUI, bunch of missing dependencies arrive. It would be helpful to package the running software into a can. Maybe docker container, any ideas? How do you fare with the project? 

  Are you sure? yes | no

doctek wrote 01/06/2017 at 05:28 point

This is a very valid concern, Brian. Please have a look at this paper (which I mentioned above, but never added the reference for). It shows clearly that a high-intensity white LED is a good source for visible light spectrometry.

Piasecki, T., Breadmore, M. C. and Macka, M. (2010), White LEDs as broad
spectrum light sources for spectrophotometry: Demonstration in the
visible spectrum range in a diode-array spectrophotometric detector.
ELECTROPHORESIS, 31: 3737–3744. doi: 10.1002/elps.201000341

Unfortunately, it is behind a paywall. You may be able to get it through a local library, or a friend in academia.

  Are you sure? yes | no

Brian wrote 01/06/2017 at 02:33 point

Have you looked at the spectrum from your LED source? I think you will find is not as useful as an incandescent source for spectroscopy, even though the LED intensity can be quite a bit higher. 

  Are you sure? yes | no

doctek wrote 07/22/2016 at 21:57 point

Thanks for the suggestion! I'm just now at the stage of evaluating the amount of rotation needed. Once I have a handle on that, I'll figure out how best to get it. May be that using writeMicroseconds() will do the job. If not, your suggestion sounds like a good one.

  Are you sure? yes | no

Neon22 wrote 07/22/2016 at 05:30 point

It might be an idea to gear down the drive from the servo to rotate the spectrum. You probably need less than 5 degrees of end motion and using the full 180 degree range from the servo would give you more control over the separation. Probbaly a 3D printed gear might be best. Always rewinding and only driving fwd would eliminate the backlash issues...

  Are you sure? yes | no

Similar Projects

Does this project spark your interest?

Become a member to follow this project and never miss any updates