Introduction: A DIY Six-Color Transmitted-Light Spectrophotometer

About: Scientist working in in-vitro diagnostics industry. Playing with all types of sensor as a spare time hobby. Aiming for simple and inexpensive tools and projects for STEM, with a bit of science and a bit of sil…

The AS726X Spectral Sensors from AMS do allow six channel spectrophotometry for the visible (AS7262, 430 - 680 nm) and near infrared (AS7263, 580 - 880 nm) ranges of the spectrum. SparkFun is now offering breakout boards for both sensors, which are available via Pimoroni and RS-online.

In this configuration the AS7262 sensor comes with a white LED and can be used for reflected light spectrometry. All channels have a interference filter with a half-width of about 40 nm and maxima at 450 nm/V, 500 nm/B, 550 nm/G, 570 nm/Y, 600 nm/O, 650 nm/R. Be aware that the yellow chanel strongly overlaps with the green and orange chanels. The sensor AS7263 will focus on 610, 680, 730, 760, 810 and 860nm.

To demonstrate that the AS7262 sensor can be used for transmitted light spectrophotometry and for basic analytical applications, I have build a very simple spectrophotometric device. It basically consists of the sensor breakout, a white LED and a plastic frame, the latter with a slot to place plastic color filters into the light path. A set of colored plastic membranes were used to test sensor and device.

Then, based on the same basic layout, a device able to hold cuvettes was build. This allows to analyze colored solutions, as demonstrated below by a few examples.

The sensor breakout is connected to an Arduino via a 5.0 V -> 3.3 V level shifter, as this 3.3 V sensor must not be connected directly to the Arduino.

* Update Dec 2018: In the meantime, similar AS7262 sensor breakouts are also available from Adafruit, Pimoroni and others. If you like to use the sensor with a Raspberry Pi, you may use the AS726x CircuitPython code from Adafruit and Adafruit's Blinka library. With a Raspberry you won't need a level shifter, but make sure that you are driving the sensor with 3V. As Adafruit's breakout of the AS7262 comes with an integrated level shifter, you won't need an external one: Some additional information can be found there. *

A central limitation of the device is the light source. Unlike the sun or a light blub, white LEDs do not emit light with a homogenous intensity distribution throughout the spectrum. The emission spectrum of cool or natural white LEDs consists of a violet to blue peak and a broad bell-shaped emission with a maximum in the green-yellow range, in warm white LEDs the violet/blue peak is significantly weaker then the yellow signal (see images at the "Results" step). This is also reflected by the results of the corresponding blank measurements using such LEDs. If a more homogenous emission spectrum is required, you may have to use another light source such as a halogen lamp or a xenon flash. But as the aim here is just to measure the (relative) transluminescence, respectively light absorption, within each of the six channels, a LED should be sufficient for most purposes.

The sensor allows to set the data collection time in 1 to 255 folds of 2.8 milliseconds, to set the gain in several steps, and to define various measurement modes. It also allows measurement over a wide light intensity range. For transmitted light measurements I would suggest to set the sensor parameters such that none of the blank values will exceed 3/4 of the corresponding saturation values.

My aim was to integrate the six channel color sensor into a simple colorimetric measurement device, similar to the one I had described previously. But the AS7262 six color sensor may allow significantly more detailed measurements then the RGB sensor TCS34725 I had used before.

The devices might be used for educational or citizen science projects.

If you like to learn more about spectrophotometry and its applications, the Wikipedia article on the topic would be a good starting point.

Step 1: Filter Spectrophotometer: Materials and Setup

Materials used:

- SparkFun ASAX7262 breakout; 21 GBP at Pimoroni, UK

- XCSOURCE 4 channel bi-directional level shifter 3.3 <-> 5V, I2C friendly;
a comparable one is available from Adafruit at 4.50 GBP at Pimoroni

- Arduino Uno. I used a Monkmakesduino, but any type would do.

- Warm White LED, 5 mm, runs at 3 V; about 1.5 € at Conrad, Germany

- Jumper cables

- Halfsize breadboard

- two push buttons and a 10 kOhm resistor

- a battery holder for two 1.5V batteries (optional)

- A ROSCO Cinegel sample block of color filters. I had bought mine at Modulor, Berlin, a while ago.

- 3 mm and 2 mm Forex PVC foam plates; Modulor, Berlin, Germany

- Two 3 x 20 mm Nylon screws, two M3 nuts

- A piece of 10 mm Polystyrene/Styrofoam plate as socket

- some plastic glue


I soldered a header to the I2C ports of the breakout. As the sensor is a 3.3 V device, a level shifter is required to connect it to the 5V Arduino ports. If available, you also may use the Qwiik-adaptor headers from Sparkfun.

The pieces for the frame were cut from a 3 mm Forex plate, except for the plate with a slot for the filter strips, which what cut from a 2mm Forex plate. The plates were glued to each other as indicated and 3mm holes to fix the breakout and the light channel were drilled. The most difficult ones are the [ ] pieces that hold the break out, place with the breakout and adjust before gluing. For the LED, the hole at the LED holder was widened to 5 mm. The edges were trimmed and cleaned, and the unit was glued to the socket plate. The breakout was fixed to the frame with screws and nuts, then the LED was placed in the corresponding hole. Attached you find a svg-file with a drawing of the parts.

Then the cables were attached the sensor and the electronics were set up. I have slightly modified one of the scripts given as examples with the sensor breakout. You will find it attached. I also had placed two push buttons on the breadboard. One is the "B" button for blank values and the other the "M" button for the actual measurements. Both will evoke measurements and the results being sent to the serial console, with either a "B" or "M" as prefix.

You may power the LED from the 3.3V output of the Arduino, but my impression was that using batteries may give more stable results. As the measured signal intensity changes with time, I recommend to perform blank and colour measurements directly after another.

From the ROSCO Cinegel samples strips about 9-10 mm wide were cut. One nice thing about the filter samples is that they come each with a detailed absorption spectrum graph (see image), that can be compared with the six channel measurements.

The settings I have chosen were a gain of 1x, and a data collection time of about 250 x 2.8 ms (140ms), giving about 50,000 counts for the strongest channel, which is about 2/3 of the saturation signal. Needs to be optimized for different light sources.

For measurements at first blanks were taken pressing "B", then the filter is placed in the slot and measured pressing "M". Now measured values were transferred from the serial console to an Excel sheet and the blank/filter ratios of the six channels were calculated and displayed in bar graphs.

Step 2: Filter Spectrophotometer: Results and First Conclusions

Some results

The maximum blank values had been adjusted for the different light sources by modification of the corresponding parameter in the Arduino script.

Shown here are some of the measurement results, for blue, green, yellow and red filters.

As expected a blue filter weakens the yellow and orange signals very strongly, but the blue signal only slightly. In contrast, a red filter will block blue and green light, a green filter red light and a yellow filter blue and violett light (see images).

A natural white LED will have a strong signal in violett and a minimum in the blue/cyan range, whereas the warm white LED used for the color measurements shows a broad, bell-shaped spectrum with a weak violett signal.


Using this simple prototype, my first impressions indicate that the AS7262 breakout can be used for six-color transmitted light spectrophotometry.

Step 3: A Cuvette Version of the DIY Spectrophotometer

Using the same material and basic layout as described in the previous steps, a version of the spectrophotometer that can hold standard disposable photometric cuvettes was build. This shall allow to perform measurements of colored solutions, as color measurements of dyes or beverages, or pH determinations using appropriate indicator dyes.

The outer diameter of the cuvettes is 12.0 to 12.6 mm. They are available for about 10 € per 100 pieces, e.g. via Amazon. I have tested normal and half micro cuvettes, both were working well.

Attached you find a svg-file describing the parts. If you build one yourself, make sure that the opening of the sensor chip is placed in the center of the light path. Use a LED with a narrow emission angle and ensure its optimal positioning to illuminate the sensor.

I would recommend to glue the stack of layers that will hold the cuvette first, with a cuvette inserted, then add the outer layers, and finally drill the holes. Then add the sensor holding pieces, but adjust such that the sensor is perfectly places in the light path. Fix the pieces by gluing, then place and fix the LED holder. I used a 3mm screw for alignment of the elements. The edges were cleaned, then the frame was glued to the socket. Now the sensor was attached, aligned and fixed with two M3 screws and the LED added. The electronic parts and software were as described above.

Step 4: A 3D Printed Version of the Spectrophotometer

For all of you that would prefer a bit more professional, 3D printed version, a stl-file has been attached. Printing was about 16 Euro (without shipping) at i.materialise, Belgium. As the layout had been optimized for polyamide sinter printing, all three parts are connected by bridges. Just break them of and remove the bridges, then throughly remove all residual polyamide powder inside. Fix the sensor to the body with two 3mm screws and nuts, adjusting the position of the breakout such that you can see the hole in the sensor through the light channel. Then place the LED on the other side of the body and fix it with the back plate, using three 3 mm rods or screws to fix its position. I had cut the heads fron 20 mm 3M nylon screws and glued them into the appropriate holes.

The electronics are as described before. The lid had been found as to make not too much difference on the measured values.

Step 5: Cuvette Version: First Results

As an initial experiment to test the cuvette version of the DIY spectrophotometer, I measured the "spectra" of solutions of three food colorants. The red and faint yellow solutions were slightly turbid, the blue solution strongly colored. Above you find graph for the measured values, values normalized against blank values and the six color "spectra".

As a next step I prepared a serial 1:2 dilution of a solution of a blue ink and measured the dilutions and a blank. As you can see from the graphs, the sensor gives very nice quantitative values.

You can find the data in the attached Excel file.

This data may indicate that this quite simple and inexpensive device might be good enough to perform at least simple quantitative measurements and might be sufficient for citizen science or educational purposes.

Step 6: Arduino Script

As mentioned, the sensor was connected to the Arduino via a level shifter. The buttons are connected to the Arduino digital ports 2 and 4, and with ground via a 10kOhm resistor.

The script below is a rather crude modification of one of the excellent example scripts that are part of Spark Funs Arduino library for the sensor, with a lot of room for optimization. Any suggestions are welcome.

Attached you also can find the Excel file I used for calculation and display of results.

<p>#include "AS726X.h"<br>
AS726X sensor;</p><p>// constants won't change. They're used here to set pin numbers:
const int M_buttonPin = 2; // the number of the pushbutton pin measurement
const int B_buttonPin = 4; // the number of the pushbutton pin blank
const int intTime = 252; // 0 - 255 * 2.8 ms
const int ledPin = 13; // the number of the LED pin</p><p>
// variables will change:
int M_buttonState = 0; // variable for reading the pushbutton status M
int B_buttonState = 0; // variable for reading the pushbutton status A</p><p>
void setup() {
// initialize the LED pin as an output:
pinMode(ledPin, OUTPUT);
// initialize the pushbutton pin as an input:
pinMode(M_buttonPin, INPUT);
pinMode(B_buttonPin, INPUT);
</p><p>void loop() {
// read the state of the pushbutton value:
M_buttonState = digitalRead(M_buttonPin);
B_buttonState = digitalRead(B_buttonPin);

// check if the pushbutton is pressed. If it is, the buttonState is HIGH:
if ((M_buttonState == HIGH) or (B_buttonState == HIGH)) {
// turn LED on:
digitalWrite(ledPin, HIGH);
if (M_buttonState == HIGH) {
Serial.print("M value");
} else {
Serial.print("B value");



} else {
// turn LED off:
digitalWrite(ledPin, LOW);
LED Contest 2017

Participated in the
LED Contest 2017