Assignment
1) Find a good diffuser for your RGB LEDs (e.g. ping pong ball, Styrofoam, etc).
2) Change the code so that you can control the RGB values with multiple
key presses. For example, pressing ‘r’ 5 times will set the brightness
to 50% (or brightness = 127) and pressing ‘r’ 10 times will set it to
100% (or brightness = 255).
3) (Optional) Come up with other ways of controlling the colors of the
LEDs using the keyboard. Here’s your chance to be creative. You can
show off to your friends next week. Example: Read colors and set the
appropriate RGB values like “orange” might set r=70%, g=50%, and b=0%.
Components Used
Homemade Diffuser
Light Emitting Diodes (RGB)
Resistors
Code
For part 2 of the assignment:
/*
* 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>
*
*/
//include support for manipulating strings.
//for a useful string comparison function, see the bottom of this file... stringsEqual()
#include <stdio.h>
#include <string.h>
#include <math.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;
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
float redValue = 0;
float greenValue = 0;
float blueValue = 0;
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("enter color command (e.g. 'r43 or rrrrrrrrbbbb') :");
}
void loop () {
//read the serial port and create a string out of what you read
readSerialString(serInString, 100);
//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;
//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];
//If the character is r (red)...
if (colorCode == 'r') {
//Increase the current red value by 10, and if you reach 255 go back to 0
redValue = (redValue + 25.5);
if (redValue >= 255) {redValue = 0;}
analogWrite(redPin, ((int)redValue % 255));
Serial.print("setting color r to ");
Serial.println((int)redValue);
//If the character is g (green)...
} else if (colorCode == 'g') {
greenValue = (greenValue + 25.5);
if (greenValue >= 255) {greenValue = 0;}
analogWrite(greenPin, ((int)greenValue % 255));
Serial.print("setting color g to ");
Serial.println((int)greenValue);
//If the character is b (blue)...
} else if (colorCode == 'b') {
blueValue = (blueValue + 25.5);
if (blueValue >= 255) {blueValue = 0;}
analogWrite(bluePin, ((int)blueValue % 255));
Serial.print("setting color b to ");
Serial.println((int)blueValue);
}
//Move on to the next character in the string
//From here, the code continues executing from the "while" line above...
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;
}
}
PART 3
/*
* 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>
*
*/
//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;
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
float redValue = 0;
float greenValue = 0;
float blueValue = 0;
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("enter color command (e.g. 'r43 or rrrrrrrrbbbb') :");
}
void loop () {
//read the serial port and create a string out of what you read
readSerialString(serInString, 100);
//Uncomment the following line to read commands of the form 'rrrb'
//processRepeatKeyCommands(serInString, 100);
processColorCommand(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++;
}
}
/*
Two commands to create distinct colors.
This is a great idea, but it would be more interesting to have it tied directly
to some other process, like a mood measurement or maybe a digital color meter.
In any case here's something that works.
*/
void processColorCommand(char *strArray, int maxLength) {
if (stringsEqual(strArray, "purple", 6)) {
analogWrite(redPin, 225);
analogWrite(greenPin, 0);
analogWrite(bluePin, 255);
}
else if (stringsEqual(strArray, "turquoise", 9)) {
analogWrite(redPin, 0);
analogWrite(greenPin, 154);
analogWrite(bluePin, 192);
}
}
//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;
}
}
Image
n8agrin_3leds
Comments
GSI Comments
Looks good. I agree with your comment that it would be cool to connect the color to some kind of sensor (like mood). In fact, that's basically all there is to the Ambient Orb!
The diffuser looks like it mixes the different colors pretty well. It would be interesting to think about how you could increase the size to create a larger ambient object. Or, you could think about how to channel the light into a focused point (like a color-changing flashlight...).