Lab submission 2 - Serial communication and LED light diffuser
Description
A light diffuser was designed for three LEDs on an arduino board. It imitates a snow globe using soap water and parmesan cheese (details of the materials used are below). Two application was implemented: controlling the RGB values with multiple key presses (code 1) and trigonometric gradation on continuous time change (code 2, optional).
The first application counts the numbers of three characters of R, G, and B (case insensitive) to decide each LED's brightness. Each appearance of the letters is translated into 10% of the maximum brightness. For example, a string input of rrrbgggrr has five Rs, three Gs, and one B to represent 50% of R, 30% of G, and 10% of B.
The second application continuously grades the three LEDs' brightness according to trigonometric modulations (sin for red, cos for green, and tan for blue) with a parameter of time. To keep the values between 0 to 255, avoiding negative values and infinity, the trigonometric functions were applied as follows. This guarantees the results are available for the LEDs' brightness.
// LEDs' brightness follows Trigonometry
rVal = abs(sin(t) * 255);
gVal = abs(cos(t) * 255);
bVal = abs(tan(t) * 255);
// avoiding INFINITY of tan(t)
if(abs(tan(t))>1) bVal = 255;
Video Demo
http://youtu.be/oI0XnRJqYTA
Components Used
For arduino:
- 1 red LED
- 1 green LED
- 1 blue LED
- 3 220 ohm resistor
- 1 Arduino Uno board
For a diffuser:
- 1 water bottle
- 1 piece of silver paper (from pepperidge farm cookie bag)
- 1 pack of parmesan cheese
- 1/2 toilet paper tube
Code 1:
The code is based on an example code.
/*
* Serial RGB LED
* ---------------
* Serial commands control the brightness of R,G,B LEDs
*
* Command structure is "<colorVal><colorVal>", where "colorVal" 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
int redPin = 10; // Red LED, connected to digital pin 9
int greenPin = 11; // Green LED, connected to digital pin 10
int bluePin = 9; // Blue LED, connected to digital pin 11
// flag for a new input string
boolean valueChanged = false;
// counters for input characters
int rCnt = 0;
int gCnt = 0;
int bCnt = 0;
// brightness values for LEDs
int rVal = 0;
int gVal = 0;
int bVal = 0;
void setup() {
pinMode(redPin, OUTPUT); // sets the pins as output
pinMode(greenPin, OUTPUT);
pinMode(bluePin, OUTPUT);
Serial.begin(9600);
analogWrite(redPin, 0); // turn off red LED
analogWrite(greenPin, 0); // turn off green LED
analogWrite(bluePin, 0); // turn off blue LED
Serial.println("enter color command (e.g. 'rrrggbbbbbrrbbbg') :");
}
void loop () {
// clear the string
memset(serInString, 0, 100);
//read the serial port and create a string out of what you read
readSerialString(serInString);
// calculate values again only when a new input string comes in
if(valueChanged) {
rVal = 255 * rCnt / 10;
gVal = 255 * gCnt / 10;
bVal = 255 * bCnt / 10;
}
// analog output
analogWrite(redPin, rVal);
analogWrite(greenPin, gVal);
analogWrite(bluePin, bVal);
delay(100); // wait a bit, for serial data
if(valueChanged) {
// console output on the last input
Serial.print("r: ");
Serial.print(rCnt * 10);
Serial.print("%");
Serial.println();
Serial.print("g: ");
Serial.print(gCnt * 10);
Serial.print("%");
Serial.println();
Serial.print("b: ");
Serial.print(bCnt * 10);
Serial.print("%");
Serial.println();
Serial.println();
// ready for a new input
Serial.println("enter color command (e.g. 'rrrggbbbbbrrbbbg') :");
}
valueChanged = false;
rCnt = 0;
gCnt = 0;
bCnt = 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();
// counts the numbers of 'r', 'g', 'b'
char c = strArray[i];
if(c=='r' || c=='R') {
rCnt++;
if(rCnt>10) rCnt = 10;
valueChanged = true;
}
else if(c=='g' || c=='G') {
gCnt++;
if(gCnt>10) gCnt = 10;
valueChanged = true;
}
else if(c=='b' || c=='B') {
bCnt++;
if(bCnt>10) bCnt = 10;
valueChanged = true;
}
else { // ignoring other input characters
}
i++;
}
}
Code 2:
The code is based on an example code.
/*
* Serial RGB LED
* ---------------
* Serial commands control the brightness of R,G,B LEDs
*
* Command structure is "<colorVal><colorVal>", where "colorVal" 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/
*/
int redPin = 10; // Red LED, connected to digital pin 9
int greenPin = 11; // Green LED, connected to digital pin 10
int bluePin = 9; // Blue LED, connected to digital pin 11
// brightness values for LEDs
double rVal = 0;
double gVal = 0;
double bVal = 0;
float t = 0.0f;
void setup() {
pinMode(redPin, OUTPUT); // sets the pins as output
pinMode(greenPin, OUTPUT);
pinMode(bluePin, OUTPUT);
Serial.begin(9600);
rVal = sin(t);
gVal = cos(t);
bVal = tan(t);
analogWrite(redPin, rVal); // turn off red LED
analogWrite(greenPin, gVal); // turn off green LED
analogWrite(bluePin, bVal); // turn off blue LED
}
void loop () {
// LEDs' brightness follows Trigonometric modulation
rVal = abs(sin(t) * 255);
gVal = abs(cos(t) * 255);
bVal = abs(tan(t) * 255);
// avoiding INFINITY of tan(t)
if(abs(tan(t))>1) bVal = 255;
// analog output
analogWrite(redPin, rVal);
analogWrite(greenPin, gVal);
analogWrite(bluePin, bVal);
delay(100); // wait a bit, for serial data
t += 0.03;
if(t>PI) t = 0;
}
- Login to post comments
Drupal theme by Kiwi Themes.