Description
PART 1: Find a good diffuser for your RGB LEDs. I experimented with a few items before settling on my homemade diffuser. I tried shaping some plastic sheets around the LEDS and then I tried folding two large bubbles from plastic packing bubble wrap but none of these achieved a diffusion that I was happy with. I believe that part of this reason was because they were too close to the LEDS. So, I ended up cutting, folding, and taping a cardboard toilet paper roll so it would have a smaller circumference but still balance and stand up by itself on the breadboard. Then, I tried using the cap to my water bottle but it was a bit too small and a bit too solid white. I finally found the perfect top: while recycling my drink in the master's lounge I spotted a Vitamin Water cap which was larger and more opaque than my previous cap and is the one I ended up using.
PART 2: I changed the code so I can control the RGB values with multiple key presses of r, g, and b. Each press of a letter corresponds to 10% brightness (25), so rr = brightness of 50, rrg = brightness 50 red, 25 green.
PART 3: I then changed the code so I could control the colors produced by the LEDs by typing in the color name like "purple" or "cyan."
Note: All three different command structures for entering input can be used in the same run of a program (so no code needs to be commented out/commented back in and the program does not have to be re-uploaded), but each input line must be of the same structure/format.
Components Used
1 red, 1 blue, and 1 green LED (Light Emitting Diode)
3 20-ohm resistors (red, red, brown, gold)
Arduino Code
/*
* Serial RGB LED
* ---------------
* Serial commands control the brightness of R,G,B LEDs
* All 3 modes (with diff. command structures) work simultaneously
*
* Mode 1
* 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
*
* Homework - Lab 2
*
* Mode 2
* Create alternate command structure: "<colorCode>*"
* each press of a letter corresponds to 10% brightness (25)
* so rr = brightness of 50, rrg = brightness 50 red, 25 green
*
* Mode 3
* Create alternate command structure: "<color name>"
* when enter "purple" it will produce the color purple
* when you enter "cyan" it will produce teh color cyan
*
* Created 18 October 2006
* copyleft 2006 Tod E. Kurt <tod@todbot.com
* http://todbot.com/
*/
//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;
char valTwo = 0;
int colorVal = 0;
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 redVal = 0;
int blueVal = 0;
int greenVal = 0;
void setup() {
pinMode(redPin, OUTPUT); // sets the pins as output
pinMode(greenPin, OUTPUT);
pinMode(bluePin, OUTPUT);
Serial.begin(9600);
analogWrite(redPin, 127); // set them all to mid brightness
redVal = 127;
analogWrite(greenPin, 127); // set them all to mid brightness
greenVal = 127;
analogWrite(bluePin, 127); // set them all to mid brightness
blueVal = 127;
Serial.println("enter color command");
Serial.println("acceptable formats: 'r043' 'rrgb' 'purple' 'cyan') :");
}
void loop () {
//read the serial port and create a string out of what you read
readSerialString(serInString); // store what read in array serInString
// with MODE 1 and MODE 2 colorCode will be r, g, or b
// with MODE 3 colorCode can be any char making a word (color)
colorCode = serInString[0];
// with MODE 1 valTwo will be a number
// with MODE 2 valTwo will be r, g, or b
// with MODE 3 valTwo will be some other char making a word (color)
valTwo = serInString[1];
// if colorCode != r, g, or b then go to MODE 3, otherwise:
if( colorCode == 'r' || colorCode == 'g' || colorCode == 'b' ) {
// if the second char = r, g or b then MODE 2:
if ( valTwo == 'r' || valTwo == 'g' || valTwo == 'b' || valTwo == '\0' ) {
int x = 0;
// while string still has new data (not null)
while ( serInString[x] != '\0' && x < 100 ){
colorCode = serInString[x];
// increase brightness of red by 10% (25)
if ( colorCode == 'r' ) {
redVal = (redVal + 25) % 255;
analogWrite(redPin, redVal);
Serial.print("setting color r to ");
Serial.println(redVal);
}
// increase brightness of green by 10% (25)
else if ( colorCode == 'g' ) {
greenVal = (greenVal + 25) % 255;
analogWrite(greenPin, greenVal);
Serial.print("setting color g to ");
Serial.println(greenVal);
}
// increase brightness of blue by 10% (25)
else if ( colorCode == 'b' ) {
blueVal = (blueVal + 25) % 255;
analogWrite(bluePin, blueVal);
Serial.print("setting color b to ");
Serial.println(blueVal);
}
// move to next character to evaluate
x++;
}
}
// otherwise, Mode 1:
else {
colorVal = atoi(serInString+1); // converts string to integer
Serial.print("setting color ");
Serial.print(colorCode);
Serial.print(" to ");
Serial.print(colorVal);
Serial.println();
serInString[0] = 0; // indicates we've used this string
if(colorCode == 'r') {
analogWrite(redPin, colorVal);
redVal = colorVal;
}
else if(colorCode == 'g') {
analogWrite(greenPin, colorVal);
greenVal = colorVal;
}
else if(colorCode == 'b') {
analogWrite(bluePin, colorVal);
blueVal = colorVal;
}
}
}
// MODE 3
else {
// make purple (or blue violet apparently)
if ( stringsEqual(serInString, "purple", 6) ) {
redVal = 138;
greenVal = 43;
blueVal = 226;
analogWrite(redPin, redVal);
analogWrite(bluePin, blueVal);
analogWrite(greenPin, greenVal);
Serial.println("setting color to purple ( r = 138, g = 43, b = 226)");
}
// make cyan
if ( stringsEqual(serInString, "cyan", 4) ) {
redVal = 0;
greenVal = 255;
blueVal = 255;
analogWrite(redPin, redVal);
analogWrite(bluePin, blueVal);
analogWrite(greenPin, greenVal);
Serial.println("setting color to cyan (r = 0, g = 255, b = 255)");
}
}
// reset variables
// colorVal = 0;
// reset string - prepare it for new input data
resetSerialString(serInString, 100);
delay(100); // wait a bit, for serial data
}
// erase all data in string to make it fresh
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 i = 0;
if(!Serial.available()) {
return;
}
while (Serial.available()) {
strArray[i] = Serial.read();
i++;
}
}
//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;
}
}
Item
breadboard wired with red, blue, and green LEDs
homemade diffuser
diffuser, in action
Comments
GSI Comments
Nice work! And nice write-up. Very clear description of what you did -- The description about how you made your diffuser is good in that it talks about what did and what did not work, which can help others learn. It looks like you put a lot of effort into the code, too.