User login

Powered by Drupal, an open source content management system

Theory and Practice of Tangible User Interfaces

Mixing LED colors with serial input

Submitted by nick on Wed, 09/17/2008 - 15:17

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

  • Red, green, and blue LEDs
  • Arduino board w/USB cable
  • 3 220-ohm resistors
  • Breadboard and wires
  • Ping-pong ball
  • Wax paper

 

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);
}