These holiday lights change their color when you hold an object up to them.  A proximity sensor detects when an object is near, and a color sensor detects the object's color so the lights can change to match it--like a chameleon!


To build these lights you'll need the following parts:


First follow the guide for each component to assemble and test it:

Then wire up the components as shown below:

  • Connect power supply ground to 32u4 Feather ground, TCS34725 ground, VCNL4010 ground, and NeoPixel ground.
  • Connect power supply 5V to 32u4 Feather USB pin, TCS34725 VDD pin, VCNL4010 VIN pin, and NeoPixel +5V.
  • Connect 32u4 Feather SCL to TCS34725 SCL, VCNL4010 SCL.
  • Connect 32u4 Feather SDA to TCS34725 SDA, VCNL4010 SDA.
  • Connect 32u4 Feather pin 5 to TCS34725 LED pin.
  • Connect 32u4 Feather pin 6 to NeoPIxel signal input (Din).


Before loading the sketch make sure you have the following libraries installed.  Remember you can use the Arduino library manager to easily search for and install them:

Next download the sketch from its home on GitHub which contains five files under the Feather_32u4_Lights folder:

Click Download: Project Zip in the main code window below.

// SPDX-FileCopyrightText: 2019 Anne Barela for Adafruit Industries
// SPDX-License-Identifier: MIT

// Adafruit 32u4 Feather Color Sensing Holiday Lights
// See the full guide at:
// Author: Tony DiCola
// Released under a MIT license:
#include "Adafruit_NeoPixel.h"
#include "Adafruit_TCS34725.h"
#include "Adafruit_VCNL4000.h"
#include "Adafruit_VCNL4010.h"
#include "Wire.h"

#define PIXEL_COUNT 60    // The number of NeoPixels connected to the board.

#define PIXEL_PIN   6     // The pin connected to the input of the NeoPixels.

#define PIXEL_TYPE  NEO_GRB + NEO_KHZ800  // The type of NeoPixels, see the NeoPixel
                                          // strandtest example for more options.

#define ANIMATION_PERIOD_MS  300  // The amount of time (in milliseconds) that each
                                  // animation frame lasts.  Decrease this to speed
                                  // up the animation, and increase it to slow it down.

#define TCS_LED_PIN 5     // The digital pin connected to the TCS color sensor LED pin.
                          // Will control turning the sensor's LED on and off.

#define PROXIMITY_THRESHOLD  10000   // The threshold value to consider an object near
                                     // and attempt to read its color.  This is a good
                                     // default but you can modify it to fine tune your
                                     // setup (use the serial monitor to review what
                                     // proximity values you observe).

// Create NeoPixel strip from above parameters.
Adafruit_NeoPixel strip = Adafruit_NeoPixel(PIXEL_COUNT, PIXEL_PIN, PIXEL_TYPE);

// Create TCS color sensor object.
Adafruit_TCS34725 tcs = Adafruit_TCS34725(TCS34725_INTEGRATIONTIME_50MS, TCS34725_GAIN_4X);

// Create VCNL sensor object (defined in this sketch).
// If you're using a VCNL4010 sensor use this line:
Adafruit_VCNL4010 vcnl = Adafruit_VCNL4010();
// However if you're using a VCNL4000 sensor comment the above line and uncomment this one:
//Adafruit_VCNL4000 vcnl = Adafruit_VCNL4000();

// Build a gamma correction table for better color accuracy.
// Borrowed from TCS library examples.
uint8_t gammatable[256];

// Global variable to hold the current pixel color.  Starts out red but will be
// changed by color sensor.
int r = 255;
int g = 0;
int b = 0;

void setup() {
  Serial.println(F("Adafruit 32u4 Feather Color Sensing Holiday Lights"));

  // Setup TCS sensor LED pin as an output and turn off the LED.
  digitalWrite(TCS_LED_PIN, LOW);

  // Initialize NeoPixels.

  // Initialize TCS sensor library.
  if (tcs.begin()) {
    Serial.println("Found TCS sensor");
  else {
    Serial.println("No TCS34725 found ... check your connections");
    while (1);

  // Initialize VCNL sensor library.
  if (vcnl.begin()) {
    Serial.println("Found VNCL sensor");
  else {
    Serial.println("No VNCL found ... check your connections");
    while (1);

  // Generate gamma correction table.
  // Taken from TCS color sensor examples.
  for (int i=0; i<256; i++) {
    float x = i;
    x /= 255;
    x = pow(x, 2.5);
    x *= 255;
    gammatable[i] = x;      

void loop() {
  // Animate pixels.
  animatePixels(strip, r, g, b, 300);
  // Grab VCNL proximity measurement.
  uint16_t proximity = vcnl.readProximity();
  Serial.print("\t\tProximity = ");   

  // Take a TCS color sensor reading if an object is near (proximity measurement is larger than threshold).
  if (proximity > PROXIMITY_THRESHOLD) {
    // First turn on the LED and wait a bit for a good reading.
    digitalWrite(TCS_LED_PIN, HIGH);
    // Grab TCS color sensor reading.
    uint16_t raw_r, raw_g, raw_b, raw_c;
    tcs.getRawData(&raw_r, &raw_g, &raw_b, &raw_c);
    // Convert raw values to a value within 0...255, then run it through gamma correction curve.
    r = gammatable[(int)(((float)raw_r / (float)raw_c)*255.0)];
    g = gammatable[(int)(((float)raw_g / (float)raw_c)*255.0)];
    b = gammatable[(int)(((float)raw_b / (float)raw_c)*255.0)];
    // Print color value.
    Serial.print("R = ");
    Serial.print(" G = ");
    Serial.print(" B = ");
    // Turn off the LED.
    digitalWrite(TCS_LED_PIN, LOW);
    // Pause a bit to prevent constantly reading the color.

  // Small delay before looping.

void animatePixels(Adafruit_NeoPixel& strip, uint8_t r, uint8_t g, uint8_t b, int periodMS) {
  // Animate the NeoPixels with a simple theater chase/marquee animation.
  // Must provide a NeoPixel object, a color, and a period (in milliseconds) that controls how
  // long an animation frame will last.
  // First determine if it's an odd or even period.
  int mode = millis()/periodMS % 2;
  // Now light all the pixels and set odd and even pixels to different colors.
  // By alternating the odd/even pixel colors they'll appear to march along the strip.
  for (int i = 0; i < strip.numPixels(); ++i) {
    if (i%2 == mode) {
      strip.setPixelColor(i, r, g, b);  // Full bright color.
    else {
      strip.setPixelColor(i, r/4, g/4, b/4);  // Quarter intensity color.

Load the Feather_32u4_Lights sketch in the Arduino IDE.

Near the top of the sketch are #define values that you can adjust for your light configuration:

  • PIXEL_COUNT - Set this to the number of NeoPixels you're using.
  • PIXEL_PIN - Set this to the pin connected to the NeoPixel input (pin 6 if you followed the wiring).
  • PIXEL_TYPE - Set this to the type of NeoPixel.  Use the default unless you know you're using a different type of NeoPixel (see the strandtest example in the NeoPixel library for more information on types of NeoPixels).
  • ANIMATION_PERIOD_MS - This is the amount of time a single animation frame takes (in milliseconds).  Adjust this to slow down and speed up the animation.
  • TCS_LED_PIN - Set this to the digitial pin connected to the TCS color sensor LED pin (pin 5 if you followed the wiring).
  • PROXIMITY_THRESHOLD - This is the proximity value that's used to consider an object close enough to read its color with the TCS sensor.  You can tune this by looking at the serial monitor output to see the stream of proximity values and adjusting the threshold to be near the values you see when an object is near the sensor.

You can also adjust a part of the code depending on if you're using a VCNL4010 or older VCNL4000 proximity sensor:

// Create VCNL sensor object (defined in this sketch).
// If you're using a VCNL4010 sensor use this line:
Adafruit_VCNL4010 vcnl = Adafruit_VCNL4010();
// However if you're using a VCNL4000 sensor comment the above line and uncomment this one:
//Adafruit_VCNL4000 vcnl = Adafruit_VCNL4000();
Make sure only one of the lines above is uncommented, depending on what sensor you're using.

Now load the sketch on your hardware, then open the serial monitor at 115200 baud.  You should see proximity measurement values printed continuously to the console.  

Move a colored object right above the VCNL and TCS color sensor.  If the proximity value crosses the threshold the TCS sensor's LED will turn on and read the color of the object.  The sensor will wait about a second for you to remove the object, then the lights will start to animate using the color of the object.

Woo hoo, that's all there is to the 32u4 Feather Color Sensing Holiday Lights project!  This project is great for coloring lights on the tree using brightly wrapped gifts.

This guide was first published on Dec 22, 2015. It was last updated on Jul 16, 2024.

This page (Color Sensing Lights) was last updated on Jul 16, 2024.

Text editor powered by tinymce.