Introduction: Light and Color Measurements With the Pimoroni Enviro:bit for the Micro:bit

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…

I had been working on some devices that allow light and color measurements previously and you may find a lot about the theory behind such measurements the instructables here and here.

Pimoroni has recently released the enviro:bit, an add-on for the micro:bit, that comes with a MEMS microphone for sound level measurements, a BME280 temperature/humidity/air pressure sensor and a TCS3475 light and color sensor (RGBC). In addition there are two LEDs placed on the sides of the color sensor, allowing to measure the color of objects by reflected light. Building a tool yourself to perform these measurements has never been easier.

I here would like to describe how the enviro:bit can be used for color and light measurements and the MakeCode script that allow to perform these. The combination of micro:bit and enviro:bit is a nice and inexpensive device to demonstrate the principles of scientific measurements hands-on and play with them.


This instructable is part of the "Rainbow" contest. If you like it, please give it your vote.


Step 1: Materials Used

Micro:bit, 13 GBP at Pimoroni.

Pimoroni Enviro:bit, 20 GBP at Pimoroni.

Pimoroni Power:bit, 6 GBP at Piomoroni. You also may use battery packs or a LiPo for the micro:bit

Rosco Cinegel color filter sample block. I got mine from Modulor, Berlin.

IKEA colored plastic cups. IKEA, Berlin.

Wild flowers. A meadow at Potsdam-Golm.

Step 2: The MakeCode/JavaScript Script

Pimoroni has developed a library for the Enviro:bit, both for the MakeCode/JavaScript coding environment and for MicroPython. I here have used MakeCode, as the scripts can be uploaded directly to the micro:bit and allows block coding.

The script reads the values of the red, green and blue (RGB) and the clear (C) channels. The firsts are given in values from 0 to 255, the second in the whole range from 0 to about 61000.

The range of the clear channel is very wide and allows measurements from bright daylight to a dark room.

By now I don't understand all the details of the color measurement function, but I assume that they have some correction and normalisation mechanisms implemented.

At first, the values of all four channels are taken. To be able to display the results on the 5x5 LED matrix, measured values are used to place the results in 5 (RGB) or 10 (C) bins, that are represented by one LED in either one (R, G, B) or two (C) rows.

In the case of RGB, the scaling is linear and the interval size of each bin is 51 units wide.
In the case of C, the scaling is logarithmic over 10 steps (log3, so every step is the 3-fold of the previous). This allows to display very dim and very bright conditions alike.

Pressing button A displays the R, G and B values in numbers, pressing B the C value.
A+B activates the LEDs and B will shut them down.

let bR = 0 // bins
let bG = 0
let bB = 0
let bS = 0
let bC = 0
let bCx = 0
let S = 0  // measured values
let C = 0
let B = 0 
let G = 0
let R = 0
basic.forever(() => {
    if (input.buttonIsPressed(Button.AB)) {
    } else if (input.buttonIsPressed(Button.A)) {
        basic.showString("R: " + R + " G: " + G + " B: " + B)
    } else if (input.buttonIsPressed(Button.B)) {
        basic.showString("C: " + C)
    } else {
        R = envirobit.getRed()
        G = envirobit.getGreen()
        B = envirobit.getBlue()
        C = envirobit.getLight()
        bC = 5
        bCx = 5
        if (R >= 204) {      // binning, max 255
            bR = 4
        } else if (R >= 153) {
            bR = 3
        } else if (R >= 102) {
            bR = 2
        } else if (R >= 51) {
            bR = 1
        } else {
            bR = 0
        if (G >= 204) {
            bG = 4
        } else if (G >= 153) {
            bG = 3
        } else if (G >= 102) {
            bG = 2
        } else if (G >= 51) {
            bG = 1
        } else {
            bG = 0
        if (B >= 204) {
            bB = 4
        } else if (B >= 153) {
            bB = 3
        } else if (B >= 102) {
            bB = 2
        } else if (B >= 51) {
            bB = 1
        } else {
            bB = 0
        if (C >= 60000) {         // Saturation
            bCx = 4
        } else if (C >= 20000) {
            bCx = 3
        } else if (C >= 6600) {
            bCx = 2
        } else if (C >= 2200) {
            bCx = 1
        } else if (C >= 729) {
            bCx = 0
        } else if (C >= 243) {
            bC = 4
        } else if (C >= 81) {
            bC = 3
        } else if (C >= 27) {
            bC = 2
        } else if (C >= 9) {
            bC = 1
        } else {
            bC = 0
        // write to led
        if (bCx < 5) {
            led.plot(1, bCx)
        } else {
            led.plot(0, bC)
        led.plot(2, bR)
        led.plot(3, bG)
        led.plot(4, bB)

Step 3: Taking RGB Measurements: Transmitted Light Mode

As indicated before, there are two modes of color measurements: transmitted and reflected light spectroscopy. In the transmitted light mode, light goes through a colored filter or solution to the sensor. In reflected light measurements, light emitted e.g. from the LEDs is reflected by an object and is detected by the sensor.

The RGB values are then displayed in the 3rd to 5th rows of the micro:bit 5x5 LED matrix, with the upper LEDs representing low, the lower LEDs the high values.

For the experiments shown here on transmitted light measurements I used daylight and placed colored filters from a Rosco sample pack in front of the sensor. You can see the effects on the display, especially in the red channel. Have a look on the pictures and compare the patterns.

To read the actual values, just press button A.

Step 4: Reflected Light RGB, and Brightness Measurements

For reflected light measurements I turned on the LEDs (button [A+B]) and placed some brightly colored pieces of IKEA children cups in front of the sensor. As can be seen from the pictures, the RGB values are changing as expected.

For brightness measurements, low values are displayed in the first, high values in the second row. Low values in the upper, higher values by the lower LEDs. To read the precise value, press button B.

Step 5: Reflected Light Measurements: Flowers

I picked some wild flowers from a meadow and tried to perform some color measurements on them.
Its been poppy, cornflower, brown knapweed, wall harkweed and a dilandelon leaf.

The RGB values were [R, G, B]:

  • none [92, 100, 105]
  • poppy (red) [208, 98, 99]
  • cornflower (blue) [93, 96, 138]
  • brown knapweed (lilac) [122, 97, 133]
  • wall harkweed (yellow) [144, 109, 63]
  • dandelon leaf (green) [164, 144, 124]

Which fits to the expectations, at least for the first three plants.
To display the colors from the values, you may use a color calculator, as the one here.

Colors of the Rainbow Contest

Participated in the
Colors of the Rainbow Contest