Project Title: Butterfly Brain Training Game
by Rain Lee
Instructor: Professor Eric Parren
My inspiration for this project mainly comes from my love for psychology. I want to make something that is actually useful but original so I designed this game. It is designed to improve players’ left-right brain skills and reaction time. The butterfly shaped board has 10 LED lights and 10 buttons in it. Each LED light has a corresponding button. The correlation is programmed to be the reflection of over both the X and the Y axis. When an LED lights up, players are expected to press to button within 2 seconds. If you press the right button the speaker will make a higher pitch buzzer sound and if you press the wrong one it is going to give you a lower pitch sound. During user testing, there were opinions that the buzzer’s sound is too weak so I changed it to a Arduino speaker. Some also said the speed that was set at 1 second at the time was too fast so I changed it to 2 seconds. I chose a butterfly design because the shape is symmetric. I needed a shape that is symmetric both horizontally and vertically. After the changes I made after user testing, the sound was louder and clearer than before, and the speed was slower so it was easier for users to play the game.
I borrowed an Arduino mega from the equipment room first because the Uno doesn’t have enough inputs. I decided to use buttons because the game itself is already confusing. I’ve thought about using magnet sensors so make a fishing stick like game so the uses can also train their hand movement preciseness and patience but my professor said it doesn’t really make sense to have a butterfly shaped board, so I decided to ouse buttons instead to make it more straight forward because it is already a little confusing. I designed a butterfly with 20 holes on it on cuttle. I first laser cut one on a thinnest wooden board because there weren’t cardboard that was big enough. Then I laser cut holes with different slightly different diameters to see which fits the best with the LEDs and buttons with different thickness of boards and materials.In these process, I learned that with different material, the laser cut measurements are slightly different. Then decided on the best size, polished the lines on cuttle that turned out not perfect and laser cut 2 butterflies on 2mm semi transparent acrylic board, one with holes and the other without. I needed many male to female jumper cables and was told I could not borrow more than 100 of them so I bought more online.
For the coding I used both Arduino and Processing. I got a lot of help from fellows and learning assistants doing this project especially with coding. After I figured out the code for the first three inputs and outputs, I rewrote the code a few more times to make all the 20 inputs and outputs work. Processing was used for only the background of butterflies flying for the project to match the game. It is set to play faster when the mouse is at the left of the screen and faster when the mouse is at the right part of the screen. Using the mouse on the screen seemed as the most simple way to adjust the speed of the video.
One thing I wanted to do but wasn’t able to achieve in this project is to connect the speed of the game with the background video. So when the player puts the mouse on the left part of the screen the game runs slower and when they put it on the right the game speeds up accordingly. Another point made by many people was to track the points so people can compare if they’re improving. I actually have the Arduino counting the numbers of right presses by telling it to count whenever the speaker makes a higher sound indicating the button pressed is the right one. If I had a few hours I would have sent that information to processing to make it show. However, I didn’t have more time so I wasn’t able to get my processing to receive data from Arduino and show the score. At first the processing code I made was to show different cartoon butterflies when the buttons are pressed but I figured it is disturbing the players so I made a new code that is only a video that is played as a background. I think this project if had more time to be polished would be a meaningful game that is not only fun to play but also trains your left-right brain reaction skills.
APPENDIX
arduino code:
int one = 0;
int two = 0;
int three = 0;
int four = 0;
int five = 0;
int gone = 0;
int gtwo = 0;
int gthree = 0;
int gfour = 0;
int gfive = 0;
int oneIn = 51;
int oneOut = 48;
int twoIn = 52;
int twoOut = 47;
int threeIn = 53;
int threeOut = 46;
int fourIn = 50;
int fourOut = 45;
int fiveIn = 49;
int fiveOut = 44;
int goneIn = 43;
int goneOut = 38;
int gtwoIn = 42;
int gtwoOut = 37;
int gthreeIn = 41;
int gthreeOut = 36;
int gfourIn = 40;
int gfourOut = 35;
int gfiveIn = 39;
int gfiveOut = 34;
int piezoPin = 10;
int incorrectOut = 10;
int correctOut = 9;
int light = -1;
int counter;
void setup()
{
Serial.begin(9600);
pinMode(oneOut, OUTPUT);
pinMode(twoOut, OUTPUT);
pinMode(threeOut, OUTPUT);
pinMode(fourOut,OUTPUT);
pinMode(fiveOut,OUTPUT);
pinMode(goneOut, OUTPUT);
pinMode(gtwoOut, OUTPUT);
pinMode(gthreeOut, OUTPUT);
pinMode(gfourOut,OUTPUT);
pinMode(gfiveOut,OUTPUT);
pinMode(oneIn, INPUT);
pinMode(twoIn, INPUT);
pinMode(threeIn, INPUT);
pinMode(fourIn,INPUT);
pinMode(fiveIn, INPUT);
pinMode(goneIn, INPUT);
pinMode(gtwoIn, INPUT);
pinMode(gthreeIn, INPUT);
pinMode(gfourIn,INPUT);
pinMode(gfiveIn, INPUT);
}
// During the pause all thre lights are hidden, pressing any button would trigger a low pitch noise
void pause() {
unsigned long current;
unsigned long end;
light = -1;
digitalWrite(oneOut, LOW);
digitalWrite(twoOut, LOW);
digitalWrite(threeOut, LOW);
digitalWrite(fourOut, LOW);
digitalWrite(fiveOut, LOW);
digitalWrite(goneOut, LOW);
digitalWrite(gtwoOut, LOW);
digitalWrite(gthreeOut, LOW);
digitalWrite(gfourOut, LOW);
digitalWrite(gfiveOut, LOW);
int pause = rand() % 500 + 100;
current = millis();
end = millis() + pause;
while (millis()<end) {
one = digitalRead(oneIn);
two = digitalRead(twoIn);
three = digitalRead(threeIn);
four = digitalRead(fourIn);
five = digitalRead(fiveIn);
gone = digitalRead(goneIn);
gtwo = digitalRead(gtwoIn);
gthree = digitalRead(gthreeIn);
gfour = digitalRead(gfourIn);
gfive = digitalRead(gfiveIn);
if (one == HIGH || two == HIGH || three == HIGH || four == HIGH || five == HIGH || gone == HIGH || gtwo == HIGH || gthree == HIGH || gfour == HIGH || gfive == HIGH) {
tone(piezoPin, 100, 300); //Pin,Frequency,Duration
delay(20);
}
}
}
// Randomly decide which LED to turn on
void displaylight() {
light = rand() % 10 + 1;
if (light==1) {
digitalWrite(oneOut, HIGH);
} else if (light==2) {
digitalWrite(twoOut, HIGH);
} else if (light==3) {
digitalWrite(threeOut, HIGH);
} else if (light==4) {
digitalWrite(fourOut, HIGH);
} else if (light==5) {
digitalWrite(fiveOut, HIGH);
} else if (light==6) {
digitalWrite(goneOut, HIGH);
} else if (light==7) {
digitalWrite(gtwoOut, HIGH);
} else if (light==8) {
digitalWrite(gthreeOut, HIGH);
} else if (light==9) {
digitalWrite(gfourOut, HIGH);
} else if (light==10) {
digitalWrite(gfiveOut, HIGH);
}
}
// If the user presses a button corresponding to the right LED (hit a light) > High pitch noise
// If the user presses the wrong button > Low pitch noise
void hitlight() {
unsigned long current;
unsigned long end;
current = millis();
end = millis() + 2000;
while (millis()<end) {
one = digitalRead(oneIn); // read input value
if (one == HIGH) { // check if the input is pressed
if (light==1) {
// High pitch tone +++
tone(piezoPin, 1000, 10); //Pin,Frequency,Duration
counter ++;
Serial.println(counter);
delay(10);
} else {
// Low pitch tone —
tone(piezoPin, 100, 300); //Pin,Frequency,Duration
delay(30);
}
}
two = digitalRead(twoIn); // read input value
if (two == HIGH) { // check if the input is pressed
if (light==2) {
// High pitch tone +++
tone(piezoPin, 1000, 10); //Pin,Frequency,Duration
counter ++;
Serial.println(counter);
delay(10);
} else {
// Low pitch tone —
tone(piezoPin, 100, 300); //Pin,Frequency,Duration
delay(30);
}
}
three = digitalRead(threeIn); // read input value
if (three == HIGH) { // check if the input is pressed
if (light==3) {
// High pitch tone +++
tone(piezoPin, 1000, 10); //Pin,Frequency,Duration
counter ++;
Serial.println(counter);
delay(10);
} else {
// Low pitch tone —
tone(piezoPin, 100, 300); //Pin,Frequency,Duration
delay(30);
}
}
four = digitalRead(fourIn); // read input value
if (four == HIGH) { // check if the input is pressed
if (light==4) {
// High pitch tone +++
tone(piezoPin, 1000, 10); //Pin,Frequency,Duration
counter ++;
Serial.println(counter);
delay(10);
} else {
// Low pitch tone —
tone(piezoPin, 100, 300); //Pin,Frequency,Duration
delay(30);
}
}
five = digitalRead(fiveIn); // read input value
if (five == HIGH) { // check if the input is pressed
if (light==5) {
// High pitch tone +++
tone(piezoPin, 1000, 10); //Pin,Frequency,Duration
counter ++;
Serial.println(counter);
delay(10);
} else {
// Low pitch tone —
tone(piezoPin, 100, 300); //Pin,Frequency,Duration
delay(30);}
}
gone = digitalRead(goneIn); // read input value
if (gone == HIGH) { // check if the input is pressed
if (light==6) {
// High pitch tone +++
tone(piezoPin, 1000, 10); //Pin,Frequency,Duration
counter ++;
Serial.println(counter);
delay(10);
} else {
// Low pitch tone —
tone(piezoPin, 100, 300); //Pin,Frequency,Duration
delay(30);
}
}
gtwo = digitalRead(gtwoIn); // read input value
if (gtwo == HIGH) { // check if the input is pressed
if (light==7) {
// High pitch tone +++
tone(piezoPin, 1000, 10); //Pin,Frequency,Duration
counter ++;
Serial.println(counter);
delay(10);
} else {
// Low pitch tone —
tone(piezoPin, 100, 300); //Pin,Frequency,Duration
delay(30);
}
}
gthree = digitalRead(gthreeIn); // read input value
if (gthree == HIGH) { // check if the input is pressed
if (light==8) {
// High pitch tone +++
tone(piezoPin, 1000, 10); //Pin,Frequency,Duration
counter ++;
Serial.println(counter);
delay(10);
} else {
// Low pitch tone —
tone(piezoPin, 100, 300); //Pin,Frequency,Duration
delay(30);
}
}
gfour = digitalRead(gfourIn); // read input value
if (gfour == HIGH) { // check if the input is pressed
if (light==9) {
// High pitch tone +++
tone(piezoPin, 1000, 10); //Pin,Frequency,Duration
counter ++;
Serial.println(counter);
delay(10);
} else {
// Low pitch tone —
tone(piezoPin, 100, 300); //Pin,Frequency,Duration
delay(30);
}
}
gfive = digitalRead(gfiveIn); // read input value
if (gfive == HIGH) { // check if the input is pressed
if (light==10) {
// High pitch tone +++
tone(piezoPin, 1000, 10); //Pin,Frequency,Duration
counter ++;
Serial.println(counter);
delay(10);
} else {
// Low pitch tone —
tone(piezoPin, 100, 300); //Pin,Frequency,Duration
delay(30);}
}
}
}
void loop() {
pause();
displaylight();
hitlight();
int toP1 = digitalRead(51);
int toP2 = digitalRead(52);
int toP3 = digitalRead(53);
int toP4 = digitalRead(50);
int toP5 = digitalRead(49);
int gtoP1 = digitalRead(43);
int gtoP2 = digitalRead(42);
int gtoP3 = digitalRead(41);
int gtoP4 = digitalRead(40);
int gtoP5 = digitalRead(39);
Serial.print(toP1);
Serial.print(“,”);
Serial.print(toP2);
Serial.print(“,”);
Serial.print(toP3);
Serial.print(“,”);
Serial.print(toP4);
Serial.print(“,”);
Serial.print(toP5);
Serial.print(“,”);
Serial.print(gtoP1);
Serial.print(“,”);
Serial.print(gtoP2);
Serial.print(“,”);
Serial.print(gtoP3);
Serial.print(“,”);
Serial.print(gtoP4);
Serial.print(“,”);
Serial.print(gtoP5);
Serial.println();
delay(20);
}
processing code:
import processing.serial.*;
Serial serialPort;
int NUM_OF_VALUES_FROM_ARDUINO = 5; /* CHANGE THIS ACCORDING TO YOUR PROJECT */
/* This array stores values from Arduino */
int arduino_values[] = new int[NUM_OF_VALUES_FROM_ARDUINO];
void setup() {
size(500, 500);
background(0);
printArray(Serial.list());
// put the name of the serial port your Arduino is connected
// to in the line below – this should be the same as you’re
// using in the “Port” menu in the Arduino IDE
serialPort = new Serial(this, “/dev/cu.usbmodem14101”, 9600);
}
void draw() {
background(255);
stroke(255);
fill(0);
// receive the values from Arduino
getSerialData();
if (arduino_values[0] == 1) {
circle(100,100,100);
}
if (arduino_values[1] == 1) {
circle(100,200,100);
}
if (arduino_values[2] == 1) {
circle(200,100,100);
}
if (arduino_values[3] == 1) {
circle(100,400,100);
}
if (arduino_values[4] == 1) {
circle(400,100,100);
}
// use the values like this:
//float x = map(arduino_values[0], 0, 1023, 0, width);
//float y = map(arduino_values[1], 0, 1023, 0, height);
//rectMode(CENTER);
//rect(width/2, height/2, 50,50);
}
// the helper function below receives the values from Arduino
// in the “arduino_values” array from a connected Arduino
// running the “serial_AtoP_arduino” sketch
// (You won’t need to change this code.)
void getSerialData() {
while (serialPort.available() > 0) {
String in = serialPort.readStringUntil( 10 ); // 10 = ‘\n’ Linefeed in ASCII
if (in != null) {
print(“From Arduino: ” + in);
String[] serialInArray = split(trim(in), “,”);
if (serialInArray.length == NUM_OF_VALUES_FROM_ARDUINO) {
for (int i=0; i<serialInArray.length; i++) {
arduino_values[i] = int(serialInArray[i]);
}
}
}
}
}