LED Interactive Copper Etching
by tommo_79 in Circuits > Electronics
1768 Views, 20 Favorites, 0 Comments
LED Interactive Copper Etching
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.
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
Etching
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.
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.
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.
Finishing Touches
I left the back panel off the picture frame, leaving the circuit exposed.