Friday Night Robotics – Fading Multiple RGB LEDs
I mentioned a while ago last week that I wanted to have MANOI’s RGB LEDs fade in and out at different rates from different starting points to different ending points. Luckily, it was a pretty easy task to accomplish, so now I can share the code with everyone!
The setup I have for MANOI’s RGB LEDs are using a Sanguino for a microcontroller. It has 6 PWM pins, so I use 3 pins for two LEDs. (The RGB LEDs have 3 leads for red green and blue). On MANOI, this ends up looking like this:

I define left to be the LED #1 and #3, and right to be LED #2 and #4.
You need 1K ohm resistors, otherwise the red LED will use all of the power, and not save any for green and blue.

I kept the wiring constant, since non-constant would be too confusing. Just a personal preference when dealing with RGB LEDs.


That is all for the RGB LEDs. Next part is the Fade function!
-
void fade ( int startL_R, int startL_G, int startL_B,
-
int finishL_R, int finishL_G, int finishL_B,
-
int startR_R, int startR_G, int startR_B,
-
int finishR_R, int finishR_G, int finishR_B,
-
int stepTime ) {
-
-
// Defining the ‘skip everys’ for different rates
-
int skipEveryL_R = 256/abs(startL_R-finishL_R);
-
int skipEveryL_G = 256/abs(startL_G-finishL_G);
-
int skipEveryL_B = 256/abs(startL_B-finishL_B);
-
int skipEveryR_R = 256/abs(startR_R-finishR_R);
-
int skipEveryR_G = 256/abs(startR_G-finishR_G);
-
int skipEveryR_B = 256/abs(startR_B-finishR_B);
-
-
// Count up to 255
-
for(int i=0; i<256; i++) {
-
-
// If it’s fading down…
-
if(startL_R<finishL_R) {
-
// If we haven’t reached the final point yet…
-
if(i<=finishL_R) {
-
// If it’s a skip every…
-
if(i%skipEveryL_R == 0) {
-
// Colour the LED!
-
analogWrite(redL, i);
-
}
-
}
-
// If it’s fading up…
-
} else if(startL_R>finishL_R) {
-
// If we haven’t reached the final point yet…
-
if(i>=(256-startL_R)) {
-
// If it’s a skip every…
-
if(i%skipEveryL_R == 0) {
-
// Colour the LED!
-
analogWrite(redL, 256-i);
-
}
-
}
-
}
-
-
if(startL_G<finishL_G) {
-
if(i<=finishL_G) {
-
if(i%skipEveryL_G == 0) {
-
analogWrite(greenL, i);
-
}
-
}
-
} else if(startL_G>finishL_G) {
-
if(i>=(256-startL_G)) {
-
if(i%skipEveryL_G == 0) {
-
analogWrite(greenL, 256-i);
-
}
-
}
-
}
-
-
if(startL_B<finishL_B) {
-
if(i<=finishL_B) {
-
if(i%skipEveryL_B == 0) {
-
analogWrite(blueL, i);
-
}
-
}
-
} else if(startL_B>finishL_B) {
-
if(i>=(256-startL_B)) {
-
if(i%skipEveryL_B == 0) {
-
analogWrite(blueL, 256-i);
-
}
-
}
-
}
-
-
if(startR_R<finishR_R) {
-
if(i<=finishR_R) {
-
if(i%skipEveryR_R == 0) {
-
analogWrite(redR, i);
-
}
-
}
-
} else if(startR_R>finishR_R) {
-
if(i>=(256-startR_R)) {
-
if(i%skipEveryR_R == 0) {
-
analogWrite(redR, 256-i);
-
}
-
}
-
}
-
-
if(startR_G<finishR_G) {
-
if(i<=finishR_G) {
-
if(i%skipEveryR_G == 0) {
-
analogWrite(greenR, i);
-
}
-
}
-
} else if(startR_G>finishR_G) {
-
if(i>=(256-startR_G)) {
-
if(i%skipEveryR_G == 0) {
-
analogWrite(greenR, 256-i);
-
}
-
}
-
}
-
-
if(startR_B<finishR_B) {
-
if(i<=finishR_B) {
-
if(i%skipEveryR_B == 0) {
-
analogWrite(blueR, i);
-
}
-
}
-
} else if(startR_B>finishR_B) {
-
if(i>=(256-startR_B)) {
-
if(i%skipEveryR_B == 0) {
-
analogWrite(blueR, 256-i);
-
}
-
}
-
}
-
-
// Delay an amount of time between steps of colouring the LED
-
delay(stepTime);
-
-
}
-
-
}
I added in some comments to make it clear what is going on. The if statement ‘block’ is repeated for RGB on left and right. You could use an array if you wanted to make it more complicated and more condensed.
That code by itself is pretty fun. But, it’s even more fun if you get to interact with it!
I created a headband with an IR sensor for MANOI last week (but neglected to blog it
).

It’s very handy. The IR sensor is from Adafruit! It is really simple, and works ‘out of the box’ without any pull up or pull down resistor needed.


It goes straight into Analog 0.
Now I just need a simple function to map the analog reading back to an appropriate time
-
int theTime() {
-
int result = map(analogRead(0), 0, 1023, 500, 10);
-
/*Serial.print(analogRead(0));
-
Serial.print(", ");
-
Serial.println(result);*/
-
return result;
-
}
The reason why the Serial.print’s are all commented out is because if you leave the Sanguino running with the Serial.print’s, it will eventually run out of memory and just stop. However, for debugging, the Serial.print’s are very handy.
Here is the loop function that I use to give MANOI its magic:
-
void loop() {
-
-
LR = int(random(50, 255));
-
LG = int(random(50, 255));
-
LB = int(random(50, 255));
-
RR = int(random(50, 255));
-
RG = int(random(50, 255));
-
RB = int(random(50, 255));
-
-
fade( preLR, preLG, preLB, // L Start
-
LR, LG, LB, // L Finish
-
preRR, preRG, preRB, // R Start
-
RR, RG, RB, // R Finish
-
1);
-
-
delay(theTime());
-
-
preLR = LR;
-
preLG = LG;
-
preLB = LB;
-
preRR = RR;
-
preRG = RG;
-
preRB = RB;
-
-
}
This code means that the LEDs fade from the previous value to the current value, over and over again. At the beginning of the program, the previous values are said to be 0.
I had to use 50 as a lower bound on the random as everything below it looks off
Of course, you could add some features where you check to see if all three are below 50, if they are you would re-reandomize the values and check again. If not, you would send them to the fade function.
So all of this results in a really cool effect where if something gets close to MANOI, then its ‘antennai’ will start changing colours rapidly. Here are some videos:
The next thing now is to have MANOI dance and communicate to the Sanguino, Arduino + Motor shield (for MANOI’s ears), and the Arduino + WaveShield (for music). That would mean that MANOI would have FOUR cores!!
^_^ =)
You can see more photos on flickr.






August 24th, 2009 at 8:50 AM
[...] on last week’s RGB LEDs, it was time to add some motions to MANOI that would suit the carnival-ish [...]