The Color Matching Game!

Group Members: Sam Payne, Prerna Ramachandra, Dillon Reisman, Abbi Ward

Early idea sketches:

1) Gummi-Bear RGB color-mixer!

Cool!

Sliding your finger on a slide-sensor transfers light between three R-G-B gummi bears!

3) The “Waker-Upper”

A device that detects when your head leans, indicating that you fell asleep. Triggers LEDs in glasses to wake you up

A device that detects when your head leans, indicating that you fell asleep. Triggers LEDs in glasses to wake you up

Idea actually implemented:

We built a color matching game. The computer will generate a random color, then the user must use a touch sensitive slide control to try and match that color. When the user thinks that they have matched the color they press a button to accept. A blue LED will flash if the colors match and a red LED will flash if they do not match. The game then resets and repeats. There is no score, or meta-game these can be added to later models if desired. The difficulty of the game can be adjusted to change how closely the colors must match. This first model of the game was built with a sensor which was not ideal for the task – the resistance characteristic is exponential rather than linear depending where the user presses on it. The controls were adjusted to correct for this, but the next model should be built with a sensor with a linear characteristic to improve the feel of the user’s controls.

Graph showing linear mixing of colors as finger slides across the sensor.

Graph showing linear mixing of colors as finger slides across the sensor.

Sam explains gameplay: 

Pictures of action:

Player attempts to match right diffuser to left diffuser.

Player attempts to match right diffuser to left diffuser.

Diffuser shows off vibrant light in the dark

Diffuser shows off vibrant light in the dark

 

Parts:

Parts List

2 RGB LEDs
1 blue LED
1 red LED
8 330-Ohm Resistors
1 1-kOhm Resistor
1 10-kOhm Resistor (for the switch)
1 slider sensor
1 button switch
2 square sheets of paper for the diffusers
1 paper napkin

Instructions to recreate:

Follow the given schematic(below) to construct the circuit. The diffusers are built using small square pieces of paper (~3×3 inches) that are folded into origami paper ballons (see: http://www.youtube.com/watch?v=tSMLk_zGzf4). Cut a hole in the bottom of the balloon so that the LED can fit. Also, inside the balloon place a small sheet of 1-ply paper napkin to help diffuse the light. Finally, program the Arduino with the following code.

Schematic view of Color game

Schematic view of Color game

Close-up of diffuser

Close-up of diffuser

 

Code used for Arduino:


/*
* Names: Sam Payne, Abbi Ward, Dillon Reisman, Prerna Ramachandra
* Date: 2/10/13
* Class: COS 469, L0
*
* Description: Color Game -- player
*
* Hardware:
* 2 RGB LEDs, 1 red LED, 1 green LED
* 1 slider sensor
* 1 button switch
*
*/

//pin assignments
//user LED
int redUser = 11;  
int greenUser = 10;
int blueUser = 9;
//NPC LED
int redNPC = 6;    
int greenNPC = 5;
int blueNPC = 3;
//victory indicators
int redLED = 13;
int greenLED = 12;
//analog in's
int sensorPin = A0;

//colors assigned user and computer
int targetRed;
int targetGreen;
int targetBlue;
int selRed;
int selGreen;
int selBlue;

int buttonPin = 2;
int buttonState = HIGH;
int sensorValue = 0;

int tolerance = 64; //this can be adjusted for difficulty (lower = more difficult)
int victory = 0;

void setup()  { 
  pinMode(buttonPin, INPUT);
} 

void loop()  { 
  //generate random color
  targetRed = random(0,255);
  targetGreen = random(0,255);
  targetBlue = random(0,255);

  //ensure that color can be selected by slider
  if((targetRed <= targetGreen) && (targetRed <= targetBlue))
  targetRed = 0;
  else if((targetGreen < targetRed) && (targetGreen < targetBlue))
  targetGreen = 0;
  else
  targetBlue = 0;

  //ensure that color can be selected by slider
  if((targetRed >= targetGreen) && (targetRed >= targetBlue))
  targetRed = 255;
  else if((targetGreen > targetRed) && (targetGreen > targetBlue))
  targetGreen = 255;
  else
  targetBlue = 255;

  analogWrite(redNPC, targetRed);
  analogWrite(greenNPC, targetGreen);
  analogWrite(blueNPC, targetBlue);

  selRed = 0;
  selGreen = 0;
  selBlue = 0;
  //adjust user input
  while(1) {
     //read user input color
     sensorValue = analogRead(sensorPin);

     //set display colors based on slider
     setColors_slider(sensorValue);

     //display user color
     analogWrite(redUser, selRed);
     analogWrite(greenUser, selGreen);
     analogWrite(blueUser, selBlue);

     //when user presses accept, save color
     buttonState = digitalRead(buttonPin);

     if(buttonState == LOW) {
        break;
     }

  }
  victory = 1;
  //determine if we are within tolerance
  if(selRed > (targetRed + tolerance)) victory = 0;
  if(selRed < (targetRed - tolerance)) victory = 0;
  if(selGreen > (targetGreen + tolerance)) victory = 0;
  if(selGreen < (targetGreen - tolerance)) victory = 0;
  if(selBlue > (targetBlue + tolerance)) victory = 0;
  if(selBlue < (targetBlue - tolerance)) victory = 0;

  //if user color is in tolerance, flash green LED
  if(victory == 1) {
    for(int i = 0; i < 5; i++) {
      digitalWrite(greenLED, HIGH);
      delay(100); 
      digitalWrite(greenLED, LOW);
      delay(100); 
    }
  } else {
  //else flash red LED
    for(int i = 0; i < 5; i++) {
      digitalWrite(redLED, HIGH);
      delay(100); 
      digitalWrite(redLED, LOW);
      delay(100); 
    }
  }
}

// reads in the value from the slider and sets the RGB LED
/* This function maps from 1D on the slider to 3D (R, G, B)
At any time, one of the 3 dimensions is 0, and another is 255. 
The last scales linearly within particular ranges of color. 
*/
void setColors_slider(int readValA) {
  int readVal = map(readValA, 100, 550, 160, 256);
  /* linear scale
  int R = 160;
  int Y = 176;
  int G = 192;
  int GB = 208;
  int B = 224;
  int P = 240;
  int RH = 256;
  */
  // exponential scale - wrong way
  /*
  int R = 160;
  int Y = 193; 
  int G = 215; 
  int GB = 230; 
  int B = 239;
  int P = 248; 
  int RH = 256; 
  */
  // exponential scale - right way
  // 33, 22, 15, 9, 9, 8
  int R = 160;
  int Y = 168; 
  int G = 177; 
  int GB = 186; 
  int B = 201;
  int P = 223; 
  int RH = 256; 
  //set Red
  if(readVal <= Y) 
     selRed = 255;
  else if(readVal > Y && readVal <= G) 
     selRed = (255 - ((readVal - Y) * 255/(G-Y)));
  else if(readVal > B && readVal <= P)
    selRed = ((readVal - B) * 255/(P-B));
  else if((readVal > P && readVal <= RH) || readVal > RH)
    selRed = 255;
  else
    selRed = 0;

  //set green
  if(readVal > Y && readVal <= GB)
    selGreen = 255;
  else if(readVal <= Y && readVal > R)
    selGreen = ((readVal - R) * 255/(Y-R))-1;
  else if(readVal > GB && readVal <= B)
    selGreen = (255 - ((readVal - GB) * 255/(B-GB)));
  else
    selGreen = 0;

  //set blue
  if(readVal > G && readVal <= GB)
    selBlue = ((readVal - G) * 255/(GB-G));
  else if(readVal > GB && readVal <= P)
    selBlue = 255;
  else if(readVal > P && readVal <= RH)
    selBlue = (255 - ((readVal - B) * 255/(RH-P)));
  else
    selBlue = 0;
}

 

 

It’s the Arduino Carabinieri!

Group members: Alan Thorne, Dylan Bowman, Harvest Zhang, Tae Jun Ham

Sketches:

Three sketches. The first, (and the one we built,) a police siren complete with flashing lights and wailing speaker, with no input other than a button (used like a switch) to turn it on or off. The second idea was a whack-a-LED game, where we use light sensors along with LEDs poking out of a grid; to play, you cover up the grid hole where the LED is lit, and the light sensor placed there detects that and gives you points. The final idea is a traffic light that  responds to a walk signal, but is otherwise a normal traffic light that is programmed to hold the same durations for red and green every cycle.

Three sketches. The first, (and the one we built,) a police siren complete with flashing lights and wailing speaker, with no input other than a button (used like a switch) to turn it on or off. The second idea was a whack-a-LED game, where we use light sensors along with LEDs poking out of a grid; to play, you cover up the grid hole where the LED is lit, and the light sensor placed there detects that and gives you points. The final idea is a traffic light that responds to a walk signal, but is otherwise a normal traffic light that is programmed to hold the same durations for red and green every cycle.

The Blues and Tunes Police Siren:

The Blues and Tunes police siren has an LED light bar, a single auxiliary LED flasher, and a speaker in order to flag down speeding Arduinos. It executes two types of flashing and wailing — one in the style of American police vehicles and the other more European (the European siren mode was added primarily because we ran out of blue and red LEDs, and used two yellow ones, which do show up in some European police vehicles but almost never in US vehicles). It has a pushbutton that starts and stops the siren.

Visible here is the large breadboard, containing the main LED light bar as well as the auxiliary one, mounted on the plastic blister packaging that also serves as a crude sort of resonator for the piezo speaker underneath.

Visible here is the large breadboard, containing the main LED light bar as well as the auxiliary one, mounted on the plastic blister packaging that also serves as a crude sort of resonator for the piezo speaker underneath.

Visible here: the red breadboard containing the on/off button, the Arduino, and the main breadboard.

2013-02-11 17.30.10

Here we see the lights in action. This particular implementation features two separate light and sound patterns.

 

For the most part, it works pretty well; the siren isn’t particularly loud, but it is annoying enough to earn looks from other lab groups if left on. The diffusers are acceptable but not very nice. A better light bar with a bunch of fresnel lenses would be ideal, but no one had miniature police light bar diffusers lying around. We could have also programmed the pushbutton to cycle through various types of sirens, but in this implementation we just hardcoded two alternating patterns.

It’s the Arduino Carabinieri! (video)

The components:

  • (1) Large blue LED
  • (2) Small red LED
  • (2) Small yellow LED
  • (1) RGB LED
  • (6) 330 Ohm resistors
  • (1) Pushbutton
  • (1) Piezo speaker
  • (1) Arduino
  • (1) Large breadboard
  • (1) Small breadboard
  • (n) A bunch of jump wires
  • (1) Translucent pen cap or similar diffuser
  • (1) Blister packaging strip covered in scotch tape for the main light bar

Make one yourself:

  1. Arrange all but the RGB LED in a visually pleasing manner on the large breadboard in the style of a police light bar.
  2. Add one 330 Ohm resistor between each LED and the Arduino. Connect the yellow RGBs to the same I/O pin and the red RGBs to the same I/O pin. Give the blue one its own pin. These are all digital I/O pins.
  3. Place the RGB LED in a prominent location on the large breadboard. We will be using only the red and blue pins (not the green one) from the RGB LED. Connect those (through resistors) to two I/O pins.
  4. Mount the pushbutton on the small breadboard and wire it up to the 5V pin. (You could also put it on the large breadboard with everything else, but there’s a lot of stuff on that one already.)
  5. Wire up the piezo speaker to an I/O pin.
  6. Make an appropriately light-bar-styled diffuser out of something translucent, and make another one for the RGB LED. Put them over the LEDs.
  7. The piezo speaker also gets much louder if you give it something larger to vibrate, so tape the piezo onto a blister package or something similar to make it sound more like a siren and less like a singing holiday card.
  8. Write up the code, and play the siren!

The code:

// ENUMS
int OFF = 0;
int ON = 1;
int TRANSITION = 2;

// Names for things
int button = 2;
int y = 3;
int r = 5;
int b = 6;
int tri_r = 9;
int tri_b = 10;
int speaker = 11;
int state = ON;
int current_state = ON;

// the setup routine runs once when you press reset:
void setup() {                
   pinMode(button, INPUT);     
}

// the loop routine runs over and over again forever:
void loop() {
  button_mode();

  if (current_state == ON) {
    for (int j = 0; j < 4; j++) {
      for (int i = 0; i <= 255; i++) {
        digitalWrite(speaker, HIGH);
        delayMicroseconds(300 - i);
        digitalWrite(speaker, LOW);
        delayMicroseconds(300 - i);
        analogWrite(speaker, 255);

        analogWrite(y, i);
        analogWrite(r, 255-i);
        analogWrite(b, i);
        analogWrite(tri_r, i);
        analogWrite(tri_b, 255-i);
        button_mode();
        delay(1);
      }

      for (int i = 0; i <= 255; i++) {
        digitalWrite(speaker, HIGH);
        delayMicroseconds(i + 45);
        digitalWrite(speaker, LOW);
        delayMicroseconds(i + 45);
        analogWrite(speaker, 255);

        analogWrite(y, 255-i);
        analogWrite(r, i);
        analogWrite(b, 255-i);
        analogWrite(tri_r, 255-i);
        analogWrite(tri_b, i);
        button_mode();
        delay(1);
      }
    }

    for (int j = 0; j < 4; j++) {
      button_mode();

      for (int i = 0; i <= 200; i++) {
        digitalWrite(speaker, HIGH);
        delayMicroseconds(100);
        digitalWrite(speaker, LOW);
        delayMicroseconds(100);
        analogWrite(speaker, 255);
        button_mode();
        delay(1);
      }

      analogWrite(y, 0);
      analogWrite(r, 255);
      analogWrite(b, 0);
      analogWrite(tri_r, 255);
      analogWrite(tri_b, 0);

      for (int i = 0; i <= 1802; i++) {  
        digitalWrite(speaker, HIGH);
        delayMicroseconds(300);
        digitalWrite(speaker, LOW);
        delayMicroseconds(300);
        analogWrite(speaker, 255);
        button_mode();
        delay(1);
      }

      analogWrite(y, 255);
      analogWrite(r, 0);
      analogWrite(b, 255);
      analogWrite(tri_r, 0);
      analogWrite(tri_b, 255);
    }

  }
  else {
    analogWrite(tri_b, 0);
    analogWrite(tri_r, 0);
    analogWrite(y, 0);
    analogWrite(r, 0);
    analogWrite(b, 0);
  }
}

void button_mode() {
  if (digitalRead(button) == HIGH) {
    state = TRANSITION;
  } else {
    if (state == TRANSITION) {
      if (current_state == OFF) {
        current_state = ON;
      } else if (current_state == ON) {
        current_state = OFF;
      }
      state = OFF;
    }
  }
}

Now all you need to do is add wheels and a motor and some more sensors and and a body and you’ll have an Arduino-based police car!

Color Wheel

Colleen Caroll, Angela Dai, Connie Wan, Edward Zhang

The Color Wheel is a game that challenges players to create a specified color using LEDs and colored filters. It is a fun and easy way for children to learn about the primary colors and the secondary colors that they create! The system is great because it is simple to use and understand. A color appears on the computer screen (e.g. “purple”), one colored led lights up on the board (e.g. red lights up), and then the user only has to turn the color wheel so that the color on the wheel mixes with the light to create the desired color (e.g. player turns the wheel to blue, thus making purple). It was, however, difficult to get a medium that would diffuse the LED properly so that color of the light and the filter would mix properly to the desired color. The LED is so focused that it was a challenge to get it to blend well with a material. We tried saran wrap, copy paper, toilet paper, and finally–thin sketch paper with watercolor to increase the translucence slightly. We put a lot of effort into finding the most effective and  aesthetically pleasing diffuser, as it an integral part of the function of our game. Our game works well (we have played several successful games) but would be even better with a more diffuse light (or another filter) that blended better.

Diagrams:

This schematic shows the rotating diffusing filter (mounted on a potentiometer) atop the LEDs, with the “Submit” push button on the side.

Images of Final System:

The electronics. Turn the paper filter (which is connected to a potentiometer) so that the blended color with the displayed LED light becomes a prompted color. Push the button to submit your guess.

For a prompted color of purple and a blue LED light, we turn the paper filter to red so that a purple color is seen.

 

We used processing to display a prompt color to achieve (in this case green) using the displayed LED color and the filter paper.

Parts List:

Electronics:

  • Red, Yellow, and Blue LED (or a tricolor LED + yellow LED)
  • 3x 330Ω Resistors
  • 1x 10kΩ Resistor
  • Linear Potentiometer
  • 12mm button
  • Breadboard
  • Arduino Uno

Other:

  • Straw
  • Paper
  • Red, yellow, and blue markers
  • Duct Tape

Instructions:

  1. Connect each of the LEDs to ground through a 330Ω resistor. Connect the positive side of the red LED to digital port 9, the yellow LED to digital port 10, and the blue LED to digital port 11.
  2. Connect the middle pin of the potentiometer to A0 (analog input 0) on the Arduino, and the outer pins to ground and 5V power,
  3. Connect one pin of the button to 5V power, another to digital pin 2, and another to ground through a 10kΩ resistor.
  4. Tape the end of the straw to the potentiometer, so that the straw sticks straight out of the knob. The tape should be strong enough such that turning the tape turns the knob of the potentiometer and the straw.
  5. Cut the other end of the straw lengthwise such that it splits into four strips. Flatten out the strips so they are perpendicular to the rest of the straw.
  6. Using the markers, color a square of paper (approx. 10cm x 10cm) so that approximately a third is red, a third yellow, and a third blue. The paper and markers should result in something that, when the LEDs shine through it, the colors blend into the primary combinations (green, purple, orange).
  7. Attach this paper to the straw strips using tape. The potentiometer-straw diffuser should be positioned such that the LEDs are underneath the paper to one side, and turning the potentiometer places each of the different colored paper regions over the LEDs.

Source Code:
Arduino Code

/**
* arduino
**/

/*
 Radiate, L0
 */

int val = 0;       // variable to store the value coming from the sensor
int leds[] = {9, 10, 11}; // LED pins
int NUM_LEDS = 3;           // number of LEDs
const int buttonPin = 2;
int buttonState = 0;

enum COLOR {
  RED,
  YELLOW,
  BLUE,
  ORANGE,
  GREEN,
  PURPLE,
  NUM_PROMPTS
};
const int NUM_QUESTIONS = 9;
int question_leds[] =    {RED, RED,    RED,    YELLOW, YELLOW, YELLOW, BLUE, BLUE,   BLUE};
int question_prompts[] = {RED, ORANGE, PURPLE, YELLOW, ORANGE, GREEN,  BLUE, PURPLE, GREEN};
int solutions[] =        {RED, YELLOW, BLUE,   YELLOW, RED,    BLUE,   BLUE, RED,    YELLOW};

int index = 0; // index of question
int filterindex = 0;

void setup_question()
{
  // turn on/off corresponding leds
  for (int i = 0; i < NUM_LEDS; i++) {
    if (i == question_leds[index]) {
      digitalWrite(leds[i], HIGH);
    }
    else
      digitalWrite(leds[i], LOW);
  }
  Serial.println(question_prompts[index]);
}

void setup()
{
  // initialize the serial communication:
  Serial.begin(9600);

  // initialize pushbutton as input
  pinMode(buttonPin, INPUT);

  // initialize led outputs:
  for (int i = 0; i < NUM_LEDS; i++)
    pinMode(leds[i], OUTPUT);

  // pick question
  index = random(NUM_QUESTIONS);
  setup_question();
}

void loop() {
  // read state of pushbutton
  buttonState = digitalRead(buttonPin);

  // if pressed check solution
  if (buttonState == HIGH) {
    val = analogRead(A0);    // read value from pot
    delay(10);
    filterindex = (int) (val / 1023.0 * 3 + 0.5);
    if (filterindex == 3) filterindex = 0; // two red so that pot can be circular
   /* Serial.print(val);
    Serial.print(" ");
    Serial.print(filterindex);
    Serial.print(" ");
    Serial.println(solutions[index]); */
    if (filterindex == solutions[index]) {
      // correct! new question
      index = random(NUM_QUESTIONS);
      setup_question();
    }
  }
}

Processing Code:

/**
processing -- displays colour prompts
**/

 import processing.serial.*;
 Serial port;
 PFont f; // font to display messages
 int xp = 100; // position of text
 int yp = 70;

 void setup() {
   size(256, 150);

   println("Available serial ports:");
   println(Serial.list());

   port = new Serial(this, Serial.list()[4], 9600);  

   // If you know the name of the port used by the Arduino board, you
   // can specify it directly like this.
   //port = new Serial(this, "COM1", 9600);
   background(255, 255, 255);
   f = createFont("Arial", 16, true); // Arial, 16 point, anti-aliasing on
   fill(0);
   //text("BEGIN", xp, yp);
 }

 void draw() {
 }

 void serialEvent(Serial myPort) {
   // get ascii string
   String instring = myPort.readStringUntil('\n');
   if (instring != null) {
     // trim off whitespace
     instring = trim(instring);
     int prompt = int(instring);
     drawbackground(prompt);
   }
 }

 void drawbackground(int prompt) {
   switch (prompt) {
     case 0: 
     background(255, 0, 0);
     text("RED", xp, yp);
     break;
     case 1:
     background(255, 255, 0);
     text("YELLOW", xp, yp);
     break;
     case 2:
     background(0, 0, 255);
     text("BLUE", xp, yp);
     break;
     case 3:
     background(255, 127, 80);
     text("ORANGE", xp, yp);
     break;
     case 4:
     background(0, 255, 0);
     text("GREEN", xp, yp);
     break;
     case 5:
     background(255, 0, 255);
     text("PURPLE", xp, yp);
     break;
     default:
     background(0, 0, 0); // error
     fill(255);
     text("ERROR " + prompt, xp, yp);
     fill(0);
     break;
   }
 }

Other Ideas:

1. Chalk Dust Diffuser – Fill up a room with smoke (or chalk dust if a smoke machine is not readily available) and have multicolored LEDs changing color in sync to music. Awesome ambient lighting for a dance floor. This was a “diffuser-focused” idea.

Poof (320x240)

2. Simon Says – Using a set of buttons and colored LEDs, this game presents the user with sequences of colored lights of increasing length. They have to press the buttons corresponding to the appropriate lights in the correct order to advance. Unfortunately, while interactive, this didn’t really use the idea of a diffuser effectively.
CameraZOOM-20130217174819580

3. Color matching game – This was an interactive game that had a diffuser as an integral part of the system. Create colors by moving the appropriately colored filter above the lit LED.

CameraZOOM-20130217173317849 (2)

Rainbow Tower

Green Choi (ghchoi@)
Peter Yu (keunwooy@)
Vivian Qu (equ@)
Jae Lee (jyltwo@)

Rainbow Tower:

We used five single-color LED lights positioned in a circle around a tri-color LED light. All the lights can be controlled by a dial (potentiometer) and a button. The LEDs were covered with colored straws to make a visually comforting diffuser. The button switched between modes: DIAL and STROBE modes. When the mode is DIAL, the user can one-by-one turn on each of the single-color LED lights while the tri-color LED light changes to the corresponding single-color LED light that was just turned on. When the mode is STROBE, the single-color LED lights flash every 0.5 seconds. The main tri-color LED stays on and changes to a random color every 0.5 seconds.

We were inspired by the many different types of night lights or children’s toys which change colors. We wanted to also build an interactive, colorful set of lights that could be changed to fit the user’s color preferences. Plus, it makes us really happy to play with the multiple lights!

The device responds very well to the user inputs. But in the future, we would like to make the setup more stable by attaching the base of straws to foam core or cardboard. We wanted to use a 7-segment display to show the current mode, but we didn’t have enough digital I/O ports available. So if we could use more arduinos, more functionalities (like displaying the current mode) would be possible. There is also a lot of potential for design expansion if there were more LEDs and arduinos available, so the lights and straws could be added to create a bigger Rainbow Tower!

Photos + Videos:

 

Parts Used:

  • Arduino UNO R3 (1)
  • SoftPot (1)
  • Button (1)
  • Basic LED (5)
  • Tri-Color LED (1)
  • Colored Straws (6)
  • 330 Ohm Resistors (9)
  • Breadboard (3)
  • Wires

Instructions for Recreating:

  1. Position the 5 one-color LED lights in a circle configuration on the breadboard. Place the tri-color LED in the center. Make sure there is enough space to cover each LED with a straw. Wire the one-color LEDs — connect the positive end through a resistor to the arduino’s digital I/O ports (we used ports 9, 10, 11, 12, 13) and the other end to ground, using a second breadboard to hold all the resistors if necessary. Wire the tri-color LED by connecting three legs to digital I/O ports (we used ports 3, 5, 6) and the longer leg to ground.
  2. Cover all 6 LEDs with appropriate colored straws. Cut the straws to varying size, if desired.
  3. Use another breadboard to set up the button and the potentiometer. For the button, connect one leg to a digital I/O port (we used port 8). Connect the same leg on the opposite side through a resistor to ground. Finally, connect the opposite leg to 5V.
  4. For the potentiometer, connect the rightmost leg to ground. Connect the leftmost leg to 5V. The middle leg is connected to analog input (we used port A2).
  5. Upload the code, and test it out!

Code:

/*
The Rainbow Tower -- awesome diffuser with straws
*/
// Set the I/O pin numbers.
const int blueLed = 13;
const int yellowLed = 12;
const int redLed = 11;
const int greenLed = 10;
const int purpleLed = 9;
const int multiRLed = 6;
const int multiGLed = 5;
const int multiBLed = 3;
const int potPin = 2;
const int buttonPin = 8;

// Colors for tri-color LED
// Red
const byte r1 = 255;
const byte g1 = 0;
const byte b1 = 0;
// Orange
const byte r2 = 255;
const byte g2 = 128;
const byte b2 = 0;
// Yellow
const byte r3 = 255;
const byte g3 = 255;
const byte b3 = 0;
// Green
const byte r4 = 128;
const byte g4 = 255;
const byte b4 = 0;
// Blue
const byte r5 = 0;
const byte g5 = 0;
const byte b5 = 255;
// Purple
const byte r6 = 128;
const byte g6 = 0;
const byte b6 = 255;

boolean changed = false;
int buttonMode = 0;
int buttonVal = 0; // Button
int potVal = 0; // Potentiometer
int bulbVal = 0;
long interval = 500; // Blink time (0.5 s)
long previousMillis = 0;
int flickerState = LOW;

void setup() {
    // Set the digital pins as output:
    pinMode(blueLed, OUTPUT);
    pinMode(yellowLed, OUTPUT);
    pinMode(redLed, OUTPUT);
    pinMode(greenLed, OUTPUT);
    pinMode(purpleLed, OUTPUT);
    pinMode(multiRLed, OUTPUT);
    pinMode(multiGLed, OUTPUT);
    pinMode(multiBLed, OUTPUT);
}

void loop()
{
    // Tri-color LED is always lit.
    unsigned long currentMillis = millis();

    // Read the mode.
    buttonVal = digitalRead(buttonPin);
    if (buttonVal == HIGH) {
        changed = true;
    }
    if (changed && buttonVal == LOW) {
        buttonMode++;
        buttonMode %= 2;
        changed = false;
    }
    // DIAL mode
    if (buttonMode == 0) {
        for (int i = 9; i <= 13; ++i) {
        digitalWrite(i, LOW);
        }
        potVal = analogRead(potPin);
        bulbVal = map(potVal, 0, 1023, 9, 17);
        for (int i = 13; i >= bulbVal; --i) {
            digitalWrite(i, HIGH);
        }
        if (bulbVal == 9) {
            analogWrite(multiRLed, r6);
            analogWrite(multiGLed, g6);
            analogWrite(multiBLed, b6);
        }
        if (bulbVal == 10) {
            analogWrite(multiRLed, r5);
            analogWrite(multiGLed, g5);
            analogWrite(multiBLed, b5);
        }
        if (bulbVal == 11) {
            analogWrite(multiRLed, r4);
            analogWrite(multiGLed, g4);
            analogWrite(multiBLed, b4);
        }
        if (bulbVal == 12) {
            analogWrite(multiRLed, r3);
            analogWrite(multiGLed, g3);
            analogWrite(multiBLed, b3);
        }
        if (bulbVal == 13) {
            analogWrite(multiRLed, r2);
            analogWrite(multiGLed, g2);
            analogWrite(multiBLed, b2);
        }
        if (bulbVal == 14) {
            analogWrite(multiRLed, r1);
            analogWrite(multiGLed, g1);
            analogWrite(multiBLed, b1);
        }
        if (bulbVal == 15) {
            analogWrite(multiRLed, 0);
            analogWrite(multiGLed, 0);
            analogWrite(multiBLed, 0);
        }
    }
    // STROBE mode
    else {
        if (currentMillis - previousMillis > interval) {
            previousMillis = currentMillis;

            if (flickerState == LOW)
                flickerState = HIGH;
            else
                flickerState = LOW;

            for (int i = 9; i <= 13; ++i) {
                digitalWrite(i, flickerState);
            }
            analogWrite(multiRLed, 30);
            analogWrite(multiGLed, 30);
            analogWrite(multiBLed, 30);
        }
    }
}

Harlem Shake v436

Group Members

Osman Khwaja
Alejandro Van Zandt-Escobar
Gabriel Chen
Avneesh Sarwate
Prakhar Agarwal

Description

We built a glass world that reacts to light using a photosensor and behaves according to the state it is in. There are three states governed by a button: the idle state, the build state, and the drop state. Before the button is enabled, the world is in a calibration state, used to expose the photoresistor to the range of possible light inputs and thus, resistances. The idle state consists of a tricolor LED, fitted with a straw. The tricolor LED oscillates between all ranges of colors according to three sin functions. The other LEDs do nothing. The build state is to be initiated by the press of the button when the song “Harlem Shake” is played (in light of the recent trend). The tricolor LED begins to change colors erratically, and the remaining LEDs alternate slowly between reds and blues, arranged diagonally from each other. The behavior matches the tempo of the song. The drop state is to be initiated at the beat drop of the song. The tricolor LED continues its erratic behavior, but the remaining LEDs now act based on the light sensor. This can be used to induce extremely erratic behavior all LEDs, in accordance with Harlem Shake tradition. Thus, we felt that our design successfully produced the desired behavior. The different states of the design are a good representation of different stages in the song, and the use of a button allows for ease of state transition. Additionally, the straw and ice cube trays were excellent diffusers, and really emphasized the output of the LEDs. One limitation of our design was the sensitivity of the photoresistor. It was placed under a thick layer of glass, which may have diffused light entering the circuit. Although this made the design more aesthetic, the functionality was slightly impaired. Overall, we were happy with the Harlem Shake video we were able to produce using our design, and we hope that it goes viral!

Photos of Sketches

Slide sensor controls the brightness of the lights. Lights closest to finger are brightest. Move finger to control the light.

Follow the finger: Slide sensor controls the brightness of the lights. Lights closest to finger are brightest. Move finger to control the light.

 

Perfect Pushup - Use a diffuser and flex sensor to determine whether pushup form is correct or not.

Perfect Pushup: Use a diffuser and flex sensor to determine whether pushup form is correct or not.

 

A schematic of our final design.

A schematic of our final design.

 

A design diagram of our project

A design diagram of our project.

Video

Parts

  • Arduino Uno
  • Button
  • Photoelectric Sensor
  • Ice Cube Tray
  • Glass Box/Flower Vase
  • 1 Straw
  • Wires
  • 2 10k Ohm Resistor
  • 7 330 Ohm Resistors
  • 2 Blue LEDs
  • 2 Red LEDs
  • 1 Tricolor LED
  • 2 Alligator Clips
  • Tape

Instructions

  1. Connect the TriColor LED to the three analog pins 11, 10, 9 through 330 Ohm resistors.
  2. Connect 4 LEDs in a general box shape just below the TriColor to the pins 7,6,5,4 with a 330 Ohm Resistor for each.
  3. Attach a photoelectric sensor to the top of the glass box using the alligator clips. Ensure that the sensor is facing outwards.
  4. Connect the button to the breadboard with the 10k Resistor, pulling 5 Volts from Arduino. Connect the output to pin 3.
  5. Connect the photosensor with a 10k Resistor to pin A0 on the Arduino.
  6. Cover the 4 LEDs with the ice cube tray, the tricolor with a straw, and all of them with the glass case.
  7. When powering up the system, make sure to calibrate the photosensor by covering and uncovering the sensor. The Blue LED will light up during this time.

    Here is what the final setup should look like.

    Here is what the final setup should look like.

Source Code

// ----------------------
// Harlem Shake v. 436
// ----------------------
// COS 436, Lab 0
// February 18, 2013
// ----------------------
// Prakhar Agarwal
// Gabriel Chen
// Osman Khwaja
// Avneesh Sarwate
// Alejandro Van Zandt-Escobar
// ----------------------
// The "beacon" (multicolor LED) is connected to three analog outputs
const int beaconRed = 11;
const int beaconGreen = 10;
const int beaconBlue = 9;
// The four other LEDs are connected to four digital outputs
const int ledYellow = 8;
const int ledRed = 7;
const int ledBlue = 6;
const int ledGreen = 5;

// Sensor 1: Photocell
const int sensorPin = A0;

int sensorValue = 0;
int sensorMin = 1023; // minimum sensor value
int sensorMax = 0; // maximum sensor value
int threshold = 127;

// Button
const int buttonPin = 3;

int buttonState = 0; // HIGH or LOW
int buttonCounter = 0; // Number of clicks determines the program's current state.
int lastButtonState = 0; // HIGH or LOW

// Setup Routine
void setup() {

// For debugging:
Serial.begin(9600);

// Set up I/O.
pinMode(beaconRed, OUTPUT);
pinMode(beaconGreen, OUTPUT);
pinMode(beaconBlue, OUTPUT);

pinMode(ledGreen, OUTPUT);
pinMode(ledBlue, OUTPUT);
pinMode(ledRed, OUTPUT);
pinMode(ledYellow, OUTPUT);

pinMode(buttonPin, INPUT);

// Calibrate photocell during the first five seconds.
while (millis() < 5000) { // Light up LED at the beginning of calibration phase. digitalWrite(ledBlue, HIGH); // Read in value from photocell sensorValue = analogRead(sensorPin); // Record the maximum sensor value if (sensorValue > sensorMax) {
sensorMax = sensorValue;
}

// Record the minimum sensor value
if (sensorValue < sensorMin) {
sensorMin = sensorValue;
}

// Turn off LED at end of calibration phase
digitalWrite(ledBlue, LOW);

}

}

// Variables for timing and rhythm
double time = 0;
double t = 0; // Used for sin wave patterns
int beat = 430; // Duration of a beat (in ms)
int downBeatBeacon;
int downBeatCubes;

void loop() {

// *** Process Photocell Input ***
// Read photocell sensor
sensorValue = analogRead(sensorPin);
// Apply calibration
sensorValue = map(sensorValue, sensorMin, sensorMax, 0, 255);
// Map sensor value to desired range
sensorValue = constrain(sensorValue, 0, 255);

// *** Process Button Input ***
// Read state of pushbotton
buttonState = digitalRead(buttonPin);
// Compare the buttonState to its previous state
if (buttonState != lastButtonState) {
// State changes when button is pressed down (from off to on)
// If state has changed then increment counter
if (buttonState == HIGH) {
// If the current state is HIGH then button went from off to on
if (buttonCounter == 2)
buttonCounter = 0;
else
buttonCounter++;
// For debugging:
// Serial.println("on");
// Serial.print("number of button pushes: ");
// Serial.println(buttonCounter);
}
else {
// If the current state is LOW then the button went from on to off
Serial.println("off");
}
}
// save the current state as the last state, for next time through the loop
lastButtonState = buttonState;

// *** Main Program Loop ***

// *** Idle State ***
if (buttonCounter == 0) {
// Tri-color LED has an intersecting sinusoidal pattern
analogWrite(beaconRed, (int) (127 + 127 * sin(t)));
analogWrite(beaconBlue, (int) (127 + 127 * sin(t + 3.14/3)));
analogWrite(beaconGreen, (int) (127 + 127 * sin(t + 6.28/3)));

// Turn all other LEDs off
digitalWrite(ledBlue, LOW);
digitalWrite(ledGreen, LOW);
digitalWrite(ledRed, LOW);
digitalWrite(ledYellow, LOW);

// Progression of sinusoidal pattern
t += 0.1;
delay(20);
}

// *** Build State ***
else if (buttonCounter == 1) {
// Beacon's activity is determined by eighth notes
downBeatBeacon = ((int) (time / (beat / 2)));
// Cube's activity is determined by half notes
downBeatCubes = ((int) (time / (beat * 2))) % 2;

// The beacon plays an accelerated sinusoiodal pattern
// Erratically matched to the rhythm of eighth notes
analogWrite(beaconRed, (int) (127 + 127 * sin(downBeatBeacon + .9)));
analogWrite(beaconBlue, (int) (127 + 127 * sin(9 * downBeatBeacon + .2)));
analogWrite(beaconGreen, (int) (127 + 127 * sin(7 *downBeatBeacon)));

// The four LEDs in the icecube alternate diagonally, on every half beat.
// On beat 1:
if (downBeatCubes == 0) {
digitalWrite(ledBlue, HIGH);
digitalWrite(ledGreen, LOW);
digitalWrite(ledRed, LOW);
digitalWrite(ledYellow, HIGH);
}
// On beat 2:
else if (downBeatCubes == 1) {
digitalWrite(ledBlue, LOW);
digitalWrite(ledGreen, HIGH);
digitalWrite(ledRed, HIGH);
digitalWrite(ledYellow, LOW);
}

// Update every eighth note
delay(beat / 2);
time += beat / 2;

}

// *** Drop State ***
else {
// Beacon's activity is determined by eighth notes
downBeatBeacon = ((int) (time / (beat / 2)));

// The beacon plays an accelerated sinusoiodal pattern
// Erratically matched to the rhythm of eighth notes
analogWrite(beaconRed, (int) (127 + 127 * sin(downBeatBeacon + .9))); // turn the LED on (HIGH is the voltage level)
analogWrite(beaconBlue, (int) (127 + 127 * sin(9 * downBeatBeacon + .2))); // turn the LED on (HIGH is the voltage level)
analogWrite(beaconGreen, (int) (127 + 127 * sin(7 *downBeatBeacon)));

// The cube LEDs play the same pattern, but switch according
// to input from the photocell.
if (sensorValue < threshold) {
digitalWrite(ledBlue, HIGH);
digitalWrite(ledGreen, LOW);
digitalWrite(ledRed, LOW);
digitalWrite(ledYellow, HIGH);
}
else {
digitalWrite(ledBlue, LOW);
digitalWrite(ledGreen, HIGH);
digitalWrite(ledRed, HIGH);
digitalWrite(ledYellow, LOW);
}

// Update every eighth note
delay(beat / 2);
time += beat / 2;
}
}

Not just your average crane…

I. Group members:

Xin Yang Yak <xyak@princeton.edu>, Junjun Chen <junjunc@princeton.edu>, Josh Chen <joshchen@princeton.edu>, Igor Zabukovec <iz@princeton.edu>

II. Description:

We made an ornamental Origami crane that glows with different colors based on its state. The crane glows red when left alone, and flashes green and blue when its tail is bent in the standard Origami way. We liked this design because it puts multiple forms of interactivity into one design: The crane responds to someone pulling its tail both electronically and mechanically, by both changing color (thanks to the Arduino and Flex sensor) and changing shape (thanks to our Origami design).  We think that our design was successful because, as shown in our video, all intended functionality worked.  However, the Flex sensor is quite visible and fragile, as it is only taped externally onto the crane’s tail.  The design could be improved upon if we had a Flex sensor that was thinner, shorter, and less rigid – ideally, we would use a wire Flex sensor that changed resistance when bent.

III. Diagram:

2013-02-16 16.45.35

High-level sketch of our diffuser’s functionality.  When someone pulls on the Origami crane’s tail, the Arduino detects the change through the Flex sensor.

2013-02-16 16.52.29

Low-level sketch of how our diffuser is built.  Our diffuser is built using a tri-color LED and a Flex sensor, with the LED three prongs each wired to the Arduino’s digital output pins and the Flex sensor wired to one of Arduino’s analog ports.

2013-02-16 16.46.00

An earlier design we were considering for this project.  We gave up on the alarm clock because we thought having a diffusing crane was cooler 🙂

2013-02-16 16.45.46

The low level sketch of the earlier design.

IV. Video of final system:

V. Parts used:

  • Arduino Uno
  • wires
  • 22 k ohm resistor
  • 3 330 ohm resistors
  • flex sensor
  • tricolor LED
  • wax paper crane

 VI. Instructions (see second diagram for more, as well)

  1. Connect the parts to the Arduino board as shown in the diagram mentioned.
  2. Connect the ground leg of the tricolor led to ground. Connect each of the other legs to a digital output pin (3, 5, 6) on the Arduino, which one 330 ohm resistor for each leg.
  3. Connect the positive leg of the flex sensor to 5V, and the other leg to analog in pin A0. Also connect this to a 22 k ohm resistor going to ground.
  4. Build a paper crane.  Stick the LED through the underside of the crane, and tape the flex sensor to the crane’s tail, so that pulling the tail causes both the crane’s wings to move and the flex sensor to register the change in resistance.

VII. Source code

const int ledPinRed = 6;
const int ledPinGreen = 3;
const int ledPinBlue = 5;
int flex = A0;

void setup()
{
  pinMode(ledPinGreen,   OUTPUT);
  pinMode(ledPinRed,   OUTPUT);
  pinMode(ledPinBlue,   OUTPUT);

  digitalWrite(flex, HIGH);
  analogWrite(ledPinRed, 255);
  Serial.begin(9600);
}

void loop() {
  byte brightness = analogRead(flex);
  if (brightness <   50) {
    analogWrite(ledPinRed, 0);
    analogWrite(ledPinBlue, 0);
    analogWrite(ledPinGreen, 255);
    delay(200);
    analogWrite(ledPinGreen, 0);
    analogWrite(ledPinBlue, 255);
  }
  else {
    analogWrite(ledPinGreen, 0);
    analogWrite(ledPinBlue, 0);
    analogWrite(ledPinRed, 255);
  }
  delay(200);
}

Arduino Says – Red Light Green Light

Group

Andrew Boik (aboik@)
Brian Huang (bwhuang@)
Kevin Lee (kevinlee@)
Saswathi Natta (snatta@)

Description

For our Part 3 we chose to implement a simple Red Light, Green Light game. We are using one red and one green LED to indicate when the user is supposed to stop or allowed to go. We are using the Flex sensor as a joystick where bending it in one direction signifies accelerating and not bending or bending in the other direction signifies stopping. If the green light is on, the user is allowed to “go” by bending the flex sensor forward to accumulate points in the game. If the red light is on, the user is supposed to “stop” by bending the flex sensor backwards. If the user by mistake “goes” while the red light is on, the buzzer will play a sad song signifying the end of the game. To play again, however, one need only reset the Arduino. We are using a random number generator to determine when the red light or the green light will be on. The diffuser is basically our traffic light contraption made of tape and plastic. Our project was primarily motivated by the desire to implement an interactive, joystick-controlled system. Ultimately, we think this project was a great success. We particularly like how we were able to make a responsive joystick with just a flex sensor. If we could change something, we would somehow add components to convey the gamer’s score. Unfortunately, in the current implementation, the gamer is completely oblivious to the number of points he has accumulated. Note: We could have used a button as the user control for go and stop, but we chose to use a flex sensor to give the user a feeling of a joystick. With a flex sensor, if we choose, we can also allow the user to go faster or slower and accumulate more points faster or slower instead of a simple stop and go. If you fail too many times, the police will (not) come after you with the siren from Lab group 25.

Sketches of Early Ideas

Bicycle Lights

Bicycle Lights

sketch2-group21

Simplified Theremin

sketch3-group21

Red Light Green Light 

Final Sketch

finalsketch

Demonstration Video

Parts used in design:

  • Arduino
  • Red LED
  • Green LED
  • Buzzer/speaker
  • Flex sensor
  • Plastic and tape for diffuser

Instructions:

  1. Setup LEDs, buzzer, and flex sensor
    1. Place the long end of each LED to the chosen Arduino digital output pin and the shorter end to ground
    2. The buzzer is also wired between an Arduino digital output pin (that can generate a PWM) and ground
    3. the Flex sensor is wired with a voltage divider between one pin and power and the other pin connects to a Arduino analog input pin to detect the resistance
      1. Note: if the voltage divider is not in place, the Arduino only reads a full high power and does not read the varying resistance when the flex sensor is bent
  2. Setup diffuser
    1. Diffuser is made of tape placed over two circular holes in a plastic packaging material. The red and green LED are placed under the two holes and are visible through the tape. the buzzer is covered by the plastic.
  3. Test baseline for flex sensor and change ‘go’ threshold as necessary
    1. Once the Flex sensor is connected, with the proper (~10K) voltage divider connected to power on one pin and the other pin connected to the Arduino, the Arduino software will display it’s reading of the input. You can bend it forward and backward to see how the values change. We chose a threshold value of 360, where values above the threshold are the “go” state and values below are the “stop” state
    2. The buzzer will sound if the red LED is on and the flex sensor is in the go state, signifying that the game is over.
Setup with Diffuser

Setup with Diffuser

Setup without Diffuser

Setup without Diffuser

 Code:

/*
Red Light/Green Light Game!
*/

#include "pitches.h"

int flexSensorPin = A3;
int redLED = 9;
int greenLED = 11;
int state; // holder for red/green light state
int pause = 250; // constant for use in error state
int leeway = 400; // time for player to switch
int interval = 5; // ticks before randomly generating a light
int counter = 0;
int goThreshold = 360; // threshold for stop/go.
                       // Values above are “go”
int score; // currently inconsequential,
           // but could be used to create top scorers

// notes in the melody:
int melody[] = {NOTE_C5, NOTE_B4, NOTE_AS4, NOTE_A4};

// note durations: 4 = quarter note, 8 = eighth note, etc.:
int noteDurations[] = {4, 4, 4, 1};

void setup(){
  Serial.begin(9600);
  pinMode(redLED, OUTPUT);
  pinMode(greenLED, OUTPUT);

  digitalWrite(redLED, HIGH); // initialize to red light
  digitalWrite(greenLED, LOW);
  state = 0;
  score = 0; // set score to zero
}

void loop(){
  if (counter >= interval) {
    state = random(2);
    light(state);
    counter = 0;

    delay(leeway); // give the player time to react
    leeway = leeway - 1; // make the game iteratively harder
  }

  int flexSensorReading = analogRead(flexSensorPin);
  switch (state) {
    case 0: // red light is on
      if (flexSensorReading <= goThreshold) { 
        // success! 
        score++;
      } 
      else { 
        failure();
      } 
      break;
    case 1:
      // green light is on 
      if (flexSensorReading > goThreshold) {
        // Good! Get points!
        score++;
      }
      else {
        // we don’t punish for not going, you just get no points
      }
      break;
    default:
       // we should never get here
       error();
  }

  Serial.print("state: ");
  Serial.println(state);
  Serial.println(flexSensorReading); // debugging?

  counter++;
  delay(pause);
}

void light(int status){
  switch (status) {
    case 0: // red light!
      digitalWrite(redLED, HIGH);
      digitalWrite(greenLED, LOW);
      break;
    case 1: // green light!
      digitalWrite(redLED, LOW);
      digitalWrite(greenLED, HIGH);
      break;
    default:
      //this should never happen
      error();
  }
}

void error() {
  while (true) {
    digitalWrite(redLED, LOW);
    digitalWrite(greenLED, LOW);
    delay(pause);
    digitalWrite(redLED, HIGH);
    digitalWrite(greenLED, HIGH);
    delay(pause);
  }
}

void failure() {
  // iterate over the notes of the "fail" melody:
  for (int thisNote = 0; thisNote < 4; thisNote++) {
    // to calculate the note duration, take one second
    // divided by the note type.
    // e.g. quarter note = 1000 / 4, eighth note = 1000/8, etc.
    int noteDuration = 1000/noteDurations[thisNote];
    tone(8, melody[thisNote],noteDuration);

    // to distinguish the notes, set a minimum time between them.
    // the note's duration + 30% seems to work well:
    int pauseBetweenNotes = noteDuration * 1.30;
    delay(pauseBetweenNotes);
    // stop the tone playing:
    noTone(8);
  }
error();
}

 

Bottle Organ RockBand

Erica Portnoy (eportnoy@)
Bonnie Eisenman (bmeisenm@)
Mario Alvarez  (mmcgil@)
Valya Barboy (vbarboy@)

Bottle Organ RockBand:

The Bottle Organ RockBand is a musical tutorial: it lights up the bottle that you should blow in next, teaching you to play a song (specifically, Mary Had a Little Lamb)! We were inspired to do this project by little kids’ instructional pianos, whose keys light up to teach people to play simple songs. Three of us play the flute, so the bottle organ was a natural and cheap choice of instrument. Also, we thought that light would diffuse really well through a water-milk mixture, making the instructions easy to follow (and it would look cool!). We thought the diffusion of our LEDs through the fluids worked really well. We also liked the fact that the different notes were different colors, because it makes the tutorial easier to follow. Finally, we’re proud of the tuning of the bottles. Originally we had hoped to build a larger-scale organ to span an entire octave, but because of the limited number of LEDs we could not do that. We also thought about making it more interactive (using the SoftPot to adjust tutorial speed, having a user compose a song and the tutorial play it back, etc.) We ultimately decided, however, that it would be more beneficial to focus our efforts on making the output device, because adding sensors would yield only minimal gain. Another limitation is that currently our song is hardcoded, so it can only play one song at a time. That being said, the notes themselves are in a separate array that our code reads in and parses, so giving it any other song would be easy. Finally, one major design flaw we had was that the bottles were standing very close to our electronics. If we were going to do this again, we would keep our bottles in some container, safely away from our Arduino. Overall, we are pleased with the result. We even did a user test!

Sketches:

Binary Balloon Stopwatch - counts seconds by giving the binary number via lit-up LEDs. Didn't work because we don't have helium, and have too few LEDs.

Binary Balloon Stopwatch – counts seconds by giving the binary number via lit-up LEDs. Didn’t work because we don’t have helium, and have too few LEDs.

Diffusing light through a pumpkin so that it looks like a flame - ultimately cool but kind of worthless...

Diffusing light through a pumpkin so that it looks like a flame – ultimately cool but kind of worthless…

Bottle Organ RockBand - our final design!

Bottle Organ RockBand – early sketches of our final product!

A video of our final result:

Showing various people playing our final product, and the making of our Bottle Organ!

List of materials:

  • 1 Arduino
  • 2 220 Ohm resistors
  • 2 47 Ohm resistors
  • 1 USB cable
  • 8 alligator clips
  • 9 wires
  • 1 breadboard
  • 4 LEDs
  • 4 plastic bottles, filled with a water and a few drops of milk
  • Online tuner

Instructions!

IMG_1991IMG_1990

Once you have the necessary materials, start by building the circuit, following the diagram included. The circuit should be 4 LEDs and resistors in parallel, with all connecting to the ground on the Arduino. We used weaker resistors for the weaker LEDs, to make them all closer in brightness. Using alligator clips to connect to the LEDs is useful for positioning them beyond the breadboard. Each LED is then placed under a corresponding plastic bottle so that the light diffuses upwards. To set up the bottles: acquire four plastic bottles. If necessary, remove their labels. Then, use an online tuner such as this one to determine the volume of liquid necessary to produce the desired note for each bottle. We recommend simple trial and error using water. Mark the level and note on the bottle with a marker if desired. Water doesn’t diffuse light very well. In order to improve diffusion, add a small quantity of milk to each bottle. We used a standard soda bottle cap to measure out the milk, and used between half of a capful and a whole capful for each bottle; add milk until it looks cool to you, testing diffusion using an LED. We also experimented with some other liquids, such as tea; we encourage you to experiment with liquids as well. Volume, not density, determines pitch, so the type of liquid shouldn’t matter. Finally, place the bottles above the LEDs, plug the USB cable into the Arduino and the computer, and start making music!

The final set-up should look something like this:Photo Feb 13, 9 07 54 PM

Code:

/*****
 * File: mary_lamb
 * Description: blinks LEDs to play
   Mary Had a Little Lamb.
 * HCI L0
 * netids: bmeisenm, mmcgil, vbarboy, eportnoy
 *******/

// Define which pins represent each note.
const int cpin = 3;
const int dpin = 5; 
const int epin = 9; 
const int gpin = 10;

void setup()
{
  // initialize the serial communication:
  Serial.begin(9600);
  // initialize pins output:
  pinMode(cpin, OUTPUT);
  pinMode(dpin, OUTPUT);
  pinMode(epin, OUTPUT);
  pinMode(gpin, OUTPUT);
}

// Make a pulse at pin for a length of time
void pulse(int pin, double time)
{
  int maxbright = 255;
  for (int i=0; i <= maxbright; i++) {
    analogWrite(pin, 255 - i);
    delay(time/255.0);
  }
}

// "Plays" a song
void playsong(int notes[], int lengths[], int numnotes) {
  for (int i = 0; i < numnotes; i++) {
    pulse(notes[i], lengths[i]);
  }
}

// Main run loop.
void loop() {
  // Defines pulse lengths.
  double shortpulse= 1500;
  double shorterpulse = shortpulse * 0.8;
  double longpulse = shortpulse * 1.5;
  // Defines the song! (in terms of pins & lengths)
  int notes[26] = {epin, dpin, cpin, dpin,
                 epin, epin, epin, dpin,
                 dpin, dpin, epin, gpin,
                 gpin, epin, dpin, cpin,
                 dpin, epin, epin, epin,
                 epin, dpin, dpin, epin,
                 dpin, cpin};
  int lengths[sizeof(notes)];
  for (int i=0; i < sizeof(notes); i++)
    lengths[i] = shortpulse;
  lengths[6] = longpulse;
  lengths[9] = longpulse;
  lengths[12] = longpulse;
  lengths[17] = shorterpulse;
  lengths[18] = shorterpulse;
  lengths[19] = shorterpulse;
  lengths[20] = shorterpulse;
  lengths[sizeof(notes) - 1] = longpulse;
  // Play song.
  playsong(notes, lengths, sizeof(notes));
  // Delay at end just for fun.
  delay(4000);                 
}

Color Mixer

i. Group: Philip Oasis, Gene Merewether, Alice Fuller, Rodrigo Menezes

ii. We built a color mixer, in which the user turns a potentiometer to adjust the brightness of red, green, and blue LEDs, and then observes the mixed output of the three hues on a single RGB LED.  The purpose for the user is to observe how RGB colors are mixed, as well as a fun way to try making new colors.  The tissue paper diffuser is meant to spread out the light and make it easier to view.  We feel that it is successful in achieving these goals, and that the interface is relatively easy to understand and operate.  We enjoyed using the final product and trying to make interesting colors.  We might have liked to use more LED’s to make the panel brighter and easier to see.

iii. Sketches of possible designs

20130213_201102

A reaction game where the user tries to hit the push button after the final LED is lit.

rgb-two-step-memory-game

 

A memory game in which the user uses a button to select the LED which was lit a certain number of lights ago.

20130206_210759 20130206_220008

 

A color mixer in which the user selects brightness of red, green, and blue LED’s and then observes the combination of those hues.

iv. Video of the system in action

http://www.youtube.com/watch?v=RQmMFz5ngmM

v. Parts list

  • (1) Red LED
  • (1) Green LED
  • (1) Blue LED
  • (1) Tricolor LED
  • (1) 10k trimpot
  • (4) 330 ohm resistor
  • (2) Breadboard

vi. Instructions to recreate design

  1. Connect potentiometer to analog pin A0, powered by 5v
  2. Connect push button to digital pin 2, powered by 5v, with a 330Ω resistor.
  3. Connect red, green, and blue LED’s to digital pins 3, 5, and 6 (respectively), all powered by 5v and each with a 330Ω resistor.
  4. Connect the rgb LED to digital pins 9, 10, and 11, again powered by 5v, and with 330Ω resistors.
  5. (optional) Cover the LED’s with a tissue paper diffuser

vii. Source code

const int sensorPin = 0;
const int buttonPin = 2;
const int redPin = 3;
const int greenPin = 5;
const int bluePin = 6;
const int ledRedPin = 9;
const int ledGreenPin = 10;
const int ledBluePin = 11;
 
const int RED_STATE = 0;
const int GREEN_STATE = 1;
onst int BLUE_STATE = 2;
 
int prevButtonState;
int systemState;
int redValue;
int greenValue;
int blueValue;
void setup() {
    Serial.begin(9600);
    pinMode(buttonPin, INPUT);
    pinMode(redPin, OUTPUT);
    pinMode(bluePin, OUTPUT);
    pinMode(greenPin, OUTPUT);
    pinMode(ledRedPin, OUTPUT);
    pinMode(ledGreenPin, OUTPUT);
    pinMode(ledBluePin, OUTPUT);
 
    prevButtonState = HIGH;
    systemState = RED_STATE;
    redValue = 0;
    greenValue = 0;
    blueValue = 0;
}
 
void loop() {
    int buttonState = digitalRead(buttonPin);
    int sensorValue = analogRead(sensorPin)/4;
    Serial.println(sensorValue);
 
    if (buttonState == HIGH && prevButtonState == LOW)
    {
        systemState = systemState + 1;
        if (systemState == 3)
        {
            systemState = 0;
        }

    }
    prevButtonState = buttonState;
    switch (systemState)
    {
         case RED_STATE:
             redValue = sensorValue;
             analogWrite(redPin, redValue);
             analogWrite(greenPin, 0);
             analogWrite(bluePin, 0);
             break;
         case GREEN_STATE:
             greenValue = sensorValue;
             analogWrite(redPin, 0);
             analogWrite(greenPin, greenValue);
             analogWrite(bluePin, 0);
             break;
         case BLUE_STATE:
             blueValue = sensorValue;
             analogWrite(redPin, 0);
             analogWrite(greenPin, 0);
             analogWrite(bluePin, blueValue);
             break;
         }

analogWrite(ledRedPin, redValue);
analogWrite(ledGreenPin, greenValue); 
analogWrite(ledBluePin, blueValue); 
} 

Mini Lightsaber

PART I Names

Karena Cai (kcai@)
Jean Choi (jeanchoi@)
Stephen Cognetta (cognetta@)
Eugene Lee (eugenel@)

PART II

We built a mini Lightsaber, which makes ‘authentic’ lightsaber noises when held , turns on and off with a button, changes brightness based on a knob, and also changes brightness and noise frequency when you flex your wrist. We built it because it is awesome. More seriously, we built this because the focus is on the light diffuser, as per the project description, but because it also allowed us to make a lot of interesting modifications to it. The project was an immense success. Although the lightsaber wasn’t as long or bright as we would have liked, that was a limitation of resources, not of effort. We liked that it changes brightness with both the potentiometer and flex sensor, and incorporated many types of sensors. It also interfaces with the body in an interesting way, as wrist motion affects the brightness of the LEDs. We found that the LEDs on pins 3 and 11 turn off when the buzzer (on pin 8) sounded. We were not entirely sure why. We also decided not to change the color of  the tri-color LED because it would take up 3 of the 6 analog output pins. For simplicity, we decided to connect LEDs in series, so we didn’t need to use these two analog output pins. If we were to do this again, we would begin by planning our circuit design better – we had to split components between two breadboards for greater ergo-dynamics  If we were to do this again, we would try to use more powerful LEDs of the same color to closer resemble a lightsaber. Most importantly, we would like to have some kind of impact sensor so the lightsaber can react when it is used to hit things.

PART III Sketches

20130208_152222

Light Glove

Glove turns on by clicking the switch, by using the flex sensor, one can bend ones hand to alter the light in a pattern determined by their hand motions. The flex sensor would change brightness of the LEDs.

20130208_151839

Hit the right light

Replica of an arcade game, where you must hit the proper LED when its on. The six LEDs are arranged in a circle and turn on in succession. When you hit the button when the LED is on, the digital display is incremented by one. If you miss, the buzzer will go off, but the game will continue. After 10 misses, the lights will dim and the game will end.

20130208_155053

Lightsaber

The arduino will be mounted on a handle (not included) with a protruding rod, along which the LEDS will be mounted. Button will turn the LEDs on/off, the potentiometer will change the brightness of the lights, the linear sensor (not included) will change the color of the top tri-color LED. The flex sensor will detect impacts which change the brightness of the lights and emit a sound from the buzzer.

Note: we did not include the linear sensor into our final product.

PART IV : Photo and video showing final system in action

photo

The circuit

photo (3)

In action

photo (2)

Palm of glove

photo (1)

Back of glove

PART V : List of parts used in final system: 

  • 4 LEDs
  • 1 multi-colored LED
  • 2 breadboards
  • 1 push button
  • 1potentiometer
  • 1 flex sensor
  • Arduino Uno
  • plastic straw
  • buzzer
  • 5 330 Ohm resistors
  • 1 10kOhm resistor
  • wires

PART VI :  INSTRUCTIONS

  1. Set up the potentiometer so its analog output goes to pin A0, it is powered by 5V, and connected to ground.
  2. Set up the flex sensor so that it is pulled up by a 10 kOhm resistor, and its analog output goes to pin A1. Place the flex sensor on the edge of the board with the stripes facing in the direction off of the breadboard.
  3. Set up the push button so that the digital output goes to digital pin 2 of the Arduino and it is pulled down by a 330 ohm resistor.
  4. On a separate breadboard, set up the buzzer so that it is pulled up by a 330 ohm resistor and is connected to pin 8.
  5. Connect the multi-colored LED to a 330 ohm resistor connected to digital pin 9 of the Arduino. Use long electrical wires to place the LED at the top of the straw.
  6. Place two LEDs in series, pulled up by a 330 ohm resistor and digital pin 10, and thread the LEDs into the straw using electrical wire.
  7. Use electrical tape along the electrical connections to prevent short-circuiting along the straw.
  8. Attach the flex sensor onto a glove and the lightsaber should be ready to use!

PART VII :

/*
  Karena Cai
  Stephen Cognetta
  Jean Choi
  Eugene Lee
  Sets up commands for a lightsaber/wand. Buzzes
  when flex sensor detects wrist movement, and changes brightness
  from both the potentiometer and the flex sensor. The pushbutton
  turns on and off the entire laser. 
 */
// ******************************************************
// PINS
// ******************************************************

int led1 = 6;
int led2 = 9;
int led3 = 10;

int button = 2;
int buzzer = 8;

// ******************************************************
// INPUT VARIABLES
// ******************************************************
int buttonState = 0;         // variable for reading pushbutton state
boolean lightIsOn = false;   //variable for whether saber is on
boolean firstButtonCycle = false;
int ledBrightness;

// ******************************************************
// INITIALIZE
// ******************************************************
// the setup routine runs once when you press reset:
void setup() {
  // initialize serial communication at 9600 bits per second:
  Serial.begin(9600);
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(led3, OUTPUT);
  pinMode(button, INPUT);
}

// ******************************************************
// INPUT CONTROLS
// ******************************************************
// On button down, turn the system off and on
void togglePowerState() {
  lightIsOn = lightIsOn ? false : true;
}

// pressing the button toggles the device on/off
void buttonControl(int buttonState) {
  if(buttonState == HIGH){
    // if statment prevents the device from turning on/off rapidly when 
    // the button is held down
    if (firstButtonCycle == false) {
      firstButtonCycle = true;
      togglePowerState();
    }
  }
  if(buttonState == LOW){
     firstButtonCycle = false;
  }
}

// ******************************************************
// POWER CONTROLLER
// ******************************************************
  // controls what to do when device is on and off
  // allows device to play sounds and show appropriate brightness when on
  // if off, turn off lights and sounds.
void powerControl(int ledBrightness, int flexSensorValue) {
  if(lightIsOn)
  {
    showLight(ledBrightness);
    playTone(flexSensorValue);
  }
  else 
  {
    showLight(0);
    turnOffTone();   
  }
}

// ******************************************************
// OUTPUT CONTROLS
// ******************************************************
//displays light on LEDs with brightness int bright
void showLight(int bright) {
    analogWrite(led1, bright);
    analogWrite(led2, bright);
    analogWrite(led3, bright);
}

//plays tone if flex sensor is bent beyond some fixed amount
void playTone(int flexVal) {
    if (flexVal < 300) {
      // a higher pitched noise when the flex sensor is flexed
      tone (buzzer, (800-flexVal));
    }
    else {
      // an ambient lightsaber "hum" when the flex sensor is not flexed
      tone (buzzer, 20);
    }
}

void turnOffTone () {
   noTone (buzzer); 
}

// ******************************************************
// MAIN LOOP
// ******************************************************
// the loop routine runs over and over again forever:
void loop() {
  // read the potentiometer input on analog pin 0: (0-1023)
  int potSensorValue = analogRead(A0);
  // read the flex sensor input on analog pin 1: (~314-210)
  int flexSensorValue = analogRead(A1);
  // kind of a hack, but bendValue starts at approximately 0 
  // and increases in value with larger bends
  int bendValue = (320 - flexSensorValue);

  // tells you if the button is up or down
  buttonState = digitalRead(button);
  // led brightness is a function of the potentiometer and the degree
  // to which the flex sensor is bent
  ledBrightness = constrain(potSensorValue / 10 + bendValue, 0, 255);

  // controls what happens when the button is pushed
  buttonControl(buttonState);

  // controls what to do when the device is on or off
  powerControl(ledBrightness, flexSensorValue);

  delay(10);        // delay in between reads for stability
}