Project Title: How well can you binary?

Basic setup + loading screen
Normal test_smol
Video showing a run through of the piece
GOOD result_smol
Video showing a run through of the piece fast enough to be judged as “good”
AND fail_smol
Video showing what happens if you try to press both buttons

Leah taking the “How well can you binary?” test

User experience

Super secret wiring contained in the podium: Arduino connected to buttons and the “AND” logic gate breadboard setup.
Simple narrative description:
There is a podium with two buttons on it in front of a projection. When the user presses a button the “test” begins, asking the user to choose between two different options. If the user tries to press both buttons at once a loud buzzer goes off and the projection flashes “AND is not an option.” Each time the user answers a question a ticking noise gets faster. After the last question the test/projection tells the user if they were “BAD” or “GOOD” based on how fast they were able to answer the questions.
Process Images:

Tiny test of the two buttons to arduino setup

Layout of various tasks mid-process

Early code testing the two button input before adding to main body of code

Figuring out how to add sound

Adding sound to the basic question setup

Testing the code before the buttons arrived using mouse+ keyboard inputs
Process Reflection:
Surprisingly for me the easier aspect of the project was the technical parts. In the past I have struggled the most with the coding and the wiring of the piece but I think I did an okay job giving myself a project that was relatively approachable for someone with my level of experience. It was difficult enough coding-wise where I definitely learned something (I’ve never used Processing before) but not so difficult that I saw it as a major challenge.
I think the biggest hurdle that I had to tackle was conceptual: how do I make sure my piece is meaningful? Or maybe: how do I make sure what I imagined as being “good” about the project comes through? This, for me, was more of a design problem than anything else. I wanted to make sure the piece had an element of absurdity while still making the message meaningful, and I didn’t know if there was any way to test whether or not I had crossed that line until I actually presented the thing. I think something akin to the 90% critique we are going to have for the next project would have helped me resolve this problem/these doubts before the final presentation. I think what was interesting to find out during the final critique was how people wanted to explore the piece more in terms of figuring out the different outcomes (ie rushing through the questions to get to the “you are…GOOD” outcome) as opposed to focusing on the meaning behind the questions themselves. I wonder if there is some element of the “game” that could have been changed to focus more thoroughly on the conceptual meaning behind the piece.
Elements such as messing with the question format and making the podium a binary in and of itself, suggestions I received during the critique from our guest critics, definitely might have improved this aspect of the “game.” In the end I learned that the design of the thing (the appearance of the interface, how it moved between questions, what the podium looked like) for me at least, ended up being the biggest hurdle, and something I needed more feedback on, than the technical problems I expected to struggle with more. In the future I need to focus more on getting the technical stuff out of the way earlier so that I can have people interact with the piece earlier on in order to incorporate design feedback to the functionality of the piece before the final critique.
Arduino Code:
- The code reads the input coming from the buttons and through the "AND" gate circuit (set to the 8,7, and 4 pins on the arduino)
and sends the information to the processing code as either a "0", "2", "3", or "4" depending on the input.
- code is based on the basic "digital button" sketch provided with the arduino
// constants won't change. They're used here to set pin numbers:
const int leftButtonPin = 8; // the number of the left pushbutton pin
const int rightButtonPin = 7; // the number of the right pushbutton pin
// variables will change:
int leftButtonState = 0; // variable for reading the left pushbutton status
int rightButtonState = 0; // variable for reading the right pushbutton status
// initialize the pushbuttons + AND gate pin as inputs:
pinMode(leftButtonPin, INPUT);
pinMode(rightButtonPin, INPUT);
// read the state of the pushbutton value:
leftButtonState = digitalRead(leftButtonPin);
rightButtonState = digitalRead(rightButtonPin);
andState = digitalRead(andPin);
if (andState == HIGH) { // if the and gate is activated...
Serial.write(3); //send a 3 to Processing
// check if the pushbutton is pressed. If it is, the buttonState is HIGH:
else if (leftButtonState == HIGH) { //send a 4 to processing if the left button is pressed
delay(100); // delays help prevent the code from sending out "double presses"
//Serial.print("left"); // these are commented out but used them to test the button input
else if (rightButtonState == HIGH) { // send a 2 to processing if the right button is pressed
Serial.write(0); // if nothing is happening send 0 to Processing
delay(50); // Wait 50 milliseconds
/*
How well can you binary?
Kirman Hanson
- The code reads the input coming from the buttons and through the "AND" gate circuit (set to the 8,7, and 4 pins on the arduino)
and sends the information to the processing code as either a "0", "2", "3", or "4" depending on the input.
- code is based on the basic "digital button" sketch provided with the arduino
*/
// constants won't change. They're used here to set pin numbers:
const int leftButtonPin = 8; // the number of the left pushbutton pin
const int rightButtonPin = 7; // the number of the right pushbutton pin
const int andPin = 4;
// variables will change:
int leftButtonState = 0; // variable for reading the left pushbutton status
int rightButtonState = 0; // variable for reading the right pushbutton status
int andState = 0;
void setup() {
// initialize the pushbuttons + AND gate pin as inputs:
pinMode(leftButtonPin, INPUT);
pinMode(rightButtonPin, INPUT);
pinMode (andPin, INPUT);
Serial.begin(9600);
}
void loop() {
// read the state of the pushbutton value:
leftButtonState = digitalRead(leftButtonPin);
rightButtonState = digitalRead(rightButtonPin);
andState = digitalRead(andPin);
if (andState == HIGH) { // if the and gate is activated...
Serial.write(3); //send a 3 to Processing
Serial.write(0);
//delay (500);
// check if the pushbutton is pressed. If it is, the buttonState is HIGH:
}
else if (leftButtonState == HIGH) { //send a 4 to processing if the left button is pressed
delay(100); // delays help prevent the code from sending out "double presses"
Serial.write(4);
Serial.write(0);
//Serial.print("left"); // these are commented out but used them to test the button input
//Serial.print("off");
delay(500);
}
else if (rightButtonState == HIGH) { // send a 2 to processing if the right button is pressed
delay(100);
Serial.write(2);
Serial.write(0);
//Serial.print("right");
// Serial.print("off");
delay (500);
}
else {
Serial.write(0); // if nothing is happening send 0 to Processing
}
delay(50); // Wait 50 milliseconds
/*
How well can you binary?
Kirman Hanson
- The code reads the input coming from the buttons and through the "AND" gate circuit (set to the 8,7, and 4 pins on the arduino)
and sends the information to the processing code as either a "0", "2", "3", or "4" depending on the input.
- code is based on the basic "digital button" sketch provided with the arduino
*/
// constants won't change. They're used here to set pin numbers:
const int leftButtonPin = 8; // the number of the left pushbutton pin
const int rightButtonPin = 7; // the number of the right pushbutton pin
const int andPin = 4;
// variables will change:
int leftButtonState = 0; // variable for reading the left pushbutton status
int rightButtonState = 0; // variable for reading the right pushbutton status
int andState = 0;
void setup() {
// initialize the pushbuttons + AND gate pin as inputs:
pinMode(leftButtonPin, INPUT);
pinMode(rightButtonPin, INPUT);
pinMode (andPin, INPUT);
Serial.begin(9600);
}
void loop() {
// read the state of the pushbutton value:
leftButtonState = digitalRead(leftButtonPin);
rightButtonState = digitalRead(rightButtonPin);
andState = digitalRead(andPin);
if (andState == HIGH) { // if the and gate is activated...
Serial.write(3); //send a 3 to Processing
Serial.write(0);
//delay (500);
// check if the pushbutton is pressed. If it is, the buttonState is HIGH:
}
else if (leftButtonState == HIGH) { //send a 4 to processing if the left button is pressed
delay(100); // delays help prevent the code from sending out "double presses"
Serial.write(4);
Serial.write(0);
//Serial.print("left"); // these are commented out but used them to test the button input
//Serial.print("off");
delay(500);
}
else if (rightButtonState == HIGH) { // send a 2 to processing if the right button is pressed
delay(100);
Serial.write(2);
Serial.write(0);
//Serial.print("right");
// Serial.print("off");
delay (500);
}
else {
Serial.write(0); // if nothing is happening send 0 to Processing
}
delay(50); // Wait 50 milliseconds
Processing Code:
Code draws up the interface for the game/test of the piece and
it changes the interface in response to the button presses as inputs being
read by the arduino code.
Basic structure for code is based off the basic "serial read" example
that comes with Processing
Zach + classmates helped with troubleshooting, Erin with the design elements
import processing.serial.*;
import processing.sound.*;
Serial myPort; // Create object from Serial class
int buttonVal; // Data received from the serial port
PFont f, qFont, andFont, startFont;
StringList qInventory, firstAInventory, secondAInventory;
boolean andTrigger = false; // this bool is used to trigger the "AND" state (ie the buzzer)
boolean leftHighlight = false;
boolean rightHighlight = false;
boolean buttonPressed = false;
boolean flickerLoad = false;
int warningStart = 100000;
SoundFile ticker, endBeep, endBeep2, wrongNoise;
String tickerFile = "tick2.0.wav";
boolean endStart = false;
// draws the basic interface
f = createFont("KohinoorDevanagari-Bold", 40);
qFont = createFont("KohinoorDevanagari-Regular", 54);
andFont = createFont("KohinoorDevanagari-Bold", 90);
startFont = createFont("KohinoorDevanagari-Regular", 30);
// all "inventories" are string lists containing the questions and/or answers. Change as you wish.
qInventory = new StringList("The lights are...", "It is...", "I am...", "I am...","The sky is...", "I am a student", "I am in a ___ mood", "I am...", "I am only good at...", "I am a...", "I ___ therefore I am", "I am good at making decisions", "I am...", "Carngie Mellon is...", "I am a...", "I am...", "I am...", "I am...", "I am...", "I am...");
firstAInventory = new StringList("on", "cold", "inside", "left-handed", "up", "yes", "good", "being", "art", "good person","think", "yes", "strong", "ethical", "success", "lucky", "not fun", "spiritual", "natural", "on");
println(firstAInventory.size()); // helps to diagnose whether you have enough answers for your questions
secondAInventory = new StringList("off", "hot", "outside", "right-handed", "down", "no", "bad", "becoming", "science", "bad person", "feel", "no", "weak", "unethical", "failure", "hard-working", "fun", "rational", "unnatural", "off");
ticker = new SoundFile(this, tickerFile);
ticker.loop(1,amp); // initializes the "ticking" noise
println(qInventory.size());
println(secondAInventory.size());
String portName = Serial.list()[4];
myPort = new Serial(this, portName, 9600);
if ( myPort.available() > 0) { // If data is available,
buttonVal = myPort.read(); // read it and store it in val
if (buttonPressed == false){ // tests whether or not the button has been pressed
amp = 0; // if not ticker is silent
if (buttonVal == 4 || buttonVal == 2){ //gets the interface out of "start" mode
println("button pressed now true");
amp = 0.05; // ticker is now able to be heard
else if (second()%2 == 0){ // sets up the "start mode", uses modulus to "blink" the text
text("How well can you binary?", width/2, height*0.333);
// every 2 seconds flip the bool in order to create "flicker" effect
if (flickerLoad == false){
//println("flipped to true");
else if(flickerLoad==true){
else if(flickerLoad == true){
text("PRESS ANY BUTTON TO START", width/2, height/2);
else if (buttonVal == 3) { // if the arduino sends out a 3,triggers the "AND" state
println("and triggered");
if (millis() - warningStart < 1200){ //only displays for 1.2 seconds
//play dramatic tone here
andTrigger = false; // automatically ends after 1.2 seconds
else if ((buttonVal == 4 || buttonVal== 2)&& buttonVal!=3 && endStart == false) {
//moves onto next question + triggers end state if we are at the end of the list of questions
qCount +=1; // the q count counts the number of questions answered
println("tickerRate", tickerRate);
if (qCount < qInventory.size()) {
tickerRateIncrease(buttonVal); //increases the speed of the ticker everytime question is answered
else { // triggers the "end game" function once at end of the questions
endBeep = new SoundFile(this, "endbeep.mp3");
endBeep2 = new SoundFile(this, "endbeep_extra.wav");
println("endStart set to true");
else if (qCount < qInventory.size()) { //displays the different questions so long as there are questions left
text(qInventory.get(qCount), width* 0.5, height*0.333);
//set up highlights when button pressed
if (leftHighlight==true && millis()- questionStart < 300 && andTrigger==false){
println("left Highlight", leftHighlight);
rect(width*0.333, height*0.666, 200, 80);
text(firstAInventory.get(qCount), width*0.333, height*0.666);//retrieves the correstpodning answer from the list
else if (rightHighlight==true && millis()- questionStart < 300 && andTrigger==false){
println("right highlight", rightHighlight);
rect(width*0.666, height*0.666, 200, 80);
text(secondAInventory.get(qCount), width*0.666, height*0.666);//retrieves the correstpodning answer from the list
// "normal" question display
text(secondAInventory.get(qCount), width*0.666, height*0.666);
text(firstAInventory.get(qCount), width*0.333, height*0.666);
//if neither is picked don't highlight it
// this function sets up the "AND" state
if (millis() - warningStart < 1200 && andTrigger==true){
wrongNoise = new SoundFile(this, "wrong.wav");
text("AND is not an option", width/2, height/2);
// this sequence is the end state
if (endStart==true && millis()-endTime < 2500){
println("end game displayed");
text("END GAME", width/2, height/2);
println("endTime", endTime);
println("endStart", endStart);
println("millis-endTime", millis()-endTime);
println("millis", millis());
if (millis()-endTime < 8000 && millis()-endTime >= 2500){
println("calculating score displayed");
text("Calculating results...", width/2, height/2);
if (endStart==true && millis()-endTime < 10000 && millis()-endTime >= 8000){
text("You are...", width/2, height/2);
if (endStart==true && millis()-endTime < 12000 && millis()-endTime >= 10000 && totalTime <= 30000){
text("GOOD", width/2, height/2);
if (endStart==true && millis()-endTime < 12000 && millis()-endTime >= 10000 && totalTime > 30000){
text("BAD", width/2, height/2);
if(endStart == true && millis()-endTime >= 14000){
println("went to no loop");
text("", width/2, height/2);
void tickerRateIncrease(int buttonVal) { //this function controls the ticker rate
//increase rate + loudness
timeToAnswer = millis() - questionStart;
totalTime += timeToAnswer;
questionStart = millis();
String rateString = nf(tickerRate, 1, 1);
println("new ticker rate", tickerRate);
String[] tickerParts = new String[3];
tickerParts[1] = rateString;
String tickerFile = join(tickerParts, ""); //sets up new ticker file name to be retrieved
ticker = new SoundFile(this, tickerFile);
ticker.loop(1,amp);//plays new, faster, ticker file
/*
How well can you binary?
Kirman Hanson
Code draws up the interface for the game/test of the piece and
it changes the interface in response to the button presses as inputs being
read by the arduino code.
Basic structure for code is based off the basic "serial read" example
that comes with Processing
Zach + classmates helped with troubleshooting, Erin with the design elements
*/
import processing.serial.*;
import processing.sound.*;
Serial myPort; // Create object from Serial class
int buttonVal; // Data received from the serial port
PFont f, qFont, andFont, startFont;
StringList qInventory, firstAInventory, secondAInventory;
int qCount = 0;
boolean andTrigger = false; // this bool is used to trigger the "AND" state (ie the buzzer)
boolean leftHighlight = false;
boolean rightHighlight = false;
boolean buttonPressed = false;
boolean flickerLoad = false;
int warningStart = 100000;
SoundFile ticker, endBeep, endBeep2, wrongNoise;
float tickerRate = 2.0;
String tickerFile = "tick2.0.wav";
float amp = 0;
float questionStart;
float timeToAnswer;
float totalTime;
boolean endStart = false;
float endTime;
void setup() {
// draws the basic interface
size(1400,900);
f = createFont("KohinoorDevanagari-Bold", 40);
qFont = createFont("KohinoorDevanagari-Regular", 54);
andFont = createFont("KohinoorDevanagari-Bold", 90);
startFont = createFont("KohinoorDevanagari-Regular", 30);
// all "inventories" are string lists containing the questions and/or answers. Change as you wish.
qInventory = new StringList("The lights are...", "It is...", "I am...", "I am...","The sky is...", "I am a student", "I am in a ___ mood", "I am...", "I am only good at...", "I am a...", "I ___ therefore I am", "I am good at making decisions", "I am...", "Carngie Mellon is...", "I am a...", "I am...", "I am...", "I am...", "I am...", "I am...");
firstAInventory = new StringList("on", "cold", "inside", "left-handed", "up", "yes", "good", "being", "art", "good person","think", "yes", "strong", "ethical", "success", "lucky", "not fun", "spiritual", "natural", "on");
println(firstAInventory.size()); // helps to diagnose whether you have enough answers for your questions
secondAInventory = new StringList("off", "hot", "outside", "right-handed", "down", "no", "bad", "becoming", "science", "bad person", "feel", "no", "weak", "unethical", "failure", "hard-working", "fun", "rational", "unnatural", "off");
ticker = new SoundFile(this, tickerFile);
ticker.loop(1,amp); // initializes the "ticking" noise
println(qInventory.size());
println(secondAInventory.size());
// button input
String portName = Serial.list()[4];
myPort = new Serial(this, portName, 9600);
}
void draw() {
background(255);
fill(0);
textAlign(CENTER);
if ( myPort.available() > 0) { // If data is available,
buttonVal = myPort.read(); // read it and store it in val
}
if (buttonPressed == false){ // tests whether or not the button has been pressed
background(255);
amp = 0; // if not ticker is silent
if (buttonVal == 4 || buttonVal == 2){ //gets the interface out of "start" mode
buttonPressed = true;
println("button pressed now true");
amp = 0.05; // ticker is now able to be heard
}
else if (second()%2 == 0){ // sets up the "start mode", uses modulus to "blink" the text
fill(0);
textFont(startFont);
text("How well can you binary?", width/2, height*0.333);
// every 2 seconds flip the bool in order to create "flicker" effect
if (flickerLoad == false){
//println("flipped to true");
delay(10);
flickerLoad = true;
delay(10);
}
else if(flickerLoad==true){
flickerLoad = false;
}
}
else if(flickerLoad == true){
fill(0);
textFont(qFont);
text("PRESS ANY BUTTON TO START", width/2, height/2);
}
}
else if (buttonVal == 3) { // if the arduino sends out a 3,triggers the "AND" state
println("and triggered");
fill(255);
warningStart = millis();
if (millis() - warningStart < 1200){ //only displays for 1.2 seconds
andTrigger = true;
//play dramatic tone here
}
else {
andTrigger = false; // automatically ends after 1.2 seconds
}
}
else if ((buttonVal == 4 || buttonVal== 2)&& buttonVal!=3 && endStart == false) {
//moves onto next question + triggers end state if we are at the end of the list of questions
delay(100);
qCount +=1; // the q count counts the number of questions answered
andTrigger = false;
println("tickerRate", tickerRate);
if (qCount < qInventory.size()) {
tickerRateIncrease(buttonVal); //increases the speed of the ticker everytime question is answered
}
else { // triggers the "end game" function once at end of the questions
endTime = millis();
ticker.stop();
endBeep = new SoundFile(this, "endbeep.mp3");
endBeep2 = new SoundFile(this, "endbeep_extra.wav");
endBeep.playFor(2.0);
endStart = true;
println("endStart set to true");
}
}
else if (qCount < qInventory.size()) { //displays the different questions so long as there are questions left
background(255);
textFont(qFont);
text(qInventory.get(qCount), width* 0.5, height*0.333);
textFont(f);
//set up highlights when button pressed
if (leftHighlight==true && millis()- questionStart < 300 && andTrigger==false){
println("left Highlight", leftHighlight);
rectMode(CENTER);
fill(0);
rect(width*0.333, height*0.666, 200, 80);
fill(255);
text(firstAInventory.get(qCount), width*0.333, height*0.666);//retrieves the correstpodning answer from the list
println(qCount);
}
else if (rightHighlight==true && millis()- questionStart < 300 && andTrigger==false){
println("right highlight", rightHighlight);
rectMode(CENTER);
fill(0);
rect(width*0.666, height*0.666, 200, 80);
fill(255);
text(secondAInventory.get(qCount), width*0.666, height*0.666);//retrieves the correstpodning answer from the list
println(qCount);
}
else{
// "normal" question display
fill(0);
text(secondAInventory.get(qCount), width*0.666, height*0.666);
text(firstAInventory.get(qCount), width*0.333, height*0.666);
//if neither is picked don't highlight it
rightHighlight = false;
leftHighlight = false;
}
}
// this function sets up the "AND" state
if (millis() - warningStart < 1200 && andTrigger==true){
wrongNoise = new SoundFile(this, "wrong.wav");
wrongNoise.play();
delay(90);
fill(255,0,0);
background(255);
textFont(andFont);
text("AND is not an option", width/2, height/2);
}
// this sequence is the end state
if (endStart == true){
println("end state");
ticker.stop();
if (endStart==true && millis()-endTime < 2500){
println("end game displayed");
textFont(andFont);
text("END GAME", width/2, height/2);
println("endTime", endTime);
println("endStart", endStart);
println("millis-endTime", millis()-endTime);
println("millis", millis());
}
if (millis()-endTime < 8000 && millis()-endTime >= 2500){
println("calculating score displayed");
textFont(qFont);
text("Calculating results...", width/2, height/2);
}
if (endStart==true && millis()-endTime < 10000 && millis()-endTime >= 8000){
println("you are...");
textFont(qFont);
text("You are...", width/2, height/2);
}
if (endStart==true && millis()-endTime < 12000 && millis()-endTime >= 10000 && totalTime <= 30000){
textFont(andFont);
background(0,255,0);
fill(255);
text("GOOD", width/2, height/2);
}
if (endStart==true && millis()-endTime < 12000 && millis()-endTime >= 10000 && totalTime > 30000){
textFont(andFont);
background(255,0,0);
text("BAD", width/2, height/2);
}
if(endStart == true && millis()-endTime >= 14000){
println("went to no loop");
println(endTime);
text("", width/2, height/2);
fill(0);
noLoop();
}
}
}
void tickerRateIncrease(int buttonVal) { //this function controls the ticker rate
println("click");
if (buttonVal == 4){
leftHighlight = true;
}
if (buttonVal== 2){
rightHighlight = true;
}
//increase rate + loudness
tickerRate -= 0.1;
amp += 0.05;
// endstate calculations
timeToAnswer = millis() - questionStart;
totalTime += timeToAnswer;
questionStart = millis();
//changing rates
String rateString = nf(tickerRate, 1, 1);
println("new ticker rate", tickerRate);
String[] tickerParts = new String[3];
tickerParts[0] = "tick";
tickerParts[1] = rateString;
tickerParts[2] = ".wav";
String tickerFile = join(tickerParts, ""); //sets up new ticker file name to be retrieved
ticker.stop();
ticker = new SoundFile(this, tickerFile);
ticker.cue(0.3);
ticker.loop(1,amp);//plays new, faster, ticker file
}
/*
How well can you binary?
Kirman Hanson
Code draws up the interface for the game/test of the piece and
it changes the interface in response to the button presses as inputs being
read by the arduino code.
Basic structure for code is based off the basic "serial read" example
that comes with Processing
Zach + classmates helped with troubleshooting, Erin with the design elements
*/
import processing.serial.*;
import processing.sound.*;
Serial myPort; // Create object from Serial class
int buttonVal; // Data received from the serial port
PFont f, qFont, andFont, startFont;
StringList qInventory, firstAInventory, secondAInventory;
int qCount = 0;
boolean andTrigger = false; // this bool is used to trigger the "AND" state (ie the buzzer)
boolean leftHighlight = false;
boolean rightHighlight = false;
boolean buttonPressed = false;
boolean flickerLoad = false;
int warningStart = 100000;
SoundFile ticker, endBeep, endBeep2, wrongNoise;
float tickerRate = 2.0;
String tickerFile = "tick2.0.wav";
float amp = 0;
float questionStart;
float timeToAnswer;
float totalTime;
boolean endStart = false;
float endTime;
void setup() {
// draws the basic interface
size(1400,900);
f = createFont("KohinoorDevanagari-Bold", 40);
qFont = createFont("KohinoorDevanagari-Regular", 54);
andFont = createFont("KohinoorDevanagari-Bold", 90);
startFont = createFont("KohinoorDevanagari-Regular", 30);
// all "inventories" are string lists containing the questions and/or answers. Change as you wish.
qInventory = new StringList("The lights are...", "It is...", "I am...", "I am...","The sky is...", "I am a student", "I am in a ___ mood", "I am...", "I am only good at...", "I am a...", "I ___ therefore I am", "I am good at making decisions", "I am...", "Carngie Mellon is...", "I am a...", "I am...", "I am...", "I am...", "I am...", "I am...");
firstAInventory = new StringList("on", "cold", "inside", "left-handed", "up", "yes", "good", "being", "art", "good person","think", "yes", "strong", "ethical", "success", "lucky", "not fun", "spiritual", "natural", "on");
println(firstAInventory.size()); // helps to diagnose whether you have enough answers for your questions
secondAInventory = new StringList("off", "hot", "outside", "right-handed", "down", "no", "bad", "becoming", "science", "bad person", "feel", "no", "weak", "unethical", "failure", "hard-working", "fun", "rational", "unnatural", "off");
ticker = new SoundFile(this, tickerFile);
ticker.loop(1,amp); // initializes the "ticking" noise
println(qInventory.size());
println(secondAInventory.size());
// button input
String portName = Serial.list()[4];
myPort = new Serial(this, portName, 9600);
}
void draw() {
background(255);
fill(0);
textAlign(CENTER);
if ( myPort.available() > 0) { // If data is available,
buttonVal = myPort.read(); // read it and store it in val
}
if (buttonPressed == false){ // tests whether or not the button has been pressed
background(255);
amp = 0; // if not ticker is silent
if (buttonVal == 4 || buttonVal == 2){ //gets the interface out of "start" mode
buttonPressed = true;
println("button pressed now true");
amp = 0.05; // ticker is now able to be heard
}
else if (second()%2 == 0){ // sets up the "start mode", uses modulus to "blink" the text
fill(0);
textFont(startFont);
text("How well can you binary?", width/2, height*0.333);
// every 2 seconds flip the bool in order to create "flicker" effect
if (flickerLoad == false){
//println("flipped to true");
delay(10);
flickerLoad = true;
delay(10);
}
else if(flickerLoad==true){
flickerLoad = false;
}
}
else if(flickerLoad == true){
fill(0);
textFont(qFont);
text("PRESS ANY BUTTON TO START", width/2, height/2);
}
}
else if (buttonVal == 3) { // if the arduino sends out a 3,triggers the "AND" state
println("and triggered");
fill(255);
warningStart = millis();
if (millis() - warningStart < 1200){ //only displays for 1.2 seconds
andTrigger = true;
//play dramatic tone here
}
else {
andTrigger = false; // automatically ends after 1.2 seconds
}
}
else if ((buttonVal == 4 || buttonVal== 2)&& buttonVal!=3 && endStart == false) {
//moves onto next question + triggers end state if we are at the end of the list of questions
delay(100);
qCount +=1; // the q count counts the number of questions answered
andTrigger = false;
println("tickerRate", tickerRate);
if (qCount < qInventory.size()) {
tickerRateIncrease(buttonVal); //increases the speed of the ticker everytime question is answered
}
else { // triggers the "end game" function once at end of the questions
endTime = millis();
ticker.stop();
endBeep = new SoundFile(this, "endbeep.mp3");
endBeep2 = new SoundFile(this, "endbeep_extra.wav");
endBeep.playFor(2.0);
endStart = true;
println("endStart set to true");
}
}
else if (qCount < qInventory.size()) { //displays the different questions so long as there are questions left
background(255);
textFont(qFont);
text(qInventory.get(qCount), width* 0.5, height*0.333);
textFont(f);
//set up highlights when button pressed
if (leftHighlight==true && millis()- questionStart < 300 && andTrigger==false){
println("left Highlight", leftHighlight);
rectMode(CENTER);
fill(0);
rect(width*0.333, height*0.666, 200, 80);
fill(255);
text(firstAInventory.get(qCount), width*0.333, height*0.666);//retrieves the correstpodning answer from the list
println(qCount);
}
else if (rightHighlight==true && millis()- questionStart < 300 && andTrigger==false){
println("right highlight", rightHighlight);
rectMode(CENTER);
fill(0);
rect(width*0.666, height*0.666, 200, 80);
fill(255);
text(secondAInventory.get(qCount), width*0.666, height*0.666);//retrieves the correstpodning answer from the list
println(qCount);
}
else{
// "normal" question display
fill(0);
text(secondAInventory.get(qCount), width*0.666, height*0.666);
text(firstAInventory.get(qCount), width*0.333, height*0.666);
//if neither is picked don't highlight it
rightHighlight = false;
leftHighlight = false;
}
}
// this function sets up the "AND" state
if (millis() - warningStart < 1200 && andTrigger==true){
wrongNoise = new SoundFile(this, "wrong.wav");
wrongNoise.play();
delay(90);
fill(255,0,0);
background(255);
textFont(andFont);
text("AND is not an option", width/2, height/2);
}
// this sequence is the end state
if (endStart == true){
println("end state");
ticker.stop();
if (endStart==true && millis()-endTime < 2500){
println("end game displayed");
textFont(andFont);
text("END GAME", width/2, height/2);
println("endTime", endTime);
println("endStart", endStart);
println("millis-endTime", millis()-endTime);
println("millis", millis());
}
if (millis()-endTime < 8000 && millis()-endTime >= 2500){
println("calculating score displayed");
textFont(qFont);
text("Calculating results...", width/2, height/2);
}
if (endStart==true && millis()-endTime < 10000 && millis()-endTime >= 8000){
println("you are...");
textFont(qFont);
text("You are...", width/2, height/2);
}
if (endStart==true && millis()-endTime < 12000 && millis()-endTime >= 10000 && totalTime <= 30000){
textFont(andFont);
background(0,255,0);
fill(255);
text("GOOD", width/2, height/2);
}
if (endStart==true && millis()-endTime < 12000 && millis()-endTime >= 10000 && totalTime > 30000){
textFont(andFont);
background(255,0,0);
text("BAD", width/2, height/2);
}
if(endStart == true && millis()-endTime >= 14000){
println("went to no loop");
println(endTime);
text("", width/2, height/2);
fill(0);
noLoop();
}
}
}
void tickerRateIncrease(int buttonVal) { //this function controls the ticker rate
println("click");
if (buttonVal == 4){
leftHighlight = true;
}
if (buttonVal== 2){
rightHighlight = true;
}
//increase rate + loudness
tickerRate -= 0.1;
amp += 0.05;
// endstate calculations
timeToAnswer = millis() - questionStart;
totalTime += timeToAnswer;
questionStart = millis();
//changing rates
String rateString = nf(tickerRate, 1, 1);
println("new ticker rate", tickerRate);
String[] tickerParts = new String[3];
tickerParts[0] = "tick";
tickerParts[1] = rateString;
tickerParts[2] = ".wav";
String tickerFile = join(tickerParts, ""); //sets up new ticker file name to be retrieved
ticker.stop();
ticker = new SoundFile(this, tickerFile);
ticker.cue(0.3);
ticker.loop(1,amp);//plays new, faster, ticker file
}