PHYSCI 70: Introduction to Digital Fabrication

Marie Konopacki

Final Project Proposal

About Me

Week 8

For this week, we had to use an output device we hadn’t used before. I immediately knew I wanted to work with the LED strip. But when I received it in the mail, one of the wires came off. But then, quite miraculously, I found out that my dad owns a soldering kit. I thought I’d be in the clear then, but the solder wouldn’t stick to the LED tape. After a painful hour of labor, I finally got it the solder to work, after having to cut one a section off since the heat damage was too severe. As I plugged the strip into my computer, I was hoping for a brilliant light show…. Nada. In a final ironic twist of fate, I realized that all of the wires were attached to the wrong side. But after connecting alligator clips to the other side, I was finally set to start.

I really wanted this week’s project to be both whimsical and interactive. After deciding I wanted to make some kind of game, I suddenly remembered the arcade game Cyclone. Essentially, a light moves in a cycle, and the player has to press a button at precisely when the light falls on the “target”. Every time I’ve been to a bowling alley or an arcade, I always gravitate towards this game, so I knew it would be fun to make my own attempt at it.

It took me a while to figure out how to code it, since I faced some problems when incorporating the button and the delay function. After a lot of research, I realized I should use the Millis function instead of delay. I’m super satisfied with how it turned out! After each round, the game speeds up by 20% indefinitely, and if you lose a round it resets to the initial speed. Each round has a new target light so it isn’t monotonous. I’ve attached the demo to the left and the code below!

#include <Adafruit_NeoPixel.h>

#define PIN        9 
#define NUMPIXELS 9 
#define BUTTONPIN   3

int DELAYVAL = 200; // Time (in milliseconds) to pause between pixels
unsigned long time_now = 0;

Adafruit_NeoPixel strip(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);

int buttonState = 0;         // variable for reading the pushbutton status
int targetLight = 4; // Set up intial target light, to be changed later

void setup() {
  pinMode(BUTTONPIN, INPUT_PULLUP); // Initialize button 
  Serial.begin(115200); //Baud rate for the Serial Monitor

  strip.begin(); // INITIALIZE NeoPixel strip object (REQUIRED)
  strip.show();            // Turn OFF all pixels
  strip.setBrightness(10); // Set BRIGHTNESS low to reduce draw (max = 255)

  randomSeed(analogRead(A0)); // Random number generator   

}

void loop() {
  strip.clear(); // Set all pixel colors to 'off'

  for(int i=0; i<NUMPIXELS; i++) { // For each pixel...
    time_now = millis(); // reset timer

    strip.clear(); // Set all pixel colors to 'off'
    strip.setPixelColor(targetLight, strip.Color(200, 200, 0)); // Keep lit the "chosen" bulb

    strip.setPixelColor(i, strip.Color(180, 0, 150)); // Light up the current bulb
    strip.show();   // Send the updated pixel colors to the hardware.

    while(millis() < time_now + DELAYVAL){
      buttonState = digitalRead(BUTTONPIN);  // check if the pushbutton is pressed
      if (buttonState) {
        if (i == targetLight) { // If the player successfully hits it
          winblink(i); // Winning blink sequence
          targetLight = random(0, 8); // Random number to create new target light
          DELAYVAL = DELAYVAL * .8; // Make the game go faster
        } else {
          loseblink(i); // Losing blink sequence
          DELAYVAL = 200; // Reset delay value
        };
      };
    };
  }
}

void winblink(int i) {
  strip.clear();
  strip.fill(strip.Color(0, 200, 0));
  strip.show();   // Send the updated pixel colors to the hardware.
  delay(300);
  strip.clear();
  strip.fill(strip.Color(0, 0, 0));
  strip.setPixelColor(i, strip.Color(100, 0, 100)); // Light up the current bulb
  strip.show();   // Send the updated pixel colors to the hardware.  delay(300);
  delay(300);
  strip.clear();
  strip.fill(strip.Color(0, 200, 0));
  strip.show();   // Send the updated pixel colors to the hardware.
  delay(300);
  strip.clear();
  strip.fill(strip.Color(0, 0, 0));
  strip.setPixelColor(i, strip.Color(100, 0, 100)); // Light up the current bulb
  strip.show();   // Send the updated pixel colors to the hardware.  delay(300);
  delay(300);
  strip.clear();
  strip.fill(strip.Color(0, 200, 0));
  strip.show();   // Send the updated pixel colors to the hardware.
  delay(300);
  strip.clear();
  strip.fill(strip.Color(0, 0, 0));
  strip.setPixelColor(i, strip.Color(100, 0, 100)); // Light up the current bulb
  strip.show();   // Send the updated pixel colors to the hardware.  delay(300);
  delay(300);
}

void loseblink(int i) {
  strip.clear();
  strip.fill(strip.Color(200, 0, 0));
  strip.show();   // Send the updated pixel colors to the hardware.
  delay(300);
  strip.clear();
  strip.fill(strip.Color(0, 0, 0));
  strip.setPixelColor(i, strip.Color(100, 0, 100)); // Light up the current bulb
  strip.show();   // Send the updated pixel colors to the hardware.  delay(300);
  delay(300);
  strip.clear();
  strip.fill(strip.Color(200, 0, 0));
  strip.show();   // Send the updated pixel colors to the hardware.
  delay(300);
  strip.clear();
  strip.fill(strip.Color(0, 0, 0));
  strip.setPixelColor(i, strip.Color(100, 0, 100)); // Light up the current bulb
  strip.show();   // Send the updated pixel colors to the hardware.  delay(300);
  delay(300);
  strip.clear();
  strip.fill(strip.Color(200, 0, 0));
  strip.show();   // Send the updated pixel colors to the hardware.
  delay(300);
  strip.clear();
  strip.fill(strip.Color(0, 0, 0));
  strip.setPixelColor(i, strip.Color(100, 0, 100)); // Light up the current bulb
  strip.show();   // Send the updated pixel colors to the hardware.  delay(300);
  delay(300);

}