Code cleanup:
All the light modes have been moved to separate functions.
Replaced a couple of "If, then..." with "Switch, Case", makes the code somewhat easier to read.
New features:
Added two light modes - cycleColor and lightMyFire.
Speed of pulsateColor and cycleColor now controlled via potentiometer.
Download the source code here.
Source code formatted for blogger by: formatmysourcecode.blogspot.com
/*
RGB LED controller
4 modes: off, color select, color pulse and random cycle/pulse
By Markus Ulfberg 2009-05-19
Updated to Version 2 - 2010-01-13 (Not publicly released)
Updated to Version 3 - 2011-12-14
Thanks to: Ladyada, Tom Igoe and
everyone at the Arduino forum for excellent
tutorials and everyday help.
TODO:
1. Use millis for debounce instead of delay.
*/
// set the ledPins
int ledRed = 10;
int ledGreen = 9;
int ledBlue = 11;
// color selector pin
int potPin = 1;
// lightMode selector
int switchPin = 2;
// light mode variable
// initial value 0 = off
int lightMode = 0;
// LED Power variables
byte redPwr = 0;
byte greenPwr = 0;
byte bluePwr = 0;
// Variables for lightMode 2
// variables for keeping pulse color
byte redPulse;
byte greenPulse;
byte bluePulse;
int pulseSpeed;
// Set pulse to down initially
byte pulse = 0;
// floating variables needed to be able to pulse a fixed color
float redFloat;
float greenFloat;
float blueFloat;
// the amount R,G & B should step up/down to display an fixed color
float redKoff;
float greenKoff;
float blueKoff;
// Variables for lightMode 3
// set the initial random colors
byte redNew = random(255);
byte greenNew = random(255);
byte blueNew = random(255);
// Variables for cycleColor
int truColor = 0;
// misc interface variables
// potVal store the value of the potentiometer for various needs
int potVal;
// value from the button (debounce)
int switchVal;
int switchVal2;
// buttonState registers if the button has changed
int buttonState;
void setup()
{
pinMode(ledRed, OUTPUT);
pinMode(ledGreen, OUTPUT);
pinMode(ledBlue, OUTPUT);
pinMode(potPin, INPUT);
pinMode(switchPin, INPUT);
buttonState = digitalRead(switchPin);
// serial for debugging purposes only
Serial.begin(9600);
}
void loop()
{
switchVal = digitalRead(switchPin); // read input value and store it in val
delay(10); // 10 milliseconds is a good amount of time
switchVal2 = digitalRead(switchPin); // read the input again to check for bounces
if (switchVal == switchVal2) { // make sure we got 2 consistant readings!
if (switchVal != buttonState) { // the button state has changed!
if (switchVal == LOW) { // check if the button is pressed
switch (lightMode) { // light is off
case 0:
lightMode = 1; // light is on and responds to pot
break;
case 1:
lightMode = 2; // light pulsates in the latest color from pot
break;
case 2:
lightMode = 3; // light cycles thru colors
break;
case 3:
lightMode = 4; // light changes randomly
break;
case 4:
lightMode = 5; // simulated fire
break;
case 5:
lightMode = 0; // light is off
break;
} // END switch (lightMode)
} // END if (switchVal == LOW)
} // END if (switchVal != buttonState)
buttonState = switchVal; // save the new state in our variable
} // END if (switchVal == switchVal2)
/*
// Debug
Serial.print("lightMode: ");
Serial.println(lightMode);
*/
switch (lightMode) {
case 0:
lightsOff();
break;
case 1:
colorControl();
break;
case 2:
pulsateColor();
break;
case 3:
cycleColor();
break;
case 4:
randomColor();
break;
case 5:
lightMyFire();
break;
}
} // END loop()
// lightMode 0
void lightsOff() {
redPwr = 0;
greenPwr = 0;
bluePwr = 0;
colorDisplay();
}
// lightMode 1
void colorControl() {
// read the potentiometer position
potVal = analogRead(potPin);
// RED > ORANGE > YELLOW
if (potVal > 0 && potVal < 170) {
redPwr = 255;
bluePwr = 0;
greenPwr = map(potVal, 0, 170, 0, 255);
}
// YELLOW > LIME?? > GREEN
if (potVal > 170 && potVal < 341) {
greenPwr = 255;
bluePwr = 0;
redPwr = map(potVal, 341, 170, 0, 255);
}
// GREEN > TURQOUISE
if (potVal > 341 && potVal < 511) {
greenPwr = 255;
redPwr = 0;
bluePwr = map(potVal, 341, 511, 0, 255);
}
// TURQOUISE > BLUE
if (potVal > 511 && potVal < 682) {
bluePwr = 255;
redPwr = 0;
greenPwr = map(potVal, 682, 511, 0, 255);
}
// BLUE > PURPLE
if (potVal > 682 && potVal < 852) {
bluePwr = 255;
greenPwr = 0;
redPwr = map(potVal, 682, 852, 0, 255);
}
// PURPLE > RED
if (potVal > 852 && potVal < 1023) {
redPwr = 255;
greenPwr = 0;
bluePwr = map(potVal, 1023, 852, 0, 255);
}
redFloat = float(redPwr);
greenFloat = float(greenPwr);
blueFloat = float(bluePwr);
redKoff = redFloat / 255;
greenKoff = greenFloat / 255;
blueKoff = blueFloat / 255;
redPulse = redPwr;
greenPulse = greenPwr;
bluePulse = bluePwr;
/*
// Debug
Serial.print("redFLoat: ");
Serial.print(redFloat, DEC);
Serial.print(" redPwr: ");
Serial.print(redPwr, DEC);
Serial.print(" greenFloat: ");
Serial.print(greenFloat, DEC);
Serial.print(" greenPwr: ");
Serial.print(greenPwr, DEC);
Serial.print(" blueFloat: ");
Serial.print(blueFloat, DEC);
Serial.print(" bluePwr: ");
Serial.println(bluePwr, DEC);
// End debug
*/
// Display colors
colorDisplay();
}
// lightMode 2
void pulsateColor() {
// get colors from colorControl
redPwr = int(redFloat);
greenPwr = int(greenFloat);
bluePwr = int(blueFloat);
// Read speed from potentiometer
pulseSpeed = analogRead(potPin);
pulseSpeed = map(pulseSpeed, 0, 1023, 0, 255);
//display the colors
colorDisplay();
// set speed of change
delay(pulseSpeed);
// pulse down
if (pulse == 0) {
if (redFloat > 10) {
redFloat = redFloat - redKoff;
}
if (greenFloat > 10) {
greenFloat = greenFloat - greenKoff;
}
if (blueFloat > 10) {
blueFloat = blueFloat - blueKoff;
}
// If all xFloat match 10 get pulse up
if (byte(redFloat) <= 10) {
if (byte(greenFloat) <= 10) {
if (byte(blueFloat) <= 10) {
pulse = 1;
}
}
}
}
// Pulse up
if (pulse == 1) {
if (redFloat < redPulse) {
redFloat = redFloat + redKoff;
}
if (greenFloat < greenPulse) {
greenFloat = greenFloat + greenKoff;
}
if (blueFloat < bluePulse) {
blueFloat = blueFloat + blueKoff;
}
// If all Pwr match Pulse get pulse down
if (byte(redFloat) == redPulse) {
if (byte(greenFloat) == greenPulse) {
if (byte(blueFloat) == bluePulse) {
pulse = 0;
}
}
}
}
/*
// Debug
Serial.print("redFloat: ");
Serial.print(redFloat, DEC);
Serial.print(" redPulse: ");
Serial.print(redPulse, DEC);
Serial.print(" greenFloat: ");
Serial.print(greenFloat, DEC);
Serial.print(" greenPulse: ");
Serial.print(greenPulse, DEC);
Serial.print(" blueFloat: ");
Serial.print(blueFloat, DEC);
Serial.print(" bluePulse: ");
Serial.print(bluePulse, DEC);
Serial.print(" pulse: ");
Serial.println(pulse, DEC);
// End debug
*/
} // pulsateColor END
// lightMode 3
void cycleColor() { // Cycles through colors
switch(truColor) {
// RED > ORANGE > YELLOW
case 0:
redPwr = 255;
bluePwr = 0;
greenPwr++;
if (greenPwr > 254) {
truColor = 1;
}
break;
// YELLOW > LIME?? > GREEN
case 1:
greenPwr = 255;
bluePwr = 0;
redPwr--;
if (redPwr < 1) {
truColor = 2;
}
break;
// GREEN > TURQOUISE
case 2:
greenPwr = 255;
bluePwr++;
redPwr = 0;
if (bluePwr > 254) {
truColor = 3;
}
break;
// TURQOUISE > BLUE
case 3:
greenPwr--;
bluePwr = 255;
redPwr = 0;
if (greenPwr < 1) {
truColor = 4;
}
break;
// BLUE > PURPLE
case 4:
greenPwr = 0;
bluePwr = 255;
redPwr++;
if (redPwr > 254) {
truColor = 5;
}
break;
// PURPLE > RED
case 5:
greenPwr = 0;
bluePwr--;
redPwr = 255;
if (bluePwr < 1) {
truColor = 0;
}
break;
}
// START SPEED
pulseSpeed = analogRead(potPin);
pulseSpeed = map(pulseSpeed, 0, 1023, 0, 255);
//display the colors
colorDisplay();
// set speed of change
delay(pulseSpeed);
// END SPEED
} // END cycleColor
// lightMode 4
void randomColor() { // randomize colorNew and step colorPwr to it
if (redPwr > redNew) {
redPwr--;
}
if (redPwr < redNew) {
redPwr++;
}
if (greenPwr > greenNew) {
greenPwr--;
}
if (greenPwr < greenNew) {
greenPwr++;
}
if (bluePwr > blueNew) {
bluePwr--;
}
if (bluePwr < blueNew) {
bluePwr++;
}
// If all Pwr match New get new colors
if (redPwr == redNew) {
if (greenPwr == greenNew) {
if (bluePwr == blueNew) {
redNew = random(254);
greenNew = random(254);
blueNew = random(254);
}
}
}
// display the colors
colorDisplay();
// Set speed of change
delay(20);
} // END randomColor
// lightMode 5
void lightMyFire() {
// Flicker will determine how often a fast flare will occur
int flicker;
// set flicker randomness
flicker = random(800);
// Set random colors,
// constrain green to red and blue to green
// in order to stay within a red, blue, white spectrum
redPwr = random(220, 240);
greenPwr = random(180, 200);
// when flicker occur, the colors shine brighter
// adding blue creates a white shine
if (flicker > 750) {
redPwr = 254;
greenPwr = random(200, 230);
bluePwr = random(0, 50);
} else {
bluePwr = 0;
}
// display Colors
colorDisplay();
// Set speed of fire
delay(20);
} // END lightMyFire
// Displays the colors when called from other functions
void colorDisplay() {
analogWrite(ledRed, redPwr);
analogWrite(ledGreen, greenPwr);
analogWrite(ledBlue, bluePwr);
}