Table of Contents

EMB9B: Reading colour sensor

A colour sensor (TCS 34725) can detect the brightness and colour of the light emitted. It works with the I2C; in our laboratory, each sensor has a fixed 0x29 address in the I2C bus. The sensor is in the black enclosure, ensuring no ambient light impacts readings. The only light source is an RGB LED, controlled as described in the scenario EMB9A: Use of RGB LEDs. This is another LED connected parallel to the one you can observe in the camera.

Prerequisites

To implement this scenario, it is necessary to get familiar with at least one of the following scenarios first:

and obligatory:

A good understanding of the hardware timers is essential if you plan to use asynchronous programming (see note below). Consider getting familiar with the following:

To simplify TCS sensor use, we will use a dedicated library:

lib_deps = adafruit/Adafruit TCS34725@^1.4.2
Also, remember to add the LCD handling library, as present in the EMB9 scenario, unless you decide to use another output device.

Suggested Readings and Knowledge Resources

Hands-on Lab Scenario

Task to be implemented

Create a solution where you control an RGB LED and read its colour and brightness using a TCS sensor. Present results on the LCD, e.g. in the form of “Colour: <value>” where “value” refers to the colour intensity. You should change LED brightness at least 10 times (10 different brightness) for each colour while continuously reading the TCS sensor and presenting data in the LCD. Experiment with mixing colours and check either the sensor can distinguish brightness separately, when i.e. both RGD LED's colours are on: Red+Green or Red+Blue (or any other combination you wish).

There are at least two ways to handle this task:
  • simple: a dummy loop where you set RGB LED values, read from TCS and display on LCD,
  • advanced: where the data is read and presented on the LCD in one or two asynchronous routines run by timers.

Start

Check if you can see the LCD and RGB LED in the camera view.

Remember not to use the full brightness of the RGB LED because you won't be able to observe other elements due to the camera's low dynamics. Assuming you use 8-bit PWM to control LED, we suggest a range between 0 and 60 (eventually 0 and 100), but never up to 255.

Steps

In the steps below, we present only the part for reading from the TCS sensor. Control of RGB LED with PWM and handling LCD is presented in the other lab scenarios that you need to follow accordingly and merge with the code below.

Step 1

Included necessary libraries:

#include <Wire.h>
#include "Adafruit_TCS34725.h"

Step 2

Declare and instantiate TCS controller class and related variables for readings:

static Adafruit_TCS34725 tcs = Adafruit_TCS34725(TCS34725_INTEGRATIONTIME_300MS, TCS34725_GAIN_1X);
uint16_t r, g, b, c, colorTemp, lux;
static bool isTCSOk = false;

A word of explanation regarding the parameters:

Refer to the Q&A section for the ranges.

Step 3

Initialise the sensor (in void Setup()) and check it is OK:

  isTCSOk = tcs.begin();

You communicate with TCS sensor via I2C interface. In standard and typical configurations there is no need to instantiate Wire I2C communication stack explicitly, neither provide default I2C address of the TCS sensor (0x29) so begin is parameterless. Other overloaded functions for the begin let you provide all technical parameters.

Step 4

Besides reading raw values for channels R, G, B and C, the tcs controller class provides additional functions to calculate color temperature (in K) and color intensity in Luxes.

To read, use the following code:

  if(isTCSOk)
  {
    tcs.getRawData(&r, &g, &b, &c);
    colorTemp = tcs.calculateColorTemperature_dn40(r, g, b, c);
    lux = tcs.calculateLux(r, g, b);
  }

R, G, and B reflect filtered values for Red, Green and Blue, respectively, while C (clear) is a non-filtered read that reflects brightness. Please be aware that there is no straightforward relation between R, G, B and C channels.

Result validation

Driving R, G and B channels for RGB LED that lights the sensors, you should be able to observe changes in the readings, accordingly.

FAQ

What is the range of the values for the integration time of the TCS sensor?:

#define TCS34725_INTEGRATIONTIME_2_4MS                                         \
  (0xFF) /**< 2.4ms - 1 cycle - Max Count: 1024 */
#define TCS34725_INTEGRATIONTIME_24MS                                          \
  (0xF6) /**< 24.0ms - 10 cycles - Max Count: 10240 */
#define TCS34725_INTEGRATIONTIME_50MS                                          \
  (0xEB) /**< 50.4ms - 21 cycles - Max Count: 21504 */
#define TCS34725_INTEGRATIONTIME_60MS                                          \
  (0xE7) /**< 60.0ms - 25 cycles - Max Count: 25700 */
#define TCS34725_INTEGRATIONTIME_101MS                                         \
  (0xD6) /**< 100.8ms - 42 cycles - Max Count: 43008 */
#define TCS34725_INTEGRATIONTIME_120MS                                         \
  (0xCE) /**< 120.0ms - 50 cycles - Max Count: 51200 */
#define TCS34725_INTEGRATIONTIME_154MS                                         \
  (0xC0) /**< 153.6ms - 64 cycles - Max Count: 65535 */
#define TCS34725_INTEGRATIONTIME_180MS                                         \
  (0xB5) /**< 180.0ms - 75 cycles - Max Count: 65535 */
#define TCS34725_INTEGRATIONTIME_199MS                                         \
  (0xAD) /**< 199.2ms - 83 cycles - Max Count: 65535 */
#define TCS34725_INTEGRATIONTIME_240MS                                         \
  (0x9C) /**< 240.0ms - 100 cycles - Max Count: 65535 */
#define TCS34725_INTEGRATIONTIME_300MS                                         \
  (0x83) /**< 300.0ms - 125 cycles - Max Count: 65535 */
#define TCS34725_INTEGRATIONTIME_360MS                                         \
  (0x6A) /**< 360.0ms - 150 cycles - Max Count: 65535 */
#define TCS34725_INTEGRATIONTIME_401MS                                         \
  (0x59) /**< 400.8ms - 167 cycles - Max Count: 65535 */
#define TCS34725_INTEGRATIONTIME_420MS                                         \
  (0x51) /**< 420.0ms - 175 cycles - Max Count: 65535 */
#define TCS34725_INTEGRATIONTIME_480MS                                         \
  (0x38) /**< 480.0ms - 200 cycles - Max Count: 65535 */
#define TCS34725_INTEGRATIONTIME_499MS                                         \
  (0x30) /**< 499.2ms - 208 cycles - Max Count: 65535 */
#define TCS34725_INTEGRATIONTIME_540MS                                         \
  (0x1F) /**< 540.0ms - 225 cycles - Max Count: 65535 */
#define TCS34725_INTEGRATIONTIME_600MS                                         \
  (0x06) /**< 600.0ms - 250 cycles - Max Count: 65535 */
#define TCS34725_INTEGRATIONTIME_614MS                                         \
  (0x00) /**< 614.4ms - 256 cycles - Max Count: 65535 */

What is the range of the values for the gain of the TCS sensor?:

typedef enum {
  TCS34725_GAIN_1X = 0x00,  /*  No gain  */
  TCS34725_GAIN_4X = 0x01,  /*  4x gain  */
  TCS34725_GAIN_16X = 0x02, /*  16x gain */
  TCS34725_GAIN_60X = 0x03  /*  60x gain */
} tcs34725Gain_t;

C channel reading is 0 and R, G or B readings are not reasonable: It is possibly because overdrive of the sensor with a light source (too bright). Consider lowering the RGB LED's intensity or change sensor's integration time and gain (shorter time, lower gain).

Project information


This Intellectual Output was implemented under the Erasmus+ KA2.
Project IOT-OPEN.EU Reloaded – Education-based strengthening of the European universities, companies and labour force in the global IoT market.
Project number: 2022-1-PL01-KA220-HED-000085090.

Erasmus+ Disclaimer
This project has been funded with support from the European Commission.
This publication reflects the views of only the author, and the Commission cannot be held responsible for any use that may be made of the information contained therein.

Copyright Notice
This content was created by the IOT-OPEN.EU Reloaded consortium, 2022,2024.
The content is Copyrighted and distributed under CC BY-NC Creative Commons Licence, free for Non-Commercial use.