Arduino Spectroscope With TSL1401 and Display




Introduction: Arduino Spectroscope With TSL1401 and Display


I always loved the colours of light. When I saw a rainbow as a child I was fascinated from it. Now I'm still fascinated but in the meantime I know how a rainbow is being created. I also love to realise (complicated) physics project as simple as possible. Therefore I tried to make a spectroscope to examine different light sources.

There are a lot of commercial spectroscopes on the market f.e. from ocean optics (ocean optics iusb spectroscope). But first they aren't really cheap and second you always need a computer or laptop to visualize the spectra.

I tried to eliminate those two disadvantages by using the cheap line sensor TSL1401, an arduino mega and a 320x480 display, which immediately shows the results without any further computer. In other words I tried to build an all-in-one spectroscope.

Step 1: Parts You Will Need

For the DIY-spectroscope you don't need a lot of parts. The main parts including their prices are

  • TSL1401: 27 USD (ebay TSL1401)
  • Arduino Mega: 8 USD (ebay arduino mega)
  • 320x480 pixel display for arduino mega: 11 USD (ebay display)
  • 40 pcs. dupont wires male to female: 1 USD (ebay wires)
  • a 250x150x100 mm box: 12 USD (amazon case)
  • two achromatic lenses with a focal length of f = 39.5mm and f = 26.5mm from astromedia: 15 USD (astromedia lenses)
  • a 1000 lines/mm driffraction grating: 5 USD (ebay grating)
  • 10 kOhm potentiometer: 2 USD (ebay potentiometer)
  • 2 old razor blades
  • 9V/1A power supply
  • two component glue
  • corner braces for the lens- and grating mounts
  • some magnets for the positioning of the elements

Step 2: The Building

To find out the right positions for the slit, the grating, the lenses and the sensor isn't as simple as it sounds. Start with the entrance slit. The first lens with a focal length of f = 39.5 mm has to be fixed in a distance of f from the slit to produce parallel beams of light (a so colled colliminator). Closely behind the first lens put the diffraction grating. Then it's getting a bit more complicated. You will have to find out the correct position for the second lens with f = 26.5 mm and the sensor. For this step I recommend using a flashlight as a light source. Lighten the entrance slit with the torch and put the second lens in an angle of about 30-35 degree at one side behind the grating. Then position the TSL1401-sensor about 26.5 mm behind the lens. If everything works fine you will see a coloured spectra. To get it sharp I put a small line of black duct tape in the middle of the entrance slit. When you now move the sensor back and forth, you will find a position where you can see the sharp picture of the small duct tape hiding the line-sensor. But don't despair at this step, it's really tricky...

Maybe you'll have to take magnets to fix the position of the lenses and the sensor provisionally (look at the picture). If everything is in the right position you can glue the lenses to the corner braces and screw them tight on the bottom.

Step 3: The Software

For the TSL1401 you can find a working arduino-code and library in the internet:

With this program you can check the pixel-intensities and change the integration time with the arduino-command delay(...).

If this works fine you can try to visualize the intensities with the TFT-display. For this purpose we have to calibrate the spectrum to know the relationship between the pixel number i and the wavelength lamda in nanometer. And each pixel number corresponds with a RGB-colour triple.

For calibration you lighten the slit with a red (wavelength lambda = 642 nm), a green (lambda = 532 nm) and a bluray-laser pointer (lambda = 405 nm) and write down the sensor-number with the highest intensity.

For example you get the following values:

405 nm ...... sensor number i with the highest intensity = 8

532 nm ..... i = 60

642 nm ..... i = 108

Therefore a wavelength-width of 237 nm corresponds with a sensor-width of 108 - 8 = 100 pixels. To get the number/position of the pixels on the display you have to multiply the sensor-number with the factor 3. So 237 nm correspond with 100*3 = 300 pixels on the display or in other words 40 nm are equal to 50.6 pixels. These values you'll need in the arduino-program. My spectrum starts with 385 nm (i = 0) and ends with 385 + (128 * 3 / 50.6) * 40 = 689 nm (i = 128).

To find out which sensor-number i belongs to which colour you have my RGB-wavelength-function. For example if the sensor-number i is within the intervall [32,47] (= wavelength between 460 and 500 nm) the color can be calculated with the functions (for the 3 corresponding pixels)

tft.color565(255, 255 - int((255.0/16.0) * (i - 32)),0)

tft.color565(255, 255 - int((255.0/16.0) * (i - 32 + 1.0/3.0)),0)

tft.color565(255, 255 - int((255.0/16.0) * (i - 32 + 2.0/3.0)),0)

Notice that the value 255 means minimum brightness and 0 maximum brightness! So the red value is zero, the green value increases linearly and the blue value is at its maximum for i within [32,47].

To get a smoother intensity-graph I interpolate the 128 intensity-values always with 2 further pixels. So you finally get a spectrum with 128*3 = 384 pixels. The intensities of the pixels within the sensor-values are interpolated with a straight line (linear interpolation).

With the 10kOhm-potentiometer you can change the integration time between 0 and 256 ms. With this range you can also examine very dark light sources.

Step 4: Results

If you've managed the calibration and the right wavelength-scale you'll hopefully get similar spectra like those I got. For example you can examine the light of lasers. Their spectra consist of just one wavelength and therefore those sources are called monochromatic.

When you put a candle in front of the entrance slit, you'll get a different spectrum, a so called continously spectrum. The Planck-curve named after the german physician Max Planck shows the intensity of a light source having the temperature T. For T = 1400 K i calculated the planck-curve. It goes up with increasing wavelength. This does my achieved spectrum too. The spectrum of a white LED consists of many colours with a peak in the blue region. And last but not least you can see so called emission-lines of an energy-saving lamb.

I hope you learned something about making a simple arduino-spectrometer and it was at least interesting for you.

youtube-link of the TSL1401-spectrometer:

Maybe you want to take a look at my other physics-projects on youtube:

more physics projects:

Arduino Contest 2019

Participated in the
Arduino Contest 2019

Be the First to Share


    • For the Home Contest

      For the Home Contest
    • Make It Bridge

      Make It Bridge
    • Game Design: Student Design Challenge

      Game Design: Student Design Challenge



    3 years ago

    Excellent project, beautifully executed and one I will definitely try.
    I have a question which is why you do not appear to have mapped the sensor pixels to the display 480 pixel width?
    Results to be proud of!


    Reply 3 years ago

    Thank's and good luck with your spectroscope. 480/128 = 3.75. You need an integer-value, therefore I took 3 with one real sensor-value and 2 interpolated...


    3 years ago

    Excellent project and documentation. Does your device have the capability to save the spectra to a csv file?.


    Reply 3 years ago

    Hi! At the moment I don't have anything for saving the data but it's not really a problem to save the data as a csv-file (comma separated values) on f.e. a SD-card. For this you have to expand the spectrometer with an SD-card-arduino-shield...


    3 years ago on Step 4

    First of all, it is a very interesting and very useful project. Not sure i could repeate it, because of very accurate optics mechanics, but i will think about it.
    Have you tested modern LED light sorce with your spectroscope? I mean the one that have E27 socket.


    Reply 3 years ago

    Hi, thank's... No I haven't but i think that there would be no sigificant difference between the white LED I've tested and those from modern LED sources. But I can do that next time...