Lab 2: Diffuser
Description
Use the Arduino to input the name of a color from serial, and then set the intensities of red, blue, and green light emitting diodes to match. Create a diffuser to evenly blend the light together.
Components Used
- 3 Light Emitting Diode (LED)
- 3 Resistors
- 1 Styrofoam cup
- 1 Coffee filter
Arduino Code
/*
* Text-based color dimmer
* ---------------
* Serial text commands control the brightness of R,G,B LEDs
*
* Command structure is "<colorText>", where "colorText" is
* a lowercase color
* E.g. "red" turns the red LED on to full brightness.
* "magenta" turns the red and blue LEDs on to full brightness
* "indigo" turns the red LED to 1/3 brightness, blue LED to 1/2 brightness
*
* Created 5 Feb 2011
* CC-BY 2011 R.Stuart Geiger, stuart@stuartgeiger.com
*
* Based on code by:
* copyleft 2006 Tod E. Kurt <tod@todbot.com
* http://todbot.com/ */
char serInString[20];
char colorCode[20];
char colorName[20];
int colorVal;
int redPin = 10; // Red LED, connected to digital pin 9
int greenPin = 9; // Green LED, connected to digital pin 10
int bluePin = 11; // Blue LED, connected to digital pin 11
int rDec=0;
int bDec=0; //intensity of the target color's R,G,B values in decimal, 0-255
int gDec=0;
int rDecPrev=0;
int bDecPrev=0; //intensity of the previous color's R,G,B values in decimal, 0-255
int gDecPrev=0;
void setup() {
pinMode(redPin, OUTPUT); // sets the pins as output
pinMode(greenPin, OUTPUT);
pinMode(bluePin, OUTPUT);
Serial.begin(9600); // Tried to TURN IT UP TO 11(5200) for faster fades. Bad idea.
analogWrite(redPin, 255); // set them all to full brightness
analogWrite(greenPin, 255); // set them all to full brightness
analogWrite(bluePin, 255); // set them all to full brightness
Serial.println("enter the name of a color in lowercase (e.g. 'red' or 'cyan') :");
}
void loop () {
// clear all strings
memset(serInString, 0, 20);
memset(colorCode,0,20);
memset(colorName,0,20);
// read the serial port and create a string out of what you read
readSerialString(serInString);
if(serInString[0]>0){ //if we've actually got something coming through the serial...
// copy the input from the serial to two variables
// because we have to use pointers with functions
strcpy(colorCode,serInString);
strcpy(colorName,serInString);
//Call function to turn the color name string into its corresponding HTML hex color
textToRGB(colorCode);
// store old RGB intensity values
rDecPrev=rDec;
gDecPrev=gDec;
bDecPrev=bDec;
// reset RGB intensity values
rDec=0;
gDec=0;
bDec=0;
// step through the hex color string character by character
// why yes, I am a fan of rube goldberg, how did you know?
// okay not really, I just miss python :(
rDec=(16*hexToDec(colorCode[0]))+hexToDec(colorCode[1]);
gDec=(16*hexToDec(colorCode[2]))+hexToDec(colorCode[3]);
bDec=(16*hexToDec(colorCode[4]))+hexToDec(colorCode[5]);
//if there is an error IDing colors, hexToDec will throw a -1 and make something negative
if(rDec>=0 && gDec>=0 && bDec>=0){
// verbosity
Serial.print("setting color ");
Serial.print(colorName);
Serial.print(" to ");
Serial.print(rDec);
Serial.print(" ");
Serial.print(gDec);
Serial.print(" ");
Serial.print(bDec);
Serial.println();
// fade from the previous color to the target color, write the color to pins
while(rDecPrev!=rDec || gDecPrev!=gDec || bDecPrev!=bDec) {
if(rDecPrev > rDec) {rDecPrev--;}
if(gDecPrev > gDec) {gDecPrev--;}
if(bDecPrev > bDec) {bDecPrev--;}
if(rDecPrev < rDec) {rDecPrev++;}
if(gDecPrev < gDec) {gDecPrev++;}
if(bDecPrev < bDec) {bDecPrev++;}
analogWrite(redPin, rDecPrev);
analogWrite(greenPin, gDecPrev);
analogWrite(bluePin, bDecPrev);
// more verbosity
Serial.print("setting color ");
Serial.print(colorName);
Serial.print(" to ");
Serial.print(rDecPrev);
Serial.print(" ");
Serial.print(gDecPrev);
Serial.print(" ");
Serial.print(bDecPrev);
Serial.println();
delay(1);
}
analogWrite(redPin, rDec);
analogWrite(greenPin, gDec);
analogWrite(bluePin, bDec);
Serial.println("----------------------------------------------");
}
else {
Serial.print("I don't know the color:");
Serial.println(colorName);
}
serInString[0] = 0; // apparently this is *really* necessary
}
delay(100); // wait a bit, you've got time
}
//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++;
}
}
//convert a single hex character into its corresponding int value
//this is ridiculous
int hexToDec(char hexChar) {
switch(hexChar) {
case '0':
return 0;
case '1':
return 1;
case '2':
return 2;
case '3':
return 3;
case '4': return 4;
case '5':
return 5;
case '6':
return 6;
case '7':
return 7;
case '8':
return 8;
case '9':
return 9;
case 'A':
return 10;
case 'B':
return 11;
case 'C':
return 12;
case 'D':
return 13;
case 'E':
return 14;
case 'F':
return 15;
}
return -1; //if another character, return error
}
//convert a string containing a color name into its corresponding HTML hex color value
//Taken from list of color names in the HTML spec, from http://www.w3schools.com/html/html_colornames.asp
//not all HTML color values are here, just the good ones
//returns ZZZZZZ if color is not found
void textToRGB(char *colorText) {
char hex[7];
//compare the input string to color names, if it is the same, copy it into temp string
if (strcmp(colorText,"azure") == 0) {
strcpy(hex,"F0FFFF");
}
else if (strcmp(colorText,"beige") == 0) {
strcpy(hex,"F5F5DC");
}
else if (strcmp(colorText,"black") == 0) {
strcpy(hex,"000000");
}
else if (strcmp(colorText,"blue") == 0) {
strcpy(hex,"0000FF");
}
else if (strcmp(colorText,"brown") == 0) {
strcpy(hex,"A52A2A");
}
else if (strcmp(colorText,"crimson") == 0) {
strcpy(hex,"DC143C");
}
else if (strcmp(colorText,"cyan") == 0) {
strcpy(hex,"00FFFF");
}
else if (strcmp(colorText,"gold") == 0) {
strcpy(hex,"FFD700");
}
else if (strcmp(colorText,"gray") == 0) {
strcpy(hex,"808080");
}
else if (strcmp(colorText,"grey") == 0) {
strcpy(hex,"808080");
}
else if (strcmp(colorText,"green") == 0) {
strcpy(hex,"00FF00");
}
else if (strcmp(colorText,"indigo") == 0) {
strcpy(hex,"4B0082");
}
else if (strcmp(colorText,"ivory") == 0) {
strcpy(hex,"FFFFF0");
}
else if (strcmp(colorText,"khaki") == 0) {
strcpy(hex,"F0E68C");
}
else if (strcmp(colorText,"limegreen") == 0) {
strcpy(hex,"32CD32");
}
else if (strcmp(colorText,"maroon") == 0) {
strcpy(hex,"800000");
}
else if (strcmp(colorText,"magenta") == 0) {
strcpy(hex,"FF00FF");
}
else if (strcmp(colorText,"navy") == 0) {
strcpy(hex,"000080");
}
else if (strcmp(colorText,"orange") == 0) {
strcpy(hex,"FFA500");
}
else if (strcmp(colorText,"pink") == 0) {
strcpy(hex,"FFC0CB");
}
else if (strcmp(colorText,"purple") == 0) {
strcpy(hex,"800080");
}
else if (strcmp(colorText,"red") == 0) {
strcpy(hex,"FF0000");
}
else if (strcmp(colorText,"silver") == 0) {
strcpy(hex,"C0C0C0");
}
else if (strcmp(colorText,"skyblue") == 0) {
strcpy(hex,"87CEEB");
}
else if (strcmp(colorText,"violet") == 0) {
strcpy(hex,"EE82EE");
}
else if (strcmp(colorText,"white") == 0) {
strcpy(hex,"FFFFFF");
}
else if (strcmp(colorText,"yellow") == 0) {
strcpy(hex,"FFFF00");
}
else {
strcpy(hex,"ZZZZZZ");
} //if the color isn't listed, throw an error
memset(colorText,0,20);
strcpy(colorText,hex); //pass the hex value back into colorText
return;
}