Finally after a long absence, in which I was immersed in the final realization of this project, I did it!
After months of planning, studies, research and other obstacles, the RGB LED Lamp 1.0 by Toggio is reality.
Here’s the video showing the final result obtained:
And now a brief history.
One of the things that attracted me the most when I first heard of Arduino, was light, and in particular I have always dreamed of achieving an LED lamp RGB.
Nothing difficult, you might think … Except that along this route I found several obstacles.
First of all, I did not find complete projects on the net … There is something, but, in my opinion, with bad algorithms, with little explanation or with complicated methods.
I wanted a simple present to give to the person who I love and that gave me a beautiful daughter …
I wanted something that had a powerful enough light, without too much heat. I wanted something that had a chance to choose the color and not a simple “color cycler.” I wanted something that would serve also as a standard lamp. And finally, I wanted something that was modular and upgradeable in the future.
After these reflections, I began to study the hardware first. I did not want to use the Arduino UNO because it seemed too big for my project. So I decided (and this could open up a huge parentheses) to use a board not so common, but in my opinion awesome (so much that I bought 4 or 5 piece): The Arduino Mini Pro.
(It is understood that in the project of this post, it can easily be replaced by an Arduino UNO or any other board.)
It ‘a very small board (18mm x 33mm), 100% compatible with Arduino Dumilanove, and low power consumption. It is available in four versions: with Atmega328 or with ATmega168, both with 3.3V or 5V.
So I opted in this project for the 5V version with ATmega168. In short it is a very economic solution (it costs about half of the Arduino UNO), very compact and beautiful to see.
I then thought of using the useful LED RGB strips, which offer many advantages over using 1W or 3W power LEDs: they do not heat up, they are powered with 12V and they offer a power up to 13-14W per meter.
Each channel can be powered by a PWM output of the Arduino using a simple transistor (in my case I used the BC337, but for higher power you can use other transistor, or even the MOSFET).
I then proceeded to build a kind of shield for my board. Practically I made a circuit in which the Arduino Pro Mini would fit with strip connectors and with the ability to be removed to upgrade the firmware. Everything has been designed with Fritzing and built by Fritzing Fab.
The final result of the printed circuit is as follows:
You can see the two rows of holes where the Mini Pro will be mounted… Basically, it’s the opposite of a shield 🙂
But let’s step back and see the circuit schematic:
I hope it is clear enough even if I have not drawn just fine!
In any case, the operation principle is as follows: The two 10k potentiometers connected between +5 V and ground, are the two analog inputs that allow to adjust the brightness and other parameters set by the software. The 3-position switch SW2 allows you to select three different functions for the lamp. The digital outputs 3,5,6 go through a resistor to drive the 3 BC337 transistors that will give negative voltage to the 3 channels (R, G, B) of the LED strip. The common positive goes to +12 V, while the Arduino is powered by RAW port (input from 7V to 13V) via a diode that in addition to providing reverse polarity protection, slightly lowers the voltage. SW1 is simply the bridge where will be connected a standard power switch.
Once soldered the components, connectors, potentiometers, mounted the circuit, encapsulated the Arduino board, and assembled it all in a electrician box, the result is as in the following picture:
The size of the box is approximately 10cmx10cmx7cm.
For the top, I used about 70cm of RGB led strip, for a total power of about 10W. To fit the whole strip I rolled it around the support of a “50 CD-R set”. I cut with a utility knife and I glued all with spacers on the box. I then glued with hot glue the wrapping strip led… In short, the job is a little rough but the end result is as follows:
The glass you see on the desk, is the final piece: the glass cover of a IKEA lamp, properly cut ​​by a local glazier, so that it remains empty on both sides. This coverage will finally resting on the box and glued, obtaining the following results:
Not bad right?
Of course there is still the icing on the cake, a not less important part: the software.
The self-explanatory code is as follows:
/* RGB Led Lamp 1.0a by Luca Soltoggio 15/03/2012 http://arduinoelettronica.wordpress.com/ */ int rpin = 3; // red pin int gpin = 5; // green pin int bpin = 6; // blue pin unsigned int r=0, g=0, b=0,bm=0; // r,g,b, value and blue coefficient unsigned int valh=0, vals=0, valv=0; // hue, saturation, value unsigned int sensorValue; // analog sensor value const int analogInPin = A0; // potentiometer pins const int analogInPin2 = A1; const int digitalInPin = 10; // switch pins const int digitalInPin2= 11; int red[]={255,255,135}; // predefined arrays for RGB / White int green[]={157,255,158}; int blue[]={51,255,255}; boolean DIG1, DIG2; long previousMillis = 0; int i=0,j=0; int dl=0; // delay void setup() { pinMode(digitalInPin,INPUT); pinMode(digitalInPin2,INPUT); } void loop() { DIG1=digitalRead(digitalInPin); DIG2=digitalRead(digitalInPin2); if (DIG1) { bm=1.1; HSV_Game(); } else if (DIG2) { bm=1.9; RAINBOW_Game(); } else { bm=2.4; LIGHT_Game(); } analogWrite(rpin, r/1.09); // write RED PIN analogWrite(gpin, g/1); // write GREEN PIN analogWrite(bpin, b/bm); // write BLUE PIN } // analog input smoothing function int SensorSmooth (int pin) { sensorValue=0; for (int i = 0; i<10; i++) { sensorValue+= analogRead(pin); } return int ((float)sensorValue/10+0.5); } // first light game: modify HUE and VALUE with potentiometer void HSV_Game() { valh = SensorSmooth(analogInPin); vals = 255; valv = SensorSmooth(analogInPin2); valh = map(valh,0,1023,0,359); valv = map(valv,0,1023,32,255); hsv2rgb(valh,vals,valv,r,g,b); } // second light game: three positions for Warm White, White and Cold White void LIGHT_Game() { valv = SensorSmooth(analogInPin2); valv = map(valv,0,1023,16,255); valh = SensorSmooth(analogInPin); if (valh<=281) valh=0; if (valh>=742) valh=2; if (valh>2) valh=1; r=red[valh]*valv/255; g=green[valh]*valv/255; b=blue[valh]*valv/255; } // color cycler void RAINBOW_Game() { dl = SensorSmooth(analogInPin); // delay time dl = map(dl,0,1023,1,100); valv = SensorSmooth(analogInPin2); valv = map(valv,0,1023,64,255); unsigned long currentMillis = millis(); switch (j) { case 0: r=255*valv/255; g=i*valv/255; b=0*valv/255; break; case 1: r=(255-i)*valv/255; g=255*valv/255; b=0*valv/255; break; case 2: r=0*valv/255; g=255*valv/255; b=i*valv/255; break; case 3: r=0*valv/255; g=(255-i)*valv/255; b=255*valv/255; break; case 4: r=i*valv/255; g=0*valv/255; b=255*valv/255; break; case 5: r=255*valv/255; g=0*valv/255; b=(255-i)*valv/255; } if (currentMillis-previousMillis > (long)(100-dl)) { // use millis instead of delay previousMillis=currentMillis; i=i+1; if (i==256) { i=1; j=j+1; if (j==6) j=0; } } } /* HSV2RGB function (c) Elco Jacobs, E-atelier Industrial Design TU/e, July 2011 http://code.google.com/p/shiftpwm/source/browse/trunk/examples/ShiftPWM_Example1/hsv2rgb.cpp?r=3 */ void hsv2rgb(int hue, int sat, int val, unsigned int& r, unsigned int& g, unsigned int& b) { int H_accent = hue/60; int bottom = ((255 - sat) * val)>>8; int top = val; int rising = ((top-bottom) *(hue%60 ) ) / 60 + bottom; int falling = ((top-bottom) *(60-hue%60) ) / 60 + bottom; switch(H_accent) { case 0: r = top; g = rising; b = bottom; break; case 1: r = falling; g = top; b = bottom; break; case 2: r = bottom; g = top; b = rising; break; case 3: r = bottom; g = falling; b = top; break; case 4: r = rising; g = bottom; b = top; break; case 5: r = top; g = bottom; b = falling; break; } }
The Fritzing project page (where you can also download the source code) can be found here:
http://fritzing.org/projects/high-power-rgb-lamp-10-with-arduino/
Until next time!