“Cooperation is the key” – Callie – Margaret Minsky
CONTEXT AND SIGNIFICANCE
My previous research is about connecting two persons’ dreams, which involves some cooperation. I think it inspires me to let two persons interact with my midterm project at the same time. This idea is very appealing to both my partner, Fan, and me. By analyzing my previous group project, I find that interaction can be more than simply people-and-artifacts communication, but a connection between humans. It is the connecting two human brains’ part that specifically triggered my understanding of interaction, giving me the hint of allowing more than two sides to involve in the process of interaction, during which every side is connected to others, giving out and receiving information. The cooperation design makes our project unique from others. With this project, people can entertain themselves as well as learn to cooperate with others, which makes it of some special value.
CONCEPTION AND DESIGN
At first Fan and I thought it would be easy for the user to acknowledge which part was interactive in our project. So when we presented our prototype, we just left the maze we made without any instruction sign. Now I have the understanding that users may not have such patience to get to know the overall project before they take any action. Now there are some stickers as the guide sign. Another decision is that we decide to use a hole with some metal tape to be our switch. Therefore users can turn the switch on by just rolling the metal ball into the hole. The gravity will do the rest of the things for them. The circuit will be connected as the ball touches the tape on both sides. We think metal tape is thin and electroconductive so it is suitable in such a case. Another option is that we can use a push-button. But this will make it very hard for users to roll the ball onto it. Moreover, the ball won’t be heavy enough to push the button.
FABRICATION AND PRODUCTION
I’m mainly in charge of the code, modeling in the poster and one of the boxes.
IDEA FORMING
My partner and I came up with this idea together. At first, we decided to make a box that has different buttons on each side and make it like a game. But later, inspired by Fireboy and Watergirl, we agreed that we should make a game that involves two players cooperating, rather than competing with each other.
SOLO PROTOTYPE
Then we make the prototype boxes separately in the autumn holiday. The code was a simple one only with the basic function of the switch. I built the box and the circuit separately to test if it can work in this way or not.
Pic.1.1 My prototype made of cardboard
Video.1.1 The box & the circuit
The code at that time:
#include <Servo.h> Servo myservo; int val; int button = 10; int buttonState = LOW; int servoPin = 9; void setup() { myservo.attach(9); Serial.begin(9600); pinMode(button, INPUT); pinMode(servoPin, OUTPUT); } void loop() { buttonState = digitalRead(button); if(buttonState == HIGH){ val = 90; myservo.write(val); } if(buttonState == LOW){ val = 0; myservo.write(val); } }
Pic.1.2 The circuit (ver.1)
REAL PROTOTYPE
When we came back to school, we put two boxes together to find out if it could work. It turned out to be great, so we started to make a prototype of our switch.
Pic.2.1 The switch
Video.2.1 How it works
The code & circuit (ver.2):
#include <Servo.h> Servo myservo1; Servo myservo2; int val1; int val2; int button1 = 11; int button2 = 12; int button3 = 13; int buttonState1 = LOW; int buttonState2 = LOW; int buttonState3 = LOW; int servoPin1 = 10; int servoPin2 = 9; void setup() { myservo1.attach(10); myservo2.attach(9); Serial.begin(9600); pinMode(button1, INPUT); pinMode(button2, INPUT); pinMode(button3, INPUT); pinMode(servoPin1, OUTPUT); pinMode(servoPin2, OUTPUT); } void loop() { buttonState1 = digitalRead(button1); buttonState2 = digitalRead(button2); buttonState3 = digitalRead(button3); if(buttonState1 == HIGH){ val1 = 90; myservo1.write(val1); } if(buttonState1 == LOW){ val1 = 0; myservo1.write(val1); } if(buttonState2 == HIGH){ val2 = 90; myservo2.write(val2); } if(buttonState2 == LOW){ val2 = 0; myservo2.write(val2); } if(buttonState3 == LOW){ } if(buttonState3 == HIGH){ Serial.print(" You win! "); delay(5000); Serial.print(" YEAHHHHH!You win! "); delay(5000); Serial.print(" You've already won! You can go now. "); delay(5000); } }
Pic.2.2 The circuit (ver.2)
For the hardware part, we tried to solder wires onto the metal tapes.
Video.2.2&2.3 The soldered boxes and how they worked
Pic.2.3 Sketch of the whole game process
The biggest problem we found in this part is that the switch sometimes was a poor contact. This is pointed out in Class 11. Professor Minsky suggested we use the transformation rather than the state to control the switch. So I tried to use this:
if(oldButtonState1 == LOW){ if(buttonState1 == HIGH){ val1 = 90; myservo1.write(val1); delay(1000); }
However, it made the code much complex. So I used the remainder to determine the switch should be on or not.
The code (ver.3) is here:
#include <Servo.h> Servo myservo1; Servo myservo2; int val1; int val2; int button1 = 11; int button2 = 12; int button3 = 13; int oldButtonState1 = LOW; int oldButtonState2 = LOW; int buttonState3 = LOW; int buttonCount1 = 0; int buttonCount2 = 0; int servoPin1 = 10; int servoPin2 = 9; void setup() { myservo1.attach(10); myservo2.attach(9); Serial.begin(9600); pinMode(button1, INPUT); pinMode(button2, INPUT); pinMode(button3, INPUT); pinMode(servoPin1, OUTPUT); pinMode(servoPin2, OUTPUT); } void loop() { int buttonState1 = digitalRead(button1); int buttonState2 = digitalRead(button2); int buttonState3 = digitalRead(button3); if(oldButtonState1 == LOW){ if(buttonState1 == HIGH){ buttonCount1++; } } if(oldButtonState1 == HIGH){ if(buttonState1 == LOW){ buttonCount1++; } } if(oldButtonState2 == LOW){ if(buttonState2 == HIGH){ buttonCount2++; } } if(oldButtonState2 == HIGH){ if(buttonState2 == LOW){ buttonCount2++; } } if(buttonState3 == LOW){ } if(buttonState3 == HIGH){ Serial.print(" You win! "); delay(5000); Serial.print(" YEAHHHHH!You win! "); delay(5000); Serial.print(" You've already won! You can go now. "); delay(5000); } if(buttonCount1 % 2 == 1){ val1 = 90; myservo1.write(val1); delay(1000); } if(buttonCount1 % 2 == 0){ val1 = 0; myservo1.write(val1); } if(buttonCount2 % 2 == 1){ val2 = 90; myservo2.write(val2); delay(1000); } if(buttonCount2 % 2 == 0){ val2 = 0; myservo2.write(val2); } oldButtonState1 = buttonState1; oldButtonState2 = buttonState2; }
WOODEN BOXES
Meanwhile, we used laser cutting to make wood boxes. The two boxes were different from each other, so we spent a lot of time designing each of them.
Pic.3.1 The final look before user test
Pic.3.2 Mine
Pic.3.3 Fan with her box
I came up with the idea that the wires can be soldered to the back of the box so that there were only metal tapes in the face of the box. Thus the problem of having bulges was solved. It’s easier for the users to roll the ball to its position.
Pic.3.4 The back of the box (metal tapes were glued to box to reinforce)
MELODY
In the end, we got the idea of giving a clearer output. So I was asked to add a buzzer to our circuit.
Pic.4.1 The final circuit
#include <Servo.h> Servo myservo1; Servo myservo2; int val1; int val2; int button1 = 11; int button2 = 12; int button3 = 13; int oldButtonState1 = LOW; int oldButtonState2 = LOW; int buttonState3 = LOW; int buttonCount1 = 0; int buttonCount2 = 0; int servoPin1 = 10; int servoPin2 = 9; int melodyPin = 8; int count = 0; void setup() { myservo1.attach(10); myservo2.attach(9); Serial.begin(9600); pinMode(button1, INPUT); pinMode(button2, INPUT); pinMode(button3, INPUT); pinMode(servoPin1, OUTPUT); pinMode(servoPin2, OUTPUT); pinMode(melodyPin, OUTPUT); } void loop() { int buttonState1 = digitalRead(button1); int buttonState2 = digitalRead(button2); int buttonState3 = digitalRead(button3); if(oldButtonState1 == LOW){ if(buttonState1 == HIGH){ buttonCount1++; } } if(oldButtonState1 == HIGH){ if(buttonState1 == LOW){ buttonCount1++; } } if(oldButtonState2 == LOW){ if(buttonState2 == HIGH){ buttonCount2++; } } if(oldButtonState2 == HIGH){ if(buttonState2 == LOW){ buttonCount2++; } } if(buttonState3 == LOW){ Serial.println(count); count++; delay(1000); } if(buttonState3 == HIGH){ Serial.print(" You win! "); playMelody(); delay(3000); Serial.print(" You've already won! You can go now. "); playMelody(); delay(3000); count = 0; } if(buttonCount1 % 2 == 1){ val1 = 90; myservo1.write(val1); delay(1000); } if(buttonCount1 % 2 == 0){ val1 = 0; myservo1.write(val1); } if(buttonCount2 % 2 == 1){ val2 = 90; myservo2.write(val2); delay(1000); } if(buttonCount2 % 2 == 0){ val2 = 0; myservo2.write(val2); } oldButtonState1 = buttonState1; oldButtonState2 = buttonState2; } void playFreq(double freqHz, int durationMs) { //Calculate the period in microseconds int periodMicro = int((1 / freqHz) * 1000000); int halfPeriod = periodMicro / 2; //store start time long startTime = millis(); //(millis() - startTime) is elapsed play time while ((millis() - startTime) < durationMs) { digitalWrite(melodyPin, HIGH); delayMicroseconds(halfPeriod); digitalWrite(melodyPin, LOW); delayMicroseconds(halfPeriod); } } void playMelody() { playFreq(262, 100); playFreq(294, 100); playFreq(349, 100); playFreq(294, 100); playFreq(440, 200); delay(100); playFreq(440, 400); playFreq(392, 400); delay(300); playFreq(262, 100); playFreq(294, 100); playFreq(349, 100); playFreq(294, 100); playFreq(392, 200); delay(100); playFreq(392, 400); playFreq(349, 400); }
AFTER USER TEST
The user testing session reflected two problems, poor contact, and misunderstanding of the game mode. For the poor contact, we agree that next time we should use a sensor, that will make it more sensitive and reliable. We now have the understanding that users may not have such patience to get to know the overall project before they take any action. So we put some stickers as the guide sign. And there was a delay in the music, making the users confused about whether they succeeded or not. I changed the code so it can give out immediate responses to users.
Pic.5.1 During the user test
Pic.5.2&3 My model of our work
Pic.5.4 Our Poster
THE PRESENTATION
Pic.6.1 PRESENTATION!
CONCLUSIONS
Our work’s goal is to entertain users with a maze game that needs cooperation. My project results align with my definition of interaction mainly in the circuit aspect. the circuit reflects the process of interaction. It can gain information from users by the switch, deal with information by the code, and give out information by making the servo turns. However, when users roll the ball in the maze, it is not very interactive since the artifact can’t give the users any other response. The audience tended to interact with our work in a way that the instruction guided, which lived up to our expectations. If I have more time, I’ll make the process of solving the maze more interactive, such as adding some points for the users to get bonus scores. I learned from the failure that when you put your idea into reality, there are always some technical problems caused by physical limitations. So we should try to use more sensitive and high fault tolerance materials and methods. From the accomplishments, I learned that it may have wonderful outcomes to add new ideas to existing things or definitions.