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