Interactive Touchless Light Using Arduino

Interactive Touchless Light (1)

Hi everyone! I’d like to share the project I have been working on here. I got inspired to experiment with capacitive touch sensing through a project in my university. I found out about this technology through instructables and used the things I learned here and from other places on the internet to build my own touch-less controller, which I use to blend different RGB values to create interesting light colors.Interactive Touchless Light (1)

For starters, when I started this project I knew next to nothing about either electronics nor capacitive touch sensing.

Some problems I ran in to early on were caused by misunderstanding what actually happens. So a short introduction from how I understand it:

A capacitive sensor uses multiple components, mainly:

A capacitor (in this project we use aluminium foil, but its also possible to use conductive fluids etc),

wires (ofcourse, its electronics)

and a resistor, anything under 10 MOhm is too small a resistance for more than direct touch.

the way it works is by measuring a difference in time between point A and point B. From the start pin it sends a signal to an endpin, the time it takes is measured with a timer. By decreasing the resistance value (by moving a capacitor (in this case your hand) closer to the capacitor of the sensor(the aluminium foil) this time shortens, the difference in time is what the sensor gives back as a value.

Due to the sensor being affected by capacitive surfaces the data can be wildly erratic due to interference. This can be solved for a large part by correctly insulating the capacitor and also by using a ground (I will show how later on) .

So now that is out of the way we can start inventorying all the stuff we need:

Step 1: What Do We Need?

  1. 2 x 22M Ohm + resistors (the bigger the resistance value the further away your sensor reacts, I personally used 22M Ohm, the minimum to get usable data I experienced was 10M Ohm)
  2. 3x 330 Ohm resistors


  1. Breadboard
  2. Circuit board (mine had continouos copper strips)
  3. Multiple common Cathode RGB Leds (I used 8, but you can have more or less depends on how much light you want)

7.Aluminium foil

  1. Cling wrap

9.Arduino Uno

  1. Tape

The Case:

  1. Wood I used 50 x 50 x 1.8 CM MDF(you can use anything really. It depends on the effect you want and the tools you have at your disposal)
  2. Acrylic plexiglas I used 50 x 50 x 0.3 CM(or any other transparent/translucent material like rice paper)

3.Sandpaper (fine sandpaper)


5.veneer (optional)

6.Acrylic glue


Wire stripper

Soldering iron + tin

Stanley knife


Saw (I used a table saw)

Step 2: Prototyping:Prototyping 1 (1)

Now we have everything and we can start making a prototype to see how it works:

Prep work:

Cut out 4 rectangles from the aluminium foil (Mine are about 10 cm by 5 cm), wrap these in cling wrap to insulate them from direct touch and stick a wire to the aluminium foil. I just taped a stripped end to the foil (as long as they stay in contact).

To make sure the aluminium is safely insulated I wrapped in cling wrap and ironed it between papers (just for a few seconds so it doesn’t completely melt).

Then set up the circuit as seen in the image.

Pin 4 is used as a send pin for both sensors, while the receive pins are pin 2 and 5. You could use multiple send pins but it causes trouble since they are not perfectly in sync.

use this setup for debugging purposes before soldering everything together, to make sure that everything truly works as intended.

Step 3: Code:

Now we have everything and we can start debugging the sensors.

To use my code you should download the capacitive sensing library from Arduino and install it according to the directions given by the reference page: Click me

The code: (I’m not great at coding, so if you know how to do it better please do)

include //import the code library

CapacitiveSensor cs_4_2 = CapacitiveSensor(4,2); //Send pin = 4, receive are 2 and 5
CapacitiveSensor cs_4_5 = CapacitiveSensor(4,5);

const int redPin = 11;
const int greenPin = 10;
const int bluePin = 9;

const int numIndexR = 10; // array size
const int numIndexG = 10;

int colorR = 0;
int colorG = 0;
float colorB = 0;

int indexR [numIndexR];
int posIndexR = 0;
long totalR = 0; //it needs to be a long because the total of my array was to big for an integer.
int averageR = 0;

int indexG [numIndexG];
int posIndexG = 0;
long totalG = 0;
int averageG = 0;

void setup()
pinMode(redPin, OUTPUT);
pinMode(greenPin, OUTPUT);
pinMode(bluePin, OUTPUT);

for (int thisIndexR = 0; thisIndexR < numIndexR; thisIndexR++) { //sets the array to 0
indexR [thisIndexR] = 0;

for (int thisIndexG = 0; thisIndexG < numIndexG; thisIndexG++) {
indexG [thisIndexG] = 0;

colorR = 255; //turns on all leds colors
colorG = 255;
colorB = 255;

void loop()
long start = millis();
long total1 = cs_4_2.capacitiveSensor(10); //Save the raw sensor data to a variable
long total2 = cs_4_5.capacitiveSensor(10);

if (total1 >= 4500){        //cap the sensor values to a usable maximum, this is not the same for every resistor value and also might differ a bit from environment to environment you might need to tweak this to your own needs.
  total1 = 4500;

if (total2 >= 4500){
  total2 = 4500;

totalR = totalR - indexR[posIndexR]; //this here creates an array that continuously adds a sensor output and produces the average. 
indexR[posIndexR] = total1;
totalR = totalR + indexR[posIndexR];
posIndexR = posIndexR + 1;

if (posIndexR >= numIndexR){
  posIndexR = 0; 

averageR = totalR / numIndexR; //we use the average instead of the raw data to smooth out the output, it slows the process down slightly but it also creates a really nice smooth flow.

totalG = totalG - indexG[posIndexG]; 
indexG[posIndexG] = total2;
totalG = totalG + indexG[posIndexG];
posIndexG = posIndexG + 1;

if (posIndexG >= numIndexG){
  posIndexG = 0; 

averageG = totalG / numIndexG;

if (averageR >= 2000 ){ // we don’t want the leds to constantly changes value unless there is input from your hand, so this makes sure all lower environmental readings are not taken into account.
colorR = map(averageR, 1000, 4500, 255, 0);

      analogWrite (redPin, colorR);   

else if (averageR <= 2000){
colorR = 255;
analogWrite (redPin, colorR);


if (averageG >= 1000 ){
colorG = map(averageG, 1000, 4500, 255, 0);

      analogWrite (greenPin, colorG);   

else if (averageG <= 1000){

       colorG = 255;
       analogWrite (greenPin, colorG);   

if (colorR <= 125 && colorG <= 125){ //B works a bit different because I only used 2 sensors so I mapped B on both sensors
colorB = map(colorR, 255, 125, 0, 127.5) + map(colorG, 255, 125, 0, 127.5);
analogWrite (bluePin, colorB);

colorB = map(colorR, 255, 125, 127.5, 0) + map(colorG, 255, 125, 127.5, 0);
if (colorB >= 255){
colorB = 255;

if (colorB <= 0){
colorB = 0;
analogWrite (bluePin, colorB);

Serial.print(millis() - start);        //this is for debugging purposes




What this code does is extracting the raw data from the sensor (this data will always be slightly erratic due to all the different factors that affect the sensor) and it puts the raw data continuously in an array, when the array reaches is max value (in my case 10) it purges the last value and adds a new one. Each time a value is added it calculates the average value and puts it in a new variable. This average variable is used to map a value to a value from 0 to 255, this is the value that we write to the RGB pins to increase the brightness of each channel (the channels being R G and B).

Now if you upload your code to the arduino and you open the serial monitor you should be seeing the RGB values lower when you hover your hand over each sensor also the light color of the led should change.

Step 4: Now for the Case:

The case: I made the case using tools available through my university, so this workflow is not applicable for everyone. However there is nothing too special about it, it needs a hole on one side for the USB port to fit through but other than that its just an open topped box.

The dimensions are as follows:

15 x 15 CM for the transparent top


15 x 8 CM for the wooden base (the thickness of the wood was 1.8 CM for me).

I used a table saw to cut a plate of MDF into the correct dimensions I needed (which is 4 panels 15 x 8 CM and 1 15 x 15 CM ground panel), after which I cut the corners into a 45 degree angle. All the parts I stuck together using wood glue and clamps(let it dry at least 30 minutes), I used the same procedure for the Plexiglas but with a special saw blade.

1 of the wooden sides should have a hole in the center at the height of the arduino USB plug to allow the arduino to be plugged in.

Read more: Interactive Touchless Light

Leave a Comment

Your email address will not be published. Required fields are marked *