Description
Following up on the rousing success of the blinking LED, this project combines three LED's (red, green, and blue) and a few new programs to allow a user to manipulate the intensity of each LED light.
With the code below, a user may use uppercase letters to increase the brightness of an LED, and lowercase letters to dim it. If the user dims the LED below 0, the LED will jump back to 255. Likewise, brightening over 255 resets the LED to 0.
In addition, I've tried out a few diffusers to improve the combination of colors for a more enjoyable LED experience. The photos are below (a few of them, anyway...couldn't fit much on there.)
Components:
- breadboard
- 3 220 Ohm resistors
- wires (yellow for pins to resistors toward LEDs, blue and black for ground)
- 3 LED (1 blue, 1 red, 1 green)
- Arduino board
- USB cable
- 2 rubber bands for hi-tech stability
- A few diffusers to make the colorful experience even better (ex: a glass bottle-top, my desk's translucent surface)
Code
Below is the modified code.
/*
* Serial RGB LED
* ---------------
* Serial commands control the brightness of R,G,B LEDs
*
* Command structure is "<colorCode><colorVal>", where "colorCode" is
* one of "r","g",or "b" and "colorVal" is a number 0 to 255.
* E.g. "r0" turns the red LED off.
* "g127" turns the green LED to half brightness
* "b64" turns the blue LED to 1/4 brightness
*
* Alternate command structure is "<colorCode>*", where "colorCode" is
* one of "r","g", or "b".
* E.g. "r" increases the red LED brightness by 10
* "rrr" increases the red LED brightness by 30
* "ggb" increases the green LED brightness by 20 and the blue by 10
*
* Created 18 October 2006
* copyleft 2006 Tod E. Kurt <tod@todbot.com
* http://todbot.com/
*
* Adapted 5 September 2007
* copylefter 2007 Ryan Aipperspach <ryanaip@alumni.rice.edu>
*
* Modified 12 September 2007
* Isaac Salier-Hellendag - dish@ischool
* TUI - Assignment #2
*
* Allows user to specify whether to make a given color lighter or darker
* depending on whether the character used is capitalized. For instance:
* R = make red brighter
* r = make red dimmer
*
*/
//include support for manipulating strings.
//for a useful string comparison function, see the bottom of this file... stringsEqual()
#include <stdio.h>
#include <string.h>
char serInString[100]; // array that will hold the different bytes of the string. 100=100characters;
// -> you must state how long the array will be else it won't work properly
char colorCode;
int colorVal;
char whichColor; // identifies which color to modify based on colorCode
boolean intensityDir; // dimmer or brighter? (0=dim, 1=bright)
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 redValue = 127;
int greenValue = 127;
int blueValue = 127;
void setup() {
pinMode(redPin, OUTPUT); // sets the pins as output
pinMode(greenPin, OUTPUT);
pinMode(bluePin, OUTPUT);
Serial.begin(9600);
analogWrite(redPin, redValue); // set them all to mid brightness
analogWrite(greenPin, greenValue); // set them all to mid brightness
analogWrite(bluePin, blueValue); // set them all to mid brightness
Serial.println("Brighten an LED with uppercase letters, dim an LED with lowercase.");
Serial.println("For example, 'rrr' will dim the red LED by 30. 'RRR' will brighten it by 30.");
Serial.println("Enter a command:");
}
void loop () {
//read the serial port and create a string out of what you read
readSerialString(serInString, 100);
//UNCOMMENT ONE OF THE FOLLOWING COMMANDS, OR NOTHING WILL HAPPEN WHEN YOU
//RUN THE PROGRAM...
//Uncomment the following line to read commands of the form 'r245' or 'b3'
//processNumericalCommands(serInString);
//Uncomment the following line to read commands of the form 'rrrb'
processRepeatKeyCommands(serInString, 100);
//Erase anything left in the serial string, preparing it for the
//next loop
resetSerialString(serInString, 100);
delay(100); // wait a bit, for serial data
}
void resetSerialString (char *strArray, int length) {
for (int i = 0; i < length; i++) {
strArray[i] = '\0';
}
}
//read a string from the serial and store it in an array
//you must supply the array variable
void readSerialString (char *strArray, int maxLength) {
int i = 0;
if(!Serial.available()) {
return;
}
while (Serial.available() && i < maxLength) {
strArray[i] = Serial.read();
i++;
}
}
//go through the string, and increase the red value for each 'r',
//the green value for each 'g', and the blue value for each 'b'.
//For example "rrrg" increases red by 30 and green by 10.
void processRepeatKeyCommands(char *strArray, int maxLength) {
int i = 0;
int adjustment = 0;
//loop through the string (strArray)
//i = the current position in the string
//Stop when either (a) i reaches the end of the string or
// (b) there is an empty character '\0' in the string
while (i < maxLength && strArray[i] != '\0') {
//Read in the character at position i in the string
colorCode = serInString[i];
switch(colorCode) {
case 'R' :
case 'G' :
case 'B' : intensityDir = 1; break;
case 'r' :
case 'g' :
case 'b' : intensityDir = 0; break;
}
if(intensityDir == 0) {
adjustment = -10;
} else {
adjustment = 10;
}
whichColor = colorCode;
if(whichColor == 'R') { whichColor = 'r'; }
if(whichColor == 'G') { whichColor = 'g'; }
if(whichColor == 'B') { whichColor = 'b'; }
// Red
if (whichColor == 'r') {
redValue = redValue + adjustment;
if(redValue <= 0) { // If value drops below zero, reset at 255.
redValue = 255;
} else {
redValue = redValue % 255;
}
analogWrite(redPin, redValue);
Serial.print("setting color r to ");
Serial.println(redValue);
// Green
} else if (whichColor == 'g') {
greenValue = greenValue + adjustment;
if(greenValue <= 0) {
greenValue = 255;
} else {
greenValue = greenValue % 255;
}
analogWrite(greenPin, greenValue);
Serial.print("setting color g to ");
Serial.println(greenValue);
// Blue
} else if (whichColor == 'b') {
blueValue = blueValue + adjustment;
if(blueValue <= 0) {
blueValue = 255;
} else {
blueValue = blueValue % 255;
}
analogWrite(bluePin, blueValue);
Serial.print("setting color b to ");
Serial.println(blueValue);
}
//Move on to the next character in the string
//From here, the code continues executing from the "while" line above...
i++;
}
}
//change the value of the red, green, or blue LED according to the command received.
//for example, r240 sets the red LED to the value 240 (out of 255)
void processNumericalCommands(char *strArray) {
//read in the first character in the string
colorCode = serInString[0];
//if the first character is r (red), g (green) or b (blue), do the following...
if( colorCode == 'r' || colorCode == 'g' || colorCode == 'b' ) {
//convert the string to an integer
//(start at the second character, or the beginning of the string '+1')
colorVal = atoi(serInString+1);
Serial.print("setting color ");
Serial.print(colorCode);
Serial.print(" to ");
Serial.print(colorVal);
Serial.println();
if(colorCode == 'r')
analogWrite(redPin, colorVal);
else if(colorCode == 'g')
analogWrite(greenPin, colorVal);
else if(colorCode == 'b')
analogWrite(bluePin, colorVal);
}
}
//compare two strings to see if they are equal
//compares the first 'numCharacters' characters of string1 and string2 to
//see if they are the same
//
//E.g. stringsEqual("hello","hello",5) => true
// stringsEqual("hello","helaabbnn",3) => true
// stringsEqual("hello","helaa",5) => false
boolean stringsEqual(char *string1, char *string2, int numCharacters) {
if (strncmp(string1, string2, numCharacters) == 0) {
return true;
} else {
return false;
}
}
My photos are available on Flickr:
http://www.flickr.com/photos/46877131@N00/sets/72157601991831437