Tri-Color Pendulums

9
Tri-Color Pendulums Jason Yore Making Things Interactive Carnegie Mellon University Fall 2010

description

Final Project for Making Things Interactive at Carnegie Mellon University, Fall 2010

Transcript of Tri-Color Pendulums

Page 1: Tri-Color Pendulums

Tri-Color Pendulums

Jason YoreMaking Things InteractiveCarnegie Mellon UniversityFall 2010

Page 2: Tri-Color Pendulums

What is it?

Tri-Color Pendulums consists of three pendulums: red, green, and blue. As they move toward one another, they share their colors with one another. For instance, as the red and blue pendulums are brought together they approximate purple from opposite ends of the spectrum. This combining works three ways with all of the pendulums, so when all three are brought together they all glow white. Users can interact with the pendulums by moving any of them or knocking. They can then enjoy a fun light show while learning about how colors interact in the RGB color-space .

How does it work

Each joystick contains two potentiometers; one for the x-axis and one for the y-axis. I used the measurements from these top mounted joysticks to determine the relative locations of the lights at the bottom of each pendulum.I spaced each of the joysticks on a sheet of MDF. Each of the joysticks is spaced such that they make an equilateral triangle. In my code, I assigned each joystick a virtual set of base coordinates: (0,0) red, (0,255) green, and (128, ~221) blue. These coordinates map to the physical distances between them.

Since Each pendulum is a little more than 2 feet long and the joysticks can bend approximately 30 degrees from center, I made sure to space the joysticks a minimum of two feet apart to avoid collisions.

I mapped the values coming in from the potentiometers such that when resting they were at 0 and moving full up was +128 and full down was -128, moving full left was -128 and full right was +128. I then added the value from each potentiometer to its base coordinates to determine its position. Once I had these values, I used the distance formula to determine the distance between each of the lights’ current positions. I subtracted that value from 255 (so closer results in brighter) and used that as the output for the LEDs. I kept the primary color for each light constant and varied the other two. For example the RGB values for the red light are always (255, XXX, XXX).

Since the code is running through this input and output process so fast, the lights appear to fluidly change colors as they interact with one another.

Page 3: Tri-Color Pendulums

Materials

Electronic:Arduino Megabreadboard3x: 2-Axis Joystick: Adafruit (Parallax ID: 245)3x: RGB LED: Sparkfun (sku: COM-00105 )3x: 330 Ohm resistor (for blue and green LEDs)6x:150 Ohm resistor (for red LEDs)A lot of hookup wireSolder (and soldering iron)

Structural:MDF Sheet (substitute ceiling)Wood beams (support legs)Acrylic Mounts (for Joysticks)Hot GlueEpoxy3x: 1 inch diameter x 2 foot PVC pipe3x: light bulbs6x: 1 inch diameter coupling (to interface with bulbs and joysticks)

Construction

Take 3 lightbulbs and carefully hollow them out, removing the filament and other guts inside. Spray them white so the light in them will be diffuse..

Use epoxy to attach each of them to the inside of a pvc couple. This creates a removable light housing.

take the thumbpads off of the joysticks and use epoxy to attach each of them leveled to the inside of a pvc couple as well. This allows for easy disassembly, storage, and transportation. Now drill a bout a 1/4 inch hole in these coupled to allow for the wires to the LEDs.

Solder the LEDs’ leads to resistors and then to wires at least 3 feet in length. Run the wires through the pvc pipe so the led hangs below the pipe by an inch or two and attach the bulb,couple over it. Run the wires up and through the hole at the top couple that is attached to the thumb pad.

Take a piece of MDF or similar material and cut three holes for the joysticks to hang through. Space them along points of an equilateral triangle with sides of about 28 or so inches You can cut these exact or leave room for a custom mount like I made by laser cutting acrylic to fit the joysticks. Hot glue the joysticks to the mounts and the mounts to the holes. drill 1/4 inch holes next to each mount for the LEDs’ wires to continue through.

Epoxy the pendulum assemblies to the joysticks, reattaching the thumb pads.

Construct an assembly to hold the entire thing above the ground.

Wire it up, add the code, and enjoy!

Page 4: Tri-Color Pendulums

Diagrams

Frtizing

Schematic

Page 5: Tri-Color Pendulums

Code

//Since I know I will only be making 3 lights, I found it easier to list out //my code for each instead of creating object instances. It is more straightforward// and easier to troubleshoot this way.

// I used an arduino mega 2560 which gives me enough PWM pins that the standard arduino doesn’t

int potRX = A0; //pot in pin designations (analog in pins) from 0 to 5int potRY = A1; //skip a pin for easier identification when wiringint potGX = A3; int potGY = A4;

int potBX = A6; int potBY = A7;

int rRed = 2; //led out pin designations (must be PWM)int rGreen = 3;int rBlue = 4;

int gRed = 6;int gGreen = 7;int gBlue = 8;

int bRed = 10;int bGreen = 11;int bBlue = 12;

// RGB output values for above pins (0-255) int rR=255; //always full redint rG=0; //determined by proximity to greenint rB=0; //determined by proximity to blue

int gR=0; //determined by proximity to redint gG=255; //always full greenint gB=0; //determined by proximity to blue

int bR=0; //determined by proximity to redint bG=0; //determined by proximity to greenint bB=255; ////always full blue

float rBaseX = 0; //beginning “location” relative to othersfloat rBaseY = 0;

float gBaseX = 255;float gBaseY = 0;

float bBaseX = 128;float bBaseY = sqrt((pow(255,2)) - (pow(128,2))); // not an exact integer - Pythag Thm to calculate // (this assumes the lights lie on the corners of an equilateral triangle//variables to be used for location of lights

int valRX;int valRY;

int valGX;int valGY;

Page 6: Tri-Color Pendulums

int valBX;int valBY;

int curRX;int curRY;

int curGX;int curGY;

int curBX;int curBY;

int RXL; int RXH; int RYL; int RYH; int GXL; int GXH; int GYL; int GYH; int BXL; int BXH; int BYL; int BYH; int RGdist; int GBdist; int BRdist;

void setup() { Serial.begin(9600);

pinMode(potRX, INPUT); pinMode(potRY, INPUT); pinMode(potGX, INPUT); pinMode(potGY, INPUT); pinMode(potBX, INPUT); pinMode(potBY, INPUT); pinMode(rRed, OUTPUT); pinMode(rGreen, OUTPUT); pinMode(rBlue, OUTPUT); pinMode(gRed, OUTPUT); pinMode(gGreen, OUTPUT); pinMode(gBlue, OUTPUT); pinMode(bRed, OUTPUT); pinMode(bGreen, OUTPUT); pinMode(bBlue, OUTPUT); //initial values before calibration RXL = analogRead(potRX); RXH = analogRead(potRX);

Page 7: Tri-Color Pendulums

RYL = analogRead(potRY); RYH = analogRead(potRY); GXL = analogRead(potGX); GXH = analogRead(potGX); GYL = analogRead(potGY); GYH = analogRead(potGY); BXL = analogRead(potGX); BXH = analogRead(potBX); BYL = analogRead(potBY); BYH = analogRead(potBY); }

void loop() { /////////////////////////////////////////////INPUT AND CONVERT///////////////////////////////////////////// // map pot values 0 255 this makes things in easier when we get to output

//current pot values

int curRX = analogRead(potRX); //REDint curRY = analogRead(potRY);

int curGX = analogRead(potGX); //GREENint curGY = analogRead(potGY);

int curBX = analogRead(potBX); //BLUEint curBY = analogRead(potBY);

// calibration: set new highs and lows for pot values X-axis and Y-axis

if(curRX < RXL){ //RED calibrationRXL = curRX;}if(curRX > RXH){RXH = curRX;}

if(curRY < RYL){RYL = curRY;}if(curRY > RYH){RYH = curRY;}

if(curGX < GXL){ //GREEN calibrationGXL = curGX;}if(curGX > GXH){ //AHA!!!!GXH = curGX;}

if(curGY < GYL){GYL = curGY;}

Page 8: Tri-Color Pendulums

if(curGY > GYH){GYH = curGY;}

if(curBX < BXL){ //BLUE calibrationBXL = curBX;}if(curRX > RXH){BXH = curBX;}

if(curBY < BYL){BYL = curBY;}if(curBY > BYH){BYH = curBY;} //MAY NEED TO INVERT (OR MULT BY -1 ETC) TO GET PROPER + AND - FROM POTS valRX=(map(curRX, RXL, RXH, 255, 0) -128 + rBaseX); //-128 sets center potentiometer value to ~0 HERE’S THE PROBLEM valRY=(map(curRY, RYL, RYH, 255, 0) -128 + rBaseY); // “Base” variable sets each potentiometer to its “grided” x, y location // map to 0 255 to align match up with coordinates and brightness values valGX=(map(curGX, GXL, GXH, 255, 0) -128 + gBaseX); //x and y are reversed from y since it is inverted valGY=(map(curGY, GYL, GYH, 255, 0) -128 + gBaseY); valBX=(map(curBX, BXL, BXH, 255, 0) -128 + bBaseX); //CONSIDER subtracting “resting” x and y to shift and get 0 and not -3 etc valBY=(map(curBY, BYL, BYH, 255, 0) -128 + bBaseY); //determine distances between each light relative to the other two ****ITS PROBABLY THE LINE BELOW vRGdist = constrain(sqrt( pow((valRX - valGX), 2) + pow((valRY - valGY), 2)), 0, 255); //distance formula: yields distance between 0 and 255 GBdist = constrain(sqrt( pow((valGX - valBX), 2) + pow((valGY - valBY), 2)), 0, 255);BRdist = constrain(sqrt( pow((valBX - valRX), 2) + pow((valBY - valRY), 2)), 0, 255);

//rR, gG, bB are constant // These values are the output “brightness” for the remaining 2 values for each RGB element //note: rG = gR, rB = bR, gB = bG because the distances are the same and the “gravity” of each light is equal rG = constrain((255-RGdist), 0, 255); // subtract from 255 because we want closer to be brighter, not more dim rB = constrain((255-BRdist), 0, 255); // ex No distance (0) = full (255) brightness. Full distance (255) = minimum (0) brightness gR = constrain((255-RGdist), 0, 255); // constrain to 0-255 gB = constrain((255-GBdist), 0, 255); // in future version maybe make negative distances dim the dominant color bR = constrain((255-BRdist), 0, 255); bG = constrain((255-GBdist), 0, 255);

/////////////////////////////////////////////OUTPUT///////////////////////////////////////////// // Now to write it all to each light’s three LED’s analogWrite(rRed, rR); //RED dominant output analogWrite(rGreen, rG); analogWrite(rBlue, rB);

Page 9: Tri-Color Pendulums

// Serial.print(rG);// Serial.print(“ “);// Serial.println(gR);// Serial.print(valRX); Serial.print(“ “); Serial.println(valGX); // Serial.print(rR);// Serial.print(“ “);// Serial.print(rG);// Serial.print(“ “);// Serial.print(rB);// Serial.println(“ “);

// Serial.print(RGdist);// Serial.print(“ “);// Serial.print(GBdist);// Serial.print(“ “);// Serial.print(BRdist);// Serial.println(“ “); analogWrite(gRed, gR); //Green dominant output analogWrite(gGreen, gG); analogWrite(gBlue, gB); analogWrite(bRed, bR); //Blue dominant output analogWrite(bGreen, bG); analogWrite(bBlue, bB); Serial.print(valRX); Serial.print(“ “); Serial.println(valRY); }