Behind the Scenes – Kiana Ng – Inmi Lee

Over the course of the Interaction Lab class, I have had the opportunity to explore the functions and possibilities of different motors and sensors. The stepper motor in particular caught my attention because of how versatile it is. Depending on how you set up the stepper motor, it can be a great component in multifaceted interactions. During my first encounter with the stepper motor, my partner and I created a simple visual of a girl jumping on a trampoline in only an hour. With more time, we believed we could create something even more captivating to produce an even more interaction or conversation between the project and the audience. 

My partner and I brainstormed a few interactions we wanted to stimulate. I came up with the concept of creating an installation where components of cartoons were brought to life, for example dropping an anvil will cause the cartoonish sound to correspond. We ultimately decided we wanted to allow people to relive their childhood and invoke happy memories through nostalgia by playing a racing game. Almost everyone grew up watching comical cartoons growing up, whether it be Tom & Jerry, Looney Tunes, etc. My partner and I chose to utilize Wile E. Coyote and the Road Runner series from Looney Tunes as our models. Since Looney Tunes is more popularized in the West, our project is targeted more towards Westerners. However, the artistic style and plot of most of these cartoons are almost universal to what everyone grew up watching.

First, to replicate the idea of watching a television, we constructed a bright yellow retro style television out of cardboard, paint, and hot glue because those materials were readily accessible to us. 

Additionally, we used cardboard and painted a mini television set and the characters to fill the inside of the television. Hand-picking and mixing all the colors allowed us to fine-tune an attention-grabbing project that is pleasing to the eye.

 

To indicate that the interaction was supposed to be a game, we used arcade buttons and encompassed them with small cardboard boxes to make them easier to hold, which was a suggestion during user testing. We also used a buzzer to sound out tones of an arcade game starting and tone that indicated winning.

Finally, we added some additional touches, such as a pair of antennas (made out of wires and balls of soldered wires) and fake buttons (made out of cardboard) on the bottom of the TV.

Initially, we tried using the stepper motor template from the Interaction Lab class.

One character would be glued perpendicular to the arm of the stepper motor. When the player corresponding with Wile E. Coyote presses the button faster than the Road Runner’s player, the stepper motors would correspond to the action of Wile E. Coyote closing the distance between the two and catching up to the Road Runner. m the Interaction Lab class (as seen in the photo below). One character would occupy a stepper motor. When the player corresponding with the Road Runner presses the button faster than Wile E. Coyote’s player, the stepper motors would correspond to the action of the Road Runner creating more distance between the two and outrunning Wile E. Coyote.

However, after user testing, we received feedback that the mechanism we had used was not clear about portraying our intentions. As a result, we crafted a conveyor belt out of cardboard and created a makeshift pulley system. The belt was glued together as tightly as possible, and strips of hot glue were added to the inside of the conveyor belt to produce enough friction for the belt to grip onto the pulley. This new system made our intentions much clearer.

We glued everything together, added some lighting, placed the characters in their places, and constructed the circuit.

We encountered a couple of issues with the circuit but were able to resolve it.

We also wanted a game over sign to be displayed once one of the players won, and a portion of the Looney Tunes theme song to sound.

I tried to code the music and helped with the main code for the game however, I don’t think we allocated enough time for it. We also did not have enough time to code for the servo motos to lower the GAME OVER sign.

Ultimately, we settled on having the audience recreate the scene, instead of a game. 

The goal of our project was for everyone to revisit happy childhood memories through a game. Even though my partner and I could not produce the code for the game, I think we were successful in evoking nostalgia. The audience could interact with what we had produced, however, I think making it a game would be a better fit for the definition of interaction. Based on what we saw from the audience, people could deduce the main idea of our project, and their actions aligned with our expectations. Because my partner and I had prior commitments during LA hours, I don’t think our project could have reached its maximum potential. For the final, we will definitely clear up our schedules so that we can receive help and ensure that we can make our project exactly how we want it. Finally, I am extremely proud that we had the opportunity to create something based on what we have learned over this semester. This project allowed us to show our growth as students. 

Disassembly:

Materials:

1x Breadboard
1x Arduino Uno
1x USB Cable
2x Stepper motor (42STH33-0404AC)
2x Stepper Motor Driver Module with Barrel Jack Connector pre-connected
2x Shaft adaptor
1x 12 Volt Power Supply
1x USB Protector
1x Buzzer (Speaker)
2x 10 kOhm Resistors
2x Arcade Buttons (one per person)
A handful of M/M and F/M jumper cables
1x Box cutter knife
1x Ruler
1x Hot glue gun
1x Cardboard sheets
An array of acrylic paint
Paintbrushes
1x Scissors
1x Wire cutters
1x Cutting board
1x Masking tape
1x Marker
Not included anymore:
1x Paper template
1x Glue stick
2x Rivets (paper fasteners)
2x LEDs

Code:

/* Behind the Screens

*/

/*************************************************

Public Constants, defining the pin numbers used in Arduino

*************************************************/

int buzzerPin = 8;

int buttonPin1 = 10;

int buttonPin2 = 9;

//int ledPin1 = 9;

//int ledPin2 = 10;

/*************************************************

Public Constants, defining the notes in Hertz

*************************************************/

#define NOTE_B0 31

#define NOTE_C1 33

#define NOTE_CS1 35

#define NOTE_D1 37

#define NOTE_DS1 39

#define NOTE_E1 41

#define NOTE_F1 44

#define NOTE_FS1 46

#define NOTE_G1 49

#define NOTE_GS1 52

#define NOTE_A1 55

#define NOTE_AS1 58

#define NOTE_B1 62

#define NOTE_C2 65

#define NOTE_CS2 69

#define NOTE_D2 73

#define NOTE_DS2 78

#define NOTE_E2 82

#define NOTE_F2 87

#define NOTE_FS2 93

#define NOTE_G2 98

#define NOTE_GS2 104

#define NOTE_A2 110

#define NOTE_AS2 117

#define NOTE_B2 123

#define NOTE_C3 131

#define NOTE_CS3 139

#define NOTE_D3 147

#define NOTE_DS3 156

#define NOTE_E3 165

#define NOTE_F3 175

#define NOTE_FS3 185

#define NOTE_G3 196

#define NOTE_GS3 208

#define NOTE_A3 220

#define NOTE_AS3 233

#define NOTE_B3 247

#define NOTE_C4 262

#define NOTE_CS4 277

#define NOTE_D4 294

#define NOTE_DS4 311

#define NOTE_E4 330

#define NOTE_F4 349

#define NOTE_FS4 370

#define NOTE_G4 392

#define NOTE_GS4 415

#define NOTE_A4 440

#define NOTE_AS4 466

#define NOTE_B4 494

#define NOTE_C5 523

#define NOTE_CS5 554

#define NOTE_D5 587

#define NOTE_DS5 622

#define NOTE_E5 659

#define NOTE_F5 698

#define NOTE_FS5 740

#define NOTE_G5 784

#define NOTE_GS5 831

#define NOTE_A5 880

#define NOTE_AS5 932

#define NOTE_B5 988

#define NOTE_C6 1047

#define NOTE_CS6 1109

#define NOTE_D6 1175

#define NOTE_DS6 1245

#define NOTE_E6 1319

#define NOTE_F6 1397

#define NOTE_FS6 1480

#define NOTE_G6 1568

#define NOTE_GS6 1661

#define NOTE_A6 1760

#define NOTE_AS6 1865

#define NOTE_B6 1976

#define NOTE_C7 2093

#define NOTE_CS7 2217

#define NOTE_D7 2349

#define NOTE_DS7 2489

#define NOTE_E7 2637

#define NOTE_F7 2794

#define NOTE_FS7 2960

#define NOTE_G7 3136

#define NOTE_GS7 3322

#define NOTE_A7 3520

#define NOTE_AS7 3729

#define NOTE_B7 3951

#define NOTE_C8 4186

#define NOTE_CS8 4435

#define NOTE_D8 4699

#define NOTE_DS8 4978

/*************************************************

Public Variables

*************************************************/

//button and count variables

int goal = 15;

int buttonState1 = LOW;

int previousState1 = LOW;

int buttonState2 = LOW;

int previousState2 = LOW;

int counter1 = 0;

int counter2 = 0;

boolean winner1 = false;

boolean winner2 = false;

long time = 0; // the last time the output pin was toggled

long debounce = 200; // the debounce time, increase if the output flickers

//stepper motor variables

#include <AccelStepper.h>

int randNumber1;

int randNumber2;

int CDIR_PIN = 2;

int CSTEP_PIN = 3;

int CEN_PIN = 4;

int RDIR_PIN = 5;

int RSTEP_PIN = 6;

int REN_PIN = 7;

AccelStepper stepperC(AccelStepper::DRIVER, CSTEP_PIN, CDIR_PIN);

AccelStepper stepperR(AccelStepper::DRIVER, RSTEP_PIN, RDIR_PIN);

//servo motor variables

//#include <Servo.h>

//Servo servoL;

//Servo servoR;

// notes in the main theme melody and duration

int melody[] = {

NOTE_G4,

NOTE_A4,

NOTE_E4,

NOTE_G4,

0,

NOTE_G4,

NOTE_A4,

NOTE_E4,

NOTE_G4,

0,

NOTE_G4,

NOTE_A4,

NOTE_E4,

NOTE_G4,

NOTE_A4,

NOTE_B4,

0,

};

int noteDurations[] = {

16, 16, 8, 4, 8,

16, 16, 8, 4, 8,

16, 16, 4, 4, 4, 1

};

void setup() {

Serial.begin(9600);

pinMode(buzzerPin, OUTPUT);

pinMode(buttonPin1, INPUT);

pinMode(buttonPin2, INPUT);

randNumber1 = random(0, 100);

randNumber2 = random(100, 200);

//pinMode(ledPin1, OUTPUT);

//pinMode(ledPin2, OUTPUT);

Serial.println("******************* LOONEY TUNES *******************");

delay(1000);

Serial.println("READY");

tone(8, 440);

delay(1000);

noTone(8);

delay(50);

Serial.println("SET");

tone(8, 440);

delay(1000);

noTone(8);

delay(50);

Serial.println("GO!!!!!!!!!!!!!!!!");

tone(8, 880);

delay(1500);

noTone(8);

// Set initial speed & acceleration for stepper motors

pinMode(CEN_PIN, OUTPUT);

digitalWrite(CEN_PIN, LOW);

stepperC.setMaxSpeed(500);

stepperC.setAcceleration(300);

pinMode(REN_PIN, OUTPUT);

digitalWrite(REN_PIN, LOW);

stepperR.setMaxSpeed(500);

stepperR.setAcceleration(300);

stepperC.setCurrentPosition(0);

stepperR.setCurrentPosition(0);

//set up servo motors

// servoL.attach(11);

// servoR.attach(12);

// servoL.write(90);

// servoR.write(0);

}

void loop() {

buttonState1 = digitalRead(buttonPin1);

buttonState2 = digitalRead(buttonPin2);

//Serial.println(buttonState1);

//this checks the times player 01 has pressed the button

if (counter1 < goal && winner2 == false) {

if (buttonState1 != previousState1 && millis() - time > debounce) {

if (buttonState1 == HIGH) {

counter1++;

Serial.print("player 01: ");

Serial.println(counter1);

time = millis();

}

}

previousState1 = buttonState1;

if (counter1 == goal && winner2 == false) {

winner1 = true;

// digitalWrite(ledPin1, HIGH);

Serial.println("PLAYER 01 WINS");

// servoL.write(180);

// servoR.write(90);

delay(500);

playMelody();

endGame();

}

}

//this checks the times player 02 has pressed the button

if (counter2 < goal && winner1 == false) {

if (buttonState2 != previousState2 && millis() - time > debounce) {

if (buttonState2 == HIGH) {

counter2++;

Serial.print("player 02: ");

Serial.println(counter2);

time = millis();

}

}

previousState2 = buttonState2;

if (counter2 == goal && winner2 == false) {

winner2 = true;

//digitalWrite(ledPin2, HIGH);

Serial.println("PLAYER 02 WINS");

playMelody();

endGame();

// servoL.write(180);

// servoR.write(90);

}

}

//this prompts the two characters to move based on the number of counts of each player

if (counter2 > counter1) {

stepperC.runToNewPosition(randNumber2);

stepperR.runToNewPosition(randNumber1);

} else {

stepperC.runToNewPosition(randNumber1);

stepperR.runToNewPosition(randNumber2);

}

}

void playMelody() {

for (int thisNote = 0; thisNote < 18; thisNote++) {

int noteDuration = 1000 / noteDurations[thisNote];

tone(8, melody[thisNote], noteDuration);

int pauseBetweenNotes = noteDuration * 1.30;

delay(pauseBetweenNotes);

noTone(8);

}

}

void endGame() {

stepperC.runToNewPosition(0);

stepperC.runToNewPosition(0);

int counter1 = 0;

int counter2 = 0;

boolean winner1 = false;

boolean winner2 = false;

stepperC.stop();

stepperR.stop();

// servoL.write(180);

// servoR.write(90);

}

Leave a Reply

Your email address will not be published. Required fields are marked *