Introduction: LED Interactive Copper Etching

I created this project as a nice memento to mark the birth of my little boy. After experimenting with a copper etching of his newborn hands and feet, I decided to take it a bit further and add electronics.

Each hand and foot etched from a copper PCB forms a capacitive sensor plate. An arduino measures differences in charge on each plate caused by the presence of a human hand. Depending on the relative ‘signal’ detected on each plate, the arduino alters the colour of 4 RGB leds set behind the board.

This is kind of a proof of concept ible. I’ll talk you though what I did, but hopefully this will inspire others to modify my idea and come up with something unique.

Step 1: Materials


· Copper PCBs x 2
· Method of transferring a printed image to the PCB (laser printed image or hand draw)
· Copper etchant
· Arduino pro-mini
· WS2812 through hole RGB leds x 4
· 10Mohm resistors
· Box photo frame
· 5v power supply

Step 2: Etching

I used a non toxic baby print kit to get some hand and feet prints. After cleaning them up in photoshop, I printed them out on a sheet of glossy photo paper using a laser printer.

Using a hot iron, I transferred the toner of the hands and feet image to the pcb.

There are lots of good instrucables to help you prepare and etch copper pcbs.

Step 3: The Circuitry

For the electronic circuitry, I prepared a second board of the same dimension. I only have limited access to a laser printer, so decided to hand draw the copper traces with a sharpie. I carefully drilled the holes for components using the smallest drill bit I had.

I also drilled a small hole in each hand and foot to allow me to solder a wire to each copper pad. In hindsight, I could have used a double sided pcb with a mirror image of the hands and feet etched on the underside. This would have negated the need for drilling a hole and improve the presentation of the project.

I used WS2812 through-hole RGB leds for this project. These leds can be linked up in a string and can be individually be addressed using as single arduino data pin Each led has 4 pins to be soldered to the circuit board:
Din
+5v
Gnd
Dout

Each copper hand and foot is connected to an individual arduino ‘receiver’ pin. Finally 30Mohm resistors are required between a single arduino ‘sender’ pin and each of the 4 receiver pins.

As I could not get 30Mohm resistors, I combined 10Mohm resistors in series. You may need different resistor values for your project - but basically, the higher the resistor value, the more sensitive the sensor is.

I'm using a 3.3v arduino for this project, so have found it necessary to provide 3.3v DC to both the arduino and the WS2812 LEDs. The reason being, the 3.3v Din signal from the arduino was not strong enough in relation to the input voltage of the LED. 3.3v is enough to power my particular LEDs.

Step 4: The Code

I used the arduino CapacitiveSensor library in my project. This library outputs an arbitrary value for each sensor pad, depending on the strength of signal detected. If a hand is close a strong signal is detected, it the hand is far away, a low value is detected.

For each pad, I converted the detection value to a proportion and I also created a value providing the sum of all readings.

I mapped relative proportion values to a colour scale (red to green to blue). If a pad has a relatively low proportion value, the led underneath will be towards the red end of the scale. If the pad has a relatively high proportion value the colour will be close to blue. So if you move your hand around the project, colours will move to follow your hand.

The table below indicates what colour corresponds to each proportional value.

Red (255,0,0) = Sensor value is equal or less than 15% of total sensor values

Yellow (255,255,0) = sensor value is 33% of total

Green (0,255,0) = sensor value is 50%

Aqua (0,255,255) = sensor value is 68%

Blue (0,0,255) = sensor value is greater than 85%

Through code, i have interpolated colours between each of the above thresholds so that there is a gradual progression through the colour scale. Note I've excluded the Blue to Red colour range, purely out of simplifying the code.

Note, to get a good range of colours, I capped the lowest sensor proportion at 15% and the highest at 85% - through testing, I found sensor values were generally within this range.

Also, depending on the total sensor value read, the brightness of all leds will be altered - dim if the hand is far away and bright if the hand is close.

My code is provided below.

<p>#include <br>#include 
#define PIN            1
#define NUMPIXELS      4
<br></p><p>Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_RGB + NEO_KHZ800);
<br></p><p>int delayval = 100; // delay for half a second
<br></p><p>CapacitiveSensor   cs_2_4 = CapacitiveSensor(2,4);        
CapacitiveSensor   cs_2_6 = CapacitiveSensor(2,6);        
CapacitiveSensor   cs_2_8 = CapacitiveSensor(2,8);       
CapacitiveSensor   cs_2_10 = CapacitiveSensor(2,10);       
<br></p><p>int limit1=0;
int limit2=0;
int limit3=0;
int limit4=0;
int limit5=0;
<br></p><p>//variables to store raw capacitive sensor readings</p><p>int total1=0;
int total2=0;
int total3=0;
int total4=0;
int total=0;</p><p>int min_total=0;</p><p>int max_total=0;
<br></p><p>int proportion1 =0;
int proportion2 =0;
int proportion3 =0;
int proportion4 =0;
<br></p><p>float brightness =0;
<br></p><p>// these are the rgb values to control the WS2812 LEDs</p><p>int red1 =0;
int green1 =0;
int blue1 =0;
int red2 =0;
int green2 =0;
int blue2 =0;
int red3 =0;
int green3 =0;
int blue3 =0;
int red4 =0;
int green4 =0;
int blue4 =0;
<br></p><p>void setup() {</p><p>limit1=15; //these values are the proportional thresholds that relate to the colour scale
</p><p>limit2=33;
limit3=50;
limit4=68;
limit5=85;</p><p>//minimum and maximum sensor variables to control brightness</p><p>min_total= 1000; //this value needs to be calibrated
max_total=2000; //this value needs to be calibrated</p><p>
pixels.begin(); // This initializes the NeoPixel library.
}
<br></p><p>void loop() {
// read capacitive sensor values
    long start = millis();
    long total1 =  cs_2_4.capacitiveSensor(30);
    long total2 =  cs_2_6.capacitiveSensor(30);
    long total3 =  cs_2_8.capacitiveSensor(30);
    long total4 =  cs_2_10.capacitiveSensor(30);
total = total1+total2+total3+total4;
proportion1 = 100*total1/total;
proportion2 = 100*total2/total;
proportion3 = 100*total3/total;
proportion4 = 100*total4/total;
brightness = map(total,min_total,max_total,1,255)/255;
<br></p><p>//led1 control:
if(proportion1 < limit2){
red1 = 255*brightness;
green1 = map(proportion1, limit1,limit2, 0, 255)*brightness;
blue1 = 0;
pixels.setPixelColor(0,pixels.Color(red1,green1,blue1));
    }
if (proportion1 > limit2 && proportion1 < limit3){
red1 = map (proportion1, limit2,limit3, 255, 0)*brightness;
green1 = 255*brightness;
blue1 = 0;
pixels.setPixelColor(0,pixels.Color(red1,green1,blue1));
     }
if (proportion1 > limit3 && proportion1 < limit4){
red1 = 0;
green1 = 255*brightness;
blue1 = map (proportion1, limit3,limit4,0, 255)*brightness;
pixels.setPixelColor(0,pixels.Color(red1,green1,blue1));
     }
if (proportion1 > limit4){
red1 = 0;
green1 = map (proportion1, limit4,limit5,255, 0)*brightness;
blue1 = 255*brightness;
pixels.setPixelColor(0,pixels.Color(red1,green1,blue1));
    }
<br></p><p>//led2 control:
if(proportion2 < limit2){
red2 = 255*brightness;
green2 = map (proportion2, limit1,limit2, 0, 255)*brightness;
blue2 = 0;
pixels.setPixelColor(1,pixels.Color(red2,green2,blue2));
    }
if (proportion2 > limit2 && proportion2 < limit3){
red2 = map (proportion2, limit2,limit3, 255, 0)*brightness;

green2 = 255*brightness;

blue2 = 0;
pixels.setPixelColor(1,pixels.Color(red2,green2,blue2));
     }
if (proportion2 > limit3 && proportion1 < limit4){
red2 = 0;
green2 = 255*brightness;
blue2 = map (proportion2, limit3,limit4,0, 255)*brightness;
pixels.setPixelColor(1,pixels.Color(red2,green2,blue2));
     }
if (proportion2 > limit4){
red2 =0;
green2 = map (proportion2, limit4,limit5,255, 0)*brightness;
blue2 = 255*brightness;
pixels.setPixelColor(1,pixels.Color(red2,green2,blue2));
     }
<br></p><p>//led3 control:
if(proportion3 < limit2){
red3 = 255*brightness;
green3 = map (proportion3, limit1,limit2, 0, 255)*brightness;
blue3 = 0;
pixels.setPixelColor(2,pixels.Color(red3,green3,blue3));
     }
if (proportion3 > limit2 && proportion1 < limit3){
red3 = map (proportion3, limit2,limit3, 255, 0)*brightness;
green3 = 255*brightness;
blue3 = 0;
pixels.setPixelColor(2,pixels.Color(red3,green3,blue3));
     }
if (proportion3 > limit3 && proportion1 < limit4){
red3 = 0;
green3 = 255*brightness;
blue3 = map (proportion3, limit3,limit4,0, 255)*brightness;
pixels.setPixelColor(2,pixels.Color(red3,green3,blue3));
     }
if (proportion3 > limit4){
red3 = 0;
green3 = map (proportion3, limit4,limit5,255, 0)*brightness;
blue3 = 255*brightness;
pixels.setPixelColor(2,pixels.Color(red3,green3,blue3));
     }
<br></p><p>//led4 control:
if(proportion4 < limit2){
red4 = 255*brightness;
green4 = map (proportion4, limit1,limit2, 0, 255)*brightness;
blue4 = 0;
pixels.setPixelColor(3,pixels.Color(red4,green4,blue4));
     }
if (proportion4 > limit2 && proportion1 < limit3){
red4 = map (proportion4, limit2,limit3, 255, 0)*brightness;
green4 = 255*brightness;
blue4 = 0;
pixels.setPixelColor(3,pixels.Color(red4,green4,blue4));
     }
if (proportion4 > limit3 && proportion1 < limit4){
red4 = 0;
green4 = 255*brightness;  
blue4 = map (proportion4, limit3,limit4,0, 255)*brightness;
pixels.setPixelColor(3,pixels.Color(red4,green4,blue4));
     }
if (proportion4 > limit4){
red4 = 0;  
green4 = map (proportion4, limit4,limit5,255, 0)*brightness;
blue4 = 255*brightness;
pixels.setPixelColor(3,pixels.Color(red4,green4,blue4));
     }
    pixels.show(); 
    delay(delayval);
}</p>


This code needs a few values to be configured to suit your project as the sensor values rely on a number of factors such as resistance and size of pad.

Step 5: Finishing Touches

I found a box picture frame that was the exact size of my 150x150mm pcb's. The frame had enough space to separate the two pcbs with enough space in between for the LEDs and the ardunio. I drilled a hole in the side for the 5v dc connection.

I left the back panel off the picture frame, leaving the circuit exposed.

Circuits Contest 2016

Participated in the
Circuits Contest 2016