I have seen this quite a lot around the community, but I thought I would share the code just in case someone needs it - this is just a simple rgb led that fades between random colors (random mixes of red, green, and blue)
Here is a vid:
*note: the vid has the fade time set at a constant, but the code here gives the fade time a random value each time around, if you want a constant value for fade time, just get rid of the "x = random(3, 9);" in the loop, and add "= whatever" to the "int x" at the opening of the code, replacing whatever with a number (good values are between 2 and 15)
CODE:
int pin1 = 3;
int pin2 = 5;
int pin3 = 9;
long value3;
long value2;
long value1;
long current_value3;
long current_value2;
long current_value1;
int x;
void setup(){
randomSeed(analogRead(0));
value1 = random(255);
current_value1 = value1;
value2 = random(255);
current_value2 = value2;
value3 = random(255);
current_value3 = value3;
analogWrite(pin1, current_value1);
analogWrite(pin2, current_value2);
analogWrite(pin3, current_value3);
value1 = random(255);
value2 = random(255);
value3 = random(255);
}
void loop(){
x = random(3, 9);
if (value1 > current_value1){
current_value1++;
analogWrite(pin1, current_value1);
delay(x);
}
if (value1 < current_value1){
current_value1--;
analogWrite(pin1, current_value1);
delay(x);
}
if (value1 == current_value1){
analogWrite(pin1, current_value1);
value1 = random(255);
}
//////////////////////////
if (value2 > current_value2){
current_value2++;
analogWrite(pin2, current_value2);
delay(x);
}
if (value2 < current_value2){
current_value2--;
analogWrite(pin2, current_value2);
delay(x);
}
if (value2 == current_value2){
analogWrite(pin2, current_value2);
value2 = random(255);
}
///////////////////////////////
if (value3 > current_value3){
current_value3++;
analogWrite(pin3, current_value3);
delay(x);
}
if (value3 < current_value3){
current_value3--;
analogWrite(pin3, current_value3);
delay(x);
}
if (value3 == current_value3){
analogWrite(pin3, current_value3);
value3 = random(255);
}
}
Interesting. I did this a few months back and posted up my code to make RGB LED's smoothly transition between random colours, but it has been deleted from the forum !!!! :o
Interesting. I did this a few months back and posted up my code to make RGB LED's smoothly transition between random colours, but it has been deleted from the forum !!!!
But what happens when you want the LEDs to fade more slowly than 1/1024 the speed of your delay()? In other words, what if your increment should be less than 1 per loop?
It looks like all of the algorithms posted here are missing this situation. Of course, you can always just increase the delay() amount.
Let's put this on steroids and say that what we really want is to fade multiple LEDs simultaneously from arbitrary individual colors to other arbitrary colors, and to finish fading at EXACTLY the same time (i.e. the rate of fading must be different with each LED because they may have different "distances" to go).
So each LED is really drawing a line through a 4 dimensional color-and-time space, where the origin is (say) black and each axis corresponds to R, G and B colors. You can do this using floating point math pretty easily using the standard line equation y=mx+b. But to do it efficiently using integers requires a fundamental algorithm called Bresenham's line drawing algorithm (BLDA) Bresenham's line algorithm - Wikipedia which I urge you to look at if you don't know it because it is awesomely useful for highly embedded development!
The code here: Google Code Archive - Long-term storage for Google Code Project Hosting. uses BLDA to implement software based PWM LED dimming across many LEDs driven through an LED driver chip (FlickerBrightness class), and then it uses BLDA to allow arbitrary fading of the LEDs in the ChangeBrightness class (the other class "CCShield" controls the LED driver chip).
Of course, controlling an RGB led is exactly the same as controlling 3 individual LEDs of red, green, and blue colors since RGB leds literally are 3 leds in one package.
In other words, what if your increment should be less than 1 per loop?
Then you use a accumulator with a type float, then an increment of 0.5 or 0.1 or what ever you like.
Then you convert it to an int to set the LED value.
Sorry! I just looked closely at the 1st implementation! I didn't see the float data types at the top of MikeMc's.
I'm new to AVR and so didn't even realize that it supported float types. Actually, I didn't really even bother to look for "float" because they used to be god-awful slow and often simulated since embedded processors used to not contain floating point hardware.
Hmm, I just searched for "float" in the Atmel 168 spec (no hits) and browsed the ALU instruction set summary and it looks like it does not support floating point natively so avr-gcc must be implementing the operations by hand. I wonder how efficient it is. But I guess it doesn't much matter for the OP application that used just one LED.
When I want to fade RGB LEDs between colors, something I am doing pretty often these days, I use some pretty simple math.
LEDChannels[num_leds][3] is a global array containing the information for each LED's red, green, and blue channels. Assume that some other routine (WriteLEDArray()) handles the actual control of the LEDs from the array data.
Some typedefs for colors would make some aspects of this a little easier to read. This code is similar to what I've used before, but this actual snippet hasn't been tested.
void FadeLED(int channel, int steps, int fadedelay, int red1, int green1, int blue1, int red2, int green2, int blue2) {
for (int fadeindex = 0; fadeindex < steps+1; fadeindex++) {
LEDChannels[channel][0] = (red1 * (steps - fadeindex) + red2 * fadeindex)/steps;
LEDChannels[channel][1] = (green1 * (steps - fadeindex) + green2 * fadeindex)/steps;
LEDChannels[channel][2] = (blue1 * (steps - fadeindex) + blue2 * fadeindex)/steps;
WriteLEDArray();
delay(fadedelay);
}
}
Will implemeting Boolean math speed up or slow down the loops? I creaated this small sketch, but don't have the arduino yet to test. It's a little clunky, but it gives a fade between all seven ccolors and Black (All Off) and White (All On). I used Clay Shirky's original program and modified it so I given credit, even though what I end up with is completely different.
/*
* 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
* originally "dimmingLEDs" by Clay Shirky <clay.shirky@nyu.edu>
*/
// Output
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
// Program variables
int redVal = 1; // Variables to store the values to send to the pins
int greenVal = 1; // Initial values are all off
int blueVal = 1;
int i = 0; // Loop counter
int wait = 15; // 50ms (.05 second) delay; shorten for faster fades
void setup()
{
pinMode(redPin, OUTPUT); // sets the pins as output
pinMode(greenPin, OUTPUT);
pinMode(bluePin, OUTPUT);
}
// Main program
void loop()
{
i += 1; // Increment counter
{
redVal =((i<255)*i)+((i>=255)*255)+((i>511)*(512-i))+((i>766)*(i-766))+((i>=1276)*(i-1276))+((i>1530)*(1530-i))+((i>1786)*(1786-i));
greenVal =(i<256)*(1)+(i>255)*(i-255)+(i>510)*(510-i)+(i>1020)*(1020-i)+(i>1274)*(i-1274)+(i>1530)*(i-1531)+(i>1785)*(3571-(2*i));
blueVal =(i<764)*(1)+(i>765)*(i-765)+(i>1020)*(1020-i)+(i>1786)*(1786-i);
}
if (i > 2040) //
{
i = 1;
}
// we do "255-redVal" instead of just "redVal" because the
// LEDs are hooked up to +5V instead of Gnd
analogWrite(redPin, redVal); // Write current values to LED pins
analogWrite(greenPin, greenVal);
analogWrite(bluePin, blueVal);
delay(wait); // Pause for 'wait' milliseconds before resuming the loop
}
Anyway, just looking for the fastest code to run on the Arduino.
But its probably a waste of time. To get an idea, just count every 8-bit operation as "1" except multiplication which is 2, and for 16 bits (int) use 3x (2 8-bit operations & 1 combine operation) that number and maybe 7x for 32 bits (long int). Division is EVIL -- DON'T put in the inner loop if possible! To compare the speed of a look up table relative to arithmetic, count an 8-bit memory reference as "3".
But just let the above give you an intuition. The best choice is to code them and test especially because the translation from C to assembly may not be what you expect or optimal.
int bluePin = 13; // the number of the LED pin
int greenPin = 12; // the number of the LED pin
void setup() // run once, when the sketch starts
{
Serial.begin(9600);
pinMode(bluePin, OUTPUT); // sets the digital pin as output
pinMode(greenPin, OUTPUT); // sets the digital pin as output
}
void loop() // run over and over again
{
int color = random(200);
Serial.println(color);
if (color < 100) {
digitalWrite(bluePin, HIGH);
}
if (color > 100) {
digitalWrite(greenPin, HIGH);
}
delay(100);
digitalWrite(bluePin, LOW); // sets the Green LED off
digitalWrite(greenPin, LOW); // sets the Green LED off
}