Assignment: Digital I/O with Arduino Boards + Diffuser
Collaborators:
Description
In this lab, we use 3 LEDs to create combine primary light colors. The user can enter color values through a serial interface to vary the intensity of each LED, effectively mixing custom colors.
I used a combination of a ping-pong ball and crumpled wax paper to diffuse the light from the 3 LEDs. I also wrote two programs; one takes strings with any combination of "r"s, "g"s, and "b"s, incrementing each LED's brightness by 10% for each instance of its letter, while the other takes 6-character hexidecimal codes (familiar to web developers) and translates them into brightness values.
Components Used
Arduino Code: Repeated Characters
/*
* 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
*
* Created 18 October 2006
* copyleft 2006 Tod E. Kurt <tod@todbot.com
* http://todbot.com/
*/
char serInString[30]; // 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 rPercent;
int gPercent;
int bPercent;
int inputLen;
int redPin = 11; // Red LED, connected to digital pin 9
int greenPin = 9; // Green LED, connected to digital pin 10
int bluePin = 10; // Blue LED, connected to digital pin 11
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
analogWrite(greenPin, 127); // set them all to mid brightness
analogWrite(bluePin, 127); // set them all to mid brightness
Serial.println("enter color command (e.g. 'rrrggb') :");
}
void loop () {
// set all to 0
rPercent = 0;
gPercent = 0;
bPercent = 0;
//read the serial port and create a string out of what you read
readSerialString(serInString);
if (serInString[0]) {
for (int i=0; i<inputLen; i++) {
colorCode = serInString[i];
// look for appropriate chars (ignore others)
switch(colorCode) {
case 'r':
rPercent += 10;
break;
case 'g':
gPercent += 10;
break;
case 'b':
bPercent += 10;
break;
}
}
rPercent = min(rPercent, 100);
gPercent = min(gPercent, 100);
bPercent = min(bPercent, 100);
// turn percents into values
Serial.print("setting color to ");
Serial.print(rPercent);
Serial.print("% red, ");
Serial.print(gPercent);
Serial.print("% green, ");
Serial.print(bPercent);
Serial.print("% blue");
Serial.println();
serInString[0] = 0; // indicates we've used this string
// set each led
analogWrite(redPin, rPercent * 255 / 100);
analogWrite(greenPin, gPercent * 255 / 100);
analogWrite(bluePin, bPercent * 255 / 100);
}
delay(100); // wait a bit, for serial data
}
//read a string from the serial and store it in an array
//you must supply the array variable
void readSerialString (char *strArray) {
inputLen = 0;
if(!Serial.available()) {
return;
}
while (Serial.available()) {
strArray[inputLen] = Serial.read();
inputLen++;
}
}
Arduino Code: Hex Values
/*
* 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
*
* Created 18 October 2006
* copyleft 2006 Tod E. Kurt <tod@todbot.com
* http://todbot.com/
*/
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 colorCode1;
char colorCode2;
int colorVal;
int redPin = 11; // Red LED, connected to digital pin 9
int greenPin = 9; // Green LED, connected to digital pin 10
int bluePin = 10; // Blue LED, connected to digital pin 11
int pins[] = {redPin, greenPin, bluePin};
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
analogWrite(greenPin, 127); // set them all to mid brightness
analogWrite(bluePin, 127); // set them all to mid brightness
Serial.println("enter color command (e.g. 'ff00cc') :");
}
void loop () {
//read the serial port and create a string out of what you read
readSerialString(serInString);
if (serInString[0]) {
Serial.print("setting color to ");
Serial.print(serInString);
Serial.println();
for (int i=0; i<3; i=i++) {
colorCode1 = serInString[0+(i*2)];
colorCode2 = serInString[1+(i*2)];
colorVal = (convertHex(colorCode1) * 16) + convertHex(colorCode2);
Serial.print(colorCode1);
Serial.print(colorCode2);
Serial.print(" ");
Serial.print(colorVal);
Serial.println();
analogWrite(pins[i], colorVal);
}
serInString[0] = 0;
}
delay(100); // wait a bit, for serial data
}
//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 character from hex to decimal
int convertHex(char c) {
char hexes[7] = "abcdef";
for (int x=0; x<7; x++) {
if (c == hexes[x]) return 10 + x;
}
int r = max(0, c-48);
return min(15, r);
}