User login

Powered by Drupal, an open source content management system

Theory and Practice of Tangible User Interfaces

Lab #2

Submitted by RyanKaufman on Wed, 09/17/2008 - 23:36

Assignment: Digital I/O with Arduino Boards + Diffuser

Collaborators:

 

Description:

Arduino's serial communication allows the keyboard to control the digital input to modulate the pulse width of the light, mimmicking analog brightness.  Using mixtures of the the primary colors and a ping pong ball inside of a glass bulb as a diffuser,  I made a few of the 1000+ colors available.

 

Materials used:

  • Arduino board
  • 3- 220 Ω resistors
  • 3- L.E.D.s
  • wire
  • breadboard
  • computer
  • usb cable
  • ping-pong ball
  • Glass bulb

Code:

For initial input/output settings:  (Unchanged)

// Output
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

// Program variables
int redVal = 255; // Variables to store the values to send to the pins
int greenVal = 1; // Initial values are Red full, Green and Blue off
int blueVal = 1;

int i = 0; // Loop counter
int wait = 50; // 50ms (.05 second) delay; shorten for faster fades
int DEBUG = 0; // DEBUG counter; if set to 1, will write values back via serial

void setup()
{
pinMode(redPin, OUTPUT); // sets the pins as output
pinMode(greenPin, OUTPUT);
pinMode(bluePin, OUTPUT);
if (DEBUG) { // If we want to see the pin values for debugging...
Serial.begin(9600); // ...set up the serial ouput on 0004 style
}
}

// Main program
void loop()
{
i += 1; // Increment counter
if (i < 255) // First phase of fades
{
redVal -= 1; // Red down
greenVal += 1; // Green up
blueVal = 1; // Blue low
}
else if (i < 509) // Second phase of fades
{
redVal = 1; // Red low
greenVal -= 1; // Green down
blueVal += 1; // Blue up
}
else if (i < 763) // Third phase of fades
{
redVal += 1; // Red up
greenVal = 1; // Green low
blueVal -= 1; // Blue down
}
else // Re-set the counter, and start the fades again
{
i = 1;
}

analogWrite(redPin, redVal); // Write current values to LED pins
analogWrite(greenPin, greenVal);
analogWrite(bluePin, blueVal);

if (DEBUG) { // If we want to read the output
DEBUG += 1; // Increment the DEBUG counter
if (DEBUG > 10) // Print every 10 loops
{
DEBUG = 1; // Reset the counter

Serial.print(i); // Serial commands in 0004 style
Serial.print("\t"); // Print a tab
Serial.print("R:"); // Indicate that output is red value
Serial.print(redVal); // Print red value
Serial.print("\t"); // Print a tab
Serial.print("G:"); // Repeat for green and blue...
Serial.print(greenVal);
Serial.print("\t");
Serial.print("B:");
Serial.println(blueVal); // println, to end with a carriage return
}
}
delay(wait); // Pause for 'wait' milliseconds before resuming the loop
}

 

 

For RGB keyboard control:

//include support for manipulating strings.

//for a useful string comparison function, see the bottom of this file... stringsEqual()

#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

 

int redValue = 127;

int greenValue = 127;

int blueValue = 127;

 

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 ONE OF THE FOLLOWING COMMANDS, OR NOTHING WILL HAPPEN WHEN YOU

//RUN THE PROGRAM...

//Uncomment the following line to read commands of the form 'r245' or 'b3'

//processNumericalCommands(serInString);

//Uncomment the following line to read commands of the form 'rrrb'

processRepeatKeyCommands(serInString, 100);

//Or write your own function...

//YOUR_FUNCTION_HERE(serInString);

 

 

 

//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 + 10) % 255;

analogWrite(redPin, redValue);

Serial.print("setting color r to ");

Serial.println(redValue);

//If the character is g (green)...

} else if (colorCode == 'g') {

greenValue = (greenValue + 10) % 255;

analogWrite(greenPin, greenValue);

Serial.print("setting color g to ");

Serial.println(greenValue);

//If the character is b (blue)...

} else if (colorCode == 'b') {

blueValue = (blueValue + 10) % 255;

analogWrite(bluePin, blueValue);

Serial.print("setting color b to ");

Serial.println(blueValue);

}

//Move on to the next character in the string

//From here, the code continues executing from the "while" line above...

i++;

}

}

 

//change the value of the red, green, or blue LED according to the command received.

//for example, r240 sets the red LED to the value 240 (out of 255)

void processNumericalCommands(char *strArray) {

//read in the first character in the string

colorCode = serInString[0];

//if the first character is r (red), g (green) or b (blue), do the following...

if( colorCode == 'r' || colorCode == 'g' || colorCode == 'b' ) {

//convert the string to an integer

//(start at the second character, or the beginning of the string '+1')

colorVal = atoi(serInString+1);

Serial.print("setting color ");

Serial.print(colorCode);

Serial.print(" to ");

Serial.print(colorVal);

Serial.println();

 

if(colorCode == 'r')

analogWrite(redPin, colorVal);

else if(colorCode == 'g')

analogWrite(greenPin, colorVal);

else if(colorCode == 'b')

analogWrite(bluePin, colorVal);

}

}

 

//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;

}

}