Our easy to play game is designed to help improve anyone’s ball in cup throwing skills. To start a game, a participant flips a switch which simultaneously starts a high pitched sound and a stopwatch. They then pick up a ball or another object and attempts to throw it in a cup. As soon as the shot is made, the game ends, the sound stops, an LED blinks three times, and the amount of time elapsed from the start of the game is displayed on a computer screen.
Discussion
At the beginning of our project, we very quickly agreed that creating some sort of game which required human interaction to trigger our transducers would be interesting because it extended both the complexity and range over which we could design the product. Having further become very interested in incorporating IR, light, and sound into our project we set about merging our broader project interests with these components in what became the ball in cup game. The process was wrought with several challenging aspects, and yet other surprisingly simple features. Below we discuss highlights from each, broken down into two parts: hardware-wise, and code-wise.
In our initial brainstorming, integrating several components into two coupled transistors via circuits seemed like a daunting task: each transduction piece was unknown to us and required unique circuit logic to parse and reason over on the arduino. For instance, our sound detector consisted of five ports, including three for sound reading: ‘audio’, ‘envelop’, and ‘gate’. Each port captured a different element of a sound, while only a single one contained the information we needed. However, with help from online sources and material covered in lecture, we surprisingly found that wiring up each component was surprisingly straightforward.
Furthermore, we realized that to integrate each component to form our transducers, it was sufficient to set them all in parallel with one another. This observation greatly simplified our final circuit architecture, and proved to be easier to debug than a more complicated circuit.
In conjunction with putting together our hardware project components, we faced several challenges with designing our code structure. Because our goal was to design a game based off of a double transducer, we had to not only tie in each transduction component together to form the transducers and dependencies, but also had to seamlessly integrate other game parts to work in concert with the transducers. One challenging aspect of this was incorporating game state design into our project. Our vision was to have three game states: start, active, and terminal, each which was responsible for different aspects of the game. The role of the start state was to initialize all required components for the game, the active state served to perform all actions required while the game is ongoing, and the terminal state was meant to perform game ending functions. In terms of our code, the start state should initialize the stopwatch, and flags which dictate whether the game was active. The active state in turn should play the sound infinitely and detect if the IR sensor had been tripped, turning off the sound if true (first transducer). Meanwhile, the terminal state should be triggered by the absence of sound which causes the LED blinking series (second transducer) and terminates the game. This required a complete restructuring of our code because up until this point, both transducers were captured in a single if statement which detected whether the IR sensor had been detected. Thus, meeting our vision required breaking apart the transducers into the active and terminal game states, as well adding a new start state as well.
One aspect of our project we might have changed if we had more time was the type of sound emanating from an active game. Instead of playing a single monotone sound continuously, we think it would be interesting to instead change the sound based on elapsed time. This change would provide a unique form of participant feedback as it would give an indication of how long the game has been going on for.
Video of Ball in Cup Game in action:
Code
/* Ball In Cup Game * * This code integrates several components (an IR sensor, speaker, * sound detector, LED, switch, and display) into a double transducer * ball in cup game. Specifically, the double transducer is created in * our code according to the following; IR sensor --> sound (first * transducer), sound detector --> light (second transducer). The switch * and display are then used to start the game, and show a participant's * end game score respectively. * * Inputs: an IR sensor, switch, and sound detector * Outputs: a speaker, LED, and text display (via serial port) * */ // Initialize and Assign Global Variables const int BUZZER_PIN = 4; // sound pin const int SWITCH_PIN = 3; // switch pin const int SOUND_PIN = A0; // sound detector pin const int LED_PIN = 5; // LED pin const int IR_PIN = A1; // IR sensor pin // initialize flags bool DID_PRINT = false; // Has current game time elapsed been printed bool IS_END_GAME = false; // Dictate game state int OLD_SWITCH_STATE; // initialize switch state variable unsigned long time; // initialize time variable void setup(){ // Set up arduino inputs & outputs pinMode(BUZZER_PIN, OUTPUT); pinMode(SWITCH_PIN, INPUT); pinMode(SOUND_PIN, INPUT); pinMode(IR_PIN, INPUT); // read initial state of switch OLD_SWITCH_STATE = digitalRead(SWITCH_PIN); // set serial port Serial.begin(9600); } void loop(){ // initialize function variables int start_time; // game start timestamp int end_time; // game end timestamp int ir_threshold = 180; // Used to detect when IR sensor is tripped int sound_threshold = 40; // Used to detect absence of sound int current_switch_state = digitalRead(SWITCH_PIN); // switch state is different from past switch state // trigger game start if (current_switch_state != OLD_SWITCH_STATE) { // assign active game flags IS_END_GAME = false; DID_PRINT = false; // start sound tone(BUZZER_PIN, 1000); // begin stopwatch (record current timestamp) start_time = millis(); } // game is active if (IS_END_GAME == false) { // ball has landed in cup if (analogRead(IR_PIN) > ir_threshold) { // terminate game IS_END_GAME = true; // IR sensor --> sound transducer noTone(BUZZER_PIN); } } else { // game has ended // Time taken to complete game has not been printed on screen if (DID_PRINT == false) { // stop stopwatch (record game end timestamp) end_time = millis(); // print time elapsed in seconds Serial.print("Congratulations! It took you: "); int time_elapsed = (end_time - start_time) / 1000; Serial.print(time_elapsed); Serial.println(" seconds."); } // sound sensor --> sound detector. LEDs have not blinked yet // DID_PRINT ensures LED's are only blinked once if ((analogRead(SOUND_PIN) < sound_threshold) && (DID_PRINT == false)) { // sound detection --> light transducer // begin light show digitalWrite(LED_PIN, HIGH); delay(500); digitalWrite(LED_PIN, LOW); delay(200); digitalWrite(LED_PIN, HIGH); delay(500); digitalWrite(LED_PIN, LOW); delay(200); digitalWrite(LED_PIN, HIGH); delay(500); digitalWrite(LED_PIN, LOW); // LED flash and text print has been performed // Set to so that it does not happen again (only once) DID_PRINT = true; } } // update switch state for next step OLD_SWITCH_STATE = current_switch_state; }
Comments are closed.