Handcrafted Arduino-powered RGB Moodlamp

14K4528

Intro: Handcrafted Arduino-powered RGB Moodlamp

This instructable is subdivided in 5 parts:

- Planning the construction (Step1)
- The handmade shade (Step2+3)
- The electronic circuit for driving 3W LEDs with the ATmega8 controller (Step4)
- The Code (Step5)
- How to get it stand-alone (flash the Arduino bootloader with PonyProg and burn the sketch) (Step6) coming soon

Vid: Some Impressions



http://de.youtube.com/watch?v=apZ9NpaUG84
Pic1: The Moodlamp
Pic2: A mighty 3W LED

STEP 1: Planning the Construction:

I love to do a concept on just one sheet of paper.

On the first sheet you see some early ideas. "I chose the bottom-right design.

The second page shows some details for the construction.
measurements are experimental like each time, but ok for me ;-)

My hardware thoughts were:
- Can I handle the materials?
- Will the light shine through the shade?
- What proportion should it have?
- How many knobs and pots will I need for a simple interface?

My software thoughts were:
How many different functions should the lamp have?
- Automatic RGB fading with changeable speed
- Manual color adjustment
- White with adjustable brightness

STEP 2: The Handmade Shade

Gathering the materials:

The shade:
I found a 3 foot x 3 foot sheet of 30 mill plastic at the store (Pic1-3).
Use a sharp knife to cut it.
I frosted the plastic using sandpaper (Pic4-6).
To get a smooth cylinder I screwed it all together after drilling the right holes (Pic7-8).

Mount the plastic shades on the threaded brass supports. It looks nicely and is rather easy to get and handle.
I drilled and tapped the holes to match the 1/8th threaded bar (Pic9-10).

meanwhile, I made a heatsink to cool down the 3W LEDs and to have a solid base.
For getting not too many shades from the shaft, I build a little cage from welding rod with a M8 nut on top (Pic12).

As finish i assembled all together. The little screws and nuts were a little tricky, but 30minutes later I got it done.

STEP 3: The Handmade Shade

The base:
The discs were chucked in the lathe to get it smooth and round.
Afterwards, I stained it with a mahogany wood stain so the to make the pine look good.
What next?!?
I decided to make a base using the same frosted plastic as the shade, and backlight it with a RGB microLED (Pic5).

The knobs:
I made the button from a piece of mahogany and the knobs from a offcut of nutwood.

STEP 4: The Electric Circuit:

On the first picture you see my schematic.

And here's another video:
http://de.youtube.com/watch?v=xkiYzQAYf_A&NR=1

STEP 5: The Code:

On the pics you see my process with Arduino. Firstly I tried around with my selfmade ProtoShield, a battery pack and some sorts of LEDs.
I started with "Spooky Projects" and "BionicArduino" by TodEKurt some months ago.
http://todbot.com/blog/spookyarduino/

My code is just a tricky combination of his project code.
"RGBMoodlight", "RGBPotMixer"
and some extensions.
Three analog-in and.
one digital-in as mode switch (Thanks to Ju. for the interrupt-routine :) .
The LEDs are connected to D9,D10 and D11 which support PulseWithModulation.

If you like, I can publish the sketch, but it's a really bare combination of these two great codes.

Here's my original code of the lamp.
It looks a little messy, because it was my very early stage in programming...
But if you copy it, it should work great.

There are fine peaces, like the "PotColorMixer", the "RGBfadingFunction" and the Interrupt-Routine for the mode-switch.

/* nejo June2008
  • Code for my "Moodlamp", based on "dimmingLEDs" by Clay Shirky <clay.shirky@nyu.edu>
*nejo Sep2008
  • Final code for the moodlamp with interrupt-mode-switch, analog speed-dial for RGB-fading and RGB color change.
  • The dimming-function works just for the white color
*nejo October2008
  • Sound-extension for the moodlamp:
  • A condensor microphone with a tiny LM368 Amp, a recifier and a RC-low-pass-filter
  • with another analogInput I use the RGBPotMixer-function to change the color by getting the mic-signal.
*
*
*Code for cross-fading 3 LEDs, red, green and blue, or one tri-color LED, using PWM
  • The program cross-fades slowly from red to green, green to blue, and blue to red
  • The debugging code assumes Arduino 0004, as it uses the new Serial.begin()-style functions
  • originally "dimmingLEDs" by Clay Shirky <clay.shirky@nyu.edu>
*
  • AnalogRead is enabled on Pin A0 to vary the RGB fading speed
  • AnalogRead is enabled on Pin A2 to vary the hueRGB color
*
*
*/

#include <avr/interrupt.h>
// Output
int ledPin = 13; // controlPin for debugging
int redPin = 9; // Red LED, connected to digital pin 9
int greenPin = 10; // Green LED, connected to digital pin 10
int bluePin = 11; // Blue LED, connected to digital pin 11

int dimredPin = 3; // Pins for the analog dimming value, connected to the transistor driver
int dimgreenPin = 5;
int dimbluePin = 6;

// Input
int switchPin = 2; // switch is connected to pin D2
int val = 0; // variable for reading the pin status
int buttonState; // variable to hold the button state
int buttonPresses = 0; // 3 presses to go!
int potPin0 = 0; // Pot for adjusting the delay between fading in Moodlamp;
int potPin2 = 2; // Potentiometer output for changing the hueRGB color
int potVal = 0; // Variable to store the input from the potentiometer
int maxVal = 0; // value to save the dimming factor default is 255, if no Pot is connected
int dimPin = 4; //Pot connected to A4 to dim the brightness

// Program variables
int redVal = 255; // Variables to store the values to send to the pins
int greenVal = 1; // Initial values are Red full, Green and Blue off
int blueVal = 1;

int i = 0; // Loop counter
int wait;// = 15; // 50ms (.05 second) delay; shorten for faster fades
int k = 0; // value for the controlLED in the blink-function
int DEBUG = 0; // DEBUG counter; if set to 1, will write values back via serial
int LCD = 0; // LCD counter; if set to 1, will write values back via serial

void setup()
{
pinMode(ledPin, OUTPUT);
pinMode(redPin, OUTPUT); // sets the pins as output
pinMode(greenPin, OUTPUT);
pinMode(bluePin, OUTPUT);
pinMode(dimredPin,OUTPUT);
pinMode(dimgreenPin,OUTPUT); // sets the pins as output
pinMode(dimbluePin,OUTPUT);
pinMode(potPin2, INPUT); //
pinMode(potPin0, INPUT); //
pinMode(dimPin, INPUT); //
pinMode(switchPin, INPUT); // Set the switch pin as input
attachInterrupt(0,isr0,RISING);

if (DEBUG) { // If we want to see the pin values for debugging...
Serial.begin(9600); // ...set up the serial ouput on 0004 style
}
}

// Main program
void loop()
{

if (buttonPresses == 0) {
Moodlamp(); // calls the Moodlight function
}
if (buttonPresses == 1) {
RGBPotMixer(); // calls the manuel mix function
}
if (buttonPresses == 2) {

White(); // It's all white in here
}
if (buttonPresses == 3) {

}

//Moodlamp();
//RGBPotMixer();
//White();

Monitor();
dim();
}
void Monitor(){ // Send State to the monitor

if (DEBUG) { // If we want to read the output
DEBUG += 1; // Increment the DEBUG counter
if (DEBUG > 10) { // Print every 10 loops
DEBUG = 1; // Reset the counter
Serial.print(i); // Serial commands in 0004 style
Serial.print("\t"); // Print a tab
Serial.print("R:"); // Indicate that output is red value
Serial.print(redVal); // Print red value
Serial.print("\t"); // Print a tab
Serial.print("G:"); // Repeat for green and blue...
Serial.print(greenVal);
Serial.print("\t");
Serial.print("B:");
Serial.print(blueVal); // println, to end with a carriage return
Serial.print("\t");
Serial.print("dimValue:");
Serial.print(maxVal); // println, to end with a carriage return
Serial.print("\t");
Serial.print("wait:");
Serial.print(wait); // writes the value of the potPin0 to the monitor
Serial.print("\t");
Serial.print("hueRGBvalue");
Serial.print(potVal); // writes the value of the potPin0 to the monitor
Serial.print("\t");
Serial.print("buttonState:");
Serial.print(buttonState); // writes the value of the potPin0 to the monitor
Serial.print("\t");
Serial.print("buttonPresses:");
Serial.println(buttonPresses); // writes the value of the buttonPresses to the monitor

}
}
}

void dim() // Function for dimming White // maybe later for all Modes
{
maxVal = analogRead(dimPin);
maxVal /= 4; // Analog range from 0..1024 --> too much for dimming the 0..255 value
analogWrite(dimredPin,maxVal);
analogWrite(dimgreenPin,maxVal);
analogWrite(dimbluePin,maxVal);

}

void Moodlamp()
{
wait = analogRead(potPin0); // look for the value from the potPin0;
// if no Pot is connected: wait 255

i += 1; // Increment counter
// i = i - maxVal;
if (i < 255) // First phase of fades
{
redVal -= 1; // Red down
greenVal += 1; // Green up
blueVal = 1; // Blue low
}
else if (i < 509) // Second phase of fades
{
redVal = 1; // Red low
greenVal -= 1; // Green down
blueVal += 1; // Blue up
}
else if (i < 763) // Third phase of fades
{
redVal += 1; // Red up
greenVal = 1; // Green lo2
blueVal -= 1; // Blue down
}
else // Re-set the counter, and start the fades again
{
i = 1;
}

// we do "255-redVal" instead of just "redVal" because the
// LEDs are hooked up to +5V instead of Gnd

analogWrite(redPin, 255 - redVal); // Write current values to LED pins
analogWrite(greenPin, 255 - greenVal);
analogWrite(bluePin, 255 - blueVal);

/* dimredVal =min(redVal - maxVal,255); //dimming
dimredVal =max(redVal - maxVal,0);
dimgreenVal =min(greenVal - maxVal,255);
dimgreenVal =max(greenVal - maxVal,0);
dimblueVal =min(blueVal - maxVal,255);
dimblueVal =max(blueVal - maxVal,0);

analogWrite(redPin, 255 - dimredVal); // Write current values to LED pins
analogWrite(greenPin, 255 - dimgreenVal);
analogWrite(bluePin, 255 - dimblueVal);
*/

wait /=4;
delay(wait); // Pause for 'wait' milliseconds before resuming the loop

}

void RGBPotMixer()
{
potVal = analogRead(potPin2); // read the potentiometer value at the input pin
potVal = potVal / 4; // convert from 0-1023 to 0-255

hue_to_rgb( potVal); // treat potVal as hue and convert to rgb vals

// "255-" is because we have common-anode LEDs, not common-cathode
analogWrite(redPin, 255-redVal); // Write values to LED pins
analogWrite(greenPin, 255-greenVal);
analogWrite(bluePin, 255-blueVal);

}

void White(){
analogWrite(redPin, maxVal); // Write values to LED pins
analogWrite(greenPin, maxVal);
analogWrite(bluePin, maxVal);
}

/*
  • Given a variable hue 'h', that ranges from 0-252,
  • set RGB color value appropriately.
  • Assumes maxValimum Saturation & maximum Value (brightness)
  • Performs purely integer math, no floating point.
*/
void hue_to_rgb(byte hue)
{
if( hue > 252 ) hue = 252; // stetback to 252!! nejo
byte hd = hue / 42; // 36 == 252/7, 252 == H_MAX
byte hi = hd % 6; // gives 0-5
byte f = hue % 42;
byte fs = f * 6;
switch( hi ) {
case 0:
redVal = 252; greenVal = fs; blueVal = 0;
break;
case 1:
redVal = 252-fs; greenVal = 252; blueVal = 0;
break;
case 2:
redVal = 0; greenVal = 252; blueVal = fs;
break;
case 3:
redVal = 0; greenVal = 252-fs; blueVal = 252;
break;
case 4:
redVal = fs; greenVal = 0; blueVal = 252;
break;
case 5:
redVal = 252; greenVal = 0; blueVal = 252-fs;
break;
}
}
void isr0(){
Serial.println("\n \n inerrupt \n");

buttonState = digitalRead(switchPin); // read the initial state
delayMicroseconds(100000);
//if (val != buttonState) { // the button state has changed!

// if (buttonState == HIGH) { // check if the button is now pressed
buttonPresses++;

// }
// val = buttonState; // save the new state in our variable
if (buttonPresses == 3) { // zur�cksetzen
buttonPresses = 0;
}
}

// }

Next stage were the transistor-drivers. I used 3 PNP transistors with a maximum current on 3Ampere. After forward-current and voltage were regulated, the LEDemitter worked great with full intensity.

STEP 6: Get It Standalone With PonyProg-burned Bootloader

How to use your paralell port to burn the arduino bootloader on a ATmega168 or ATmega8 to use a cheap blank chip with the arduino environment.

coming soon..... maybe on a seperate instructable

Here's also a good instructable to use the chip standalone:
https://www.instructables.com/id/uDuino-Very-Low-Cost-Arduino-Compatible-Developme/?ALLSTEPS

STEP 7: So That's My Arduino Moodlamp

If you liked it, please rate me.

28 Comments

Hello, great instructable, I don't plan on copying your circuit completely and I have my own lamp design in mind, but I was wondering what type of power transistor did you use?
Thank you
Hi, and thanks for your interest.
The lamp was my first experience with powerLeds and in the meanwhile I've found some smarter solutions to drive these leds.
I recommend you to use the MC34063 switching regulator as mentioned in this article:
http://translate.google.com/translate?hl=de&sl=auto&tl=en&u=http%3A%2F%2Fwww.mikrocontroller.net%2Farticles%2FKonstantstromquelle_fuer_Power_LED

In Germany I can get it for 0.27€ and the additional parts are available for cents.

I hope you can get it to work!
Regards,
jo
I just wanted to say thank you. I looked through at least half a dozen other RGB LED lamp instructables, and yours was the most helpful while I was designing my own lamp. Thanks!
hi and thanks for your feedback!!
im sry this is the noobyist question ever but when it said ground on the schecmatics just attach it to the ground on arduino? and while im on here on the video you had a big silvery grid thing attached to the transistors, what the heck is that is it importiant. and one last question on the top right of the shcematis where u said the button is there is a a little wire right next to it that looks like its suppose to be attached to it. is it? tyvm
u say that theres 3 pots but below there is a symbol for 6 (im not trying to correct you on your own circet i want you to correct me) (circled in red)
I said there are 3+3pots. three on PWMpins to drive the leds, three on AnalogInputPins
ok i got one more question sry ='( . why is there 6 potentiometers on the diagram and 2 in the vid.(im so sry this is my last question i got everything else together)
There are 3 pots for the transistor-drivers and 3 as "interface" with a switch to change the mode. .......--> each mode has it's own pot. ................(moodMode--> changeSpeedPot) ................(hueToRGB--> change the color valuePot) ................(fullRGB_white--> dim the lampPot) regards, jo
thanks for helping me and im only 13 so no i havent rly worked with stuff like that i think i can work off all the stuff u gave me. ty agin
thank you so much for putting up with my amature questions and ill try to stop burdening you and just put it together as the schematics sais(lol). just one thing is i dont know the numbering/abriviations(like:pb7) on you picture. the numbering skips from 1-6, 20-27 stuff like that. so can you edit it or something to make it look like a real arduino.if thats to much i understand and ill try to look up the abriviations.
OK, I don't know how familiar you are with electronics, especially with programming the Arduino and handling electronics.
have you ever worked with a controller-board or electronic components like transistors and LEDs??

Here you have some links:

All the information you're looking for
http://www.arduino.cc/
just look for some details on "connecting to hardware" and look at some tutorials on "learning"

Here you see the pinout of the chip, compared with the pinNumbers on the board
http://arduino.cc/en/Hacking/PinMapping168

The platform is open source and I like that way of thinking.
If I can help you with your problem, it's just great.

GoodLuck,
jo
/*
Here you get a simple loop for fading a led smoothly by trigonometric calculations:
Take any led you got and put it into digitalPin9, which supports PulseWidthModulation (to fade the led) take the other electrode of the led and put it through a resistor (about 100...500ohm) to +5V or GND

...Purpose: Fading a Led
Language: Arduino0012
...... Author: nejo0017
..........Date: 2009-03-03

For details on the Code: http://arduino.cc/en/Reference/Extended
*/

///////// the Arduino supports 8bit PWM on 6Pins:
int ledPin3=3; // connected to the red led
int ledPin5=5; // connected to the green led
int ledPin6=6; // connected to the blue led

int ledPin9 = 9; // red
int ledPin10 = 10; // green
int ledPin11 = 11; // blue

void setup()
{
// nothing for setup
}

void loop()
{
FadeLed(ledPin9); // calling the function
}

void FadeLed(int led) // create a function and give it the led as parameter
{
int value;
for(int i=0;i<360;i++)
{
value = 128 + 127*(-cos(i*PI/180));
analogWrite(led,value);
delay(10); // wait for 10 milliseconds
}
}
i am so sorry but i inspected your diagram and i was wondering what this symbol ment. i couldent find it in the enternet
this is a switch for the reset. the schematic is (beside the oscillater circuit) complete to run the bareBoneVersin in the Moodlamp.
hi thank you for taking you time to explain all that. but yet i am a amature and didnt understand a word so if you could just answer my questions: is there one rgb led or 3 leds or whats going on there. (circled in red) why is there 2 extra leds (to the left and to the botton) (circled in orange) ok im amature a noob w/e so what is vcc ( black) and how and why are there so many grounds(agin im a amature) (brown) ty, i put it from most importaint to least and the things are cxircled below in the picture.
Hi, I'm also a noob ;) But anyway I'll try to explain my thoughts: When you look on the previous pictures, you see 3 leds on the PNP transistors, one as power indicator and one as debuggingLed, connected to pin13 on my selfmade ArduinoBoard. The RedGreenBlue Leds are connected with their Anode to +5V (vcc) and the Kathodes are connected through the transistors on GND (vss) If you connect +5V to the Collecter (C) and GND to the Emitter (E) of the transistor, nothing happens. If you connect +5V to the Base (B), you got a short circuit. Now you put the Led between Vcc and E, the Led burns. The voltage and also the Current should be constrained. I do it with a simple resistor calculated with the right value for enough current(I figured it out with a potentiometer and a amperemeter :). As I've written before you could learn a lot from the instructables about "constant current sources", but my solution is just about 40ct and works great. vss: voltage source (Ground (-)) vdd: voltage drain (+) vcc: voltage common (+) vo: voltage out As you can see, I used 3 leds with 3W, but usually I use common anode RGB leds from Dealextreme (keyword HongKong) Do you have a current project you're working on? If you'd send me a picture I could tell you where to solder the wires ;) Regards, jo (there are many nice things to do ;)
im sry the picture was messed up in my computer. but it would be nnice if you still could add a instructable
The electronics are very cheap and easy!
I didn't use a constant current source, just some PNP transistors to get enough current.
To limit the current I inserted a resistor between the Arduino and the base.

Collector: GND
Base: ArduinoPin - resistor - Base
Emitter: LED Cathode

The LEDs Anode is connected to 5V,
The next step was to connect the cathode through a PNP transistor on GND.
I used a Pot and a amperemeter to get the right current from the datasheet.
I think it was around 1000mA.
After getting the right current and brightness I checked the resistance and replaced it with a resistor.

That's it....... Very simple and not professional, but it works very good.

I hope the info was enough....
If you want to learn more about LED driving circuits, see this Instructable:
https://www.instructables.com/id/Circuits-for-using-High-Power-LED_s/

Regards,
jo
More Comments