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
- <span class="com">/* 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)
- *
- */</span><span class="pln">
- </span><span class="com">// Initialize and Assign Global Variables</span><span class="pln">
- </span><span class="kwd">const</span><span class="pln"> </span><span class="kwd">int</span><span class="pln"> BUZZER_PIN </span><span class="pun">=</span><span class="pln"> </span><span class="lit">4</span><span class="pun">;</span><span class="pln"> </span><span class="com">// sound pin </span><span class="pln">
- </span><span class="kwd">const</span><span class="pln"> </span><span class="kwd">int</span><span class="pln"> SWITCH_PIN </span><span class="pun">=</span><span class="pln"> </span><span class="lit">3</span><span class="pun">;</span><span class="pln"> </span><span class="com">// switch pin</span><span class="pln">
- </span><span class="kwd">const</span><span class="pln"> </span><span class="kwd">int</span><span class="pln"> SOUND_PIN </span><span class="pun">=</span><span class="pln"> A0</span><span class="pun">;</span><span class="pln"> </span><span class="com">// sound detector pin</span><span class="pln">
- </span><span class="kwd">const</span><span class="pln"> </span><span class="kwd">int</span><span class="pln"> LED_PIN </span><span class="pun">=</span><span class="pln"> </span><span class="lit">5</span><span class="pun">;</span><span class="pln"> </span><span class="com">// LED pin</span><span class="pln">
- </span><span class="kwd">const</span><span class="pln"> </span><span class="kwd">int</span><span class="pln"> IR_PIN </span><span class="pun">=</span><span class="pln"> A1</span><span class="pun">;</span><span class="pln"> </span><span class="com">// IR sensor pin</span><span class="pln">
- </span><span class="com">// initialize flags</span><span class="pln">
- </span><span class="kwd">bool</span><span class="pln"> DID_PRINT </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">false</span><span class="pun">;</span><span class="pln"> </span><span class="com">// Has current game time elapsed been printed</span><span class="pln">
- </span><span class="kwd">bool</span><span class="pln"> IS_END_GAME </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">false</span><span class="pun">;</span><span class="pln"> </span><span class="com">// Dictate game state</span><span class="pln">
- </span><span class="kwd">int</span><span class="pln"> OLD_SWITCH_STATE</span><span class="pun">;</span><span class="pln"> </span><span class="com">// initialize switch state variable</span><span class="pln">
- </span><span class="kwd">unsigned</span><span class="pln"> </span><span class="kwd">long</span><span class="pln"> time</span><span class="pun">;</span><span class="pln"> </span><span class="com">// initialize time variable</span><span class="pln">
- </span><span class="kwd">void</span><span class="pln"> setup</span><span class="pun">(){</span><span class="pln">
- </span><span class="com">// Set up arduino inputs & outputs</span><span class="pln">
- pinMode</span><span class="pun">(</span><span class="pln">BUZZER_PIN</span><span class="pun">,</span><span class="pln"> OUTPUT</span><span class="pun">);</span><span class="pln">
- pinMode</span><span class="pun">(</span><span class="pln">SWITCH_PIN</span><span class="pun">,</span><span class="pln"> INPUT</span><span class="pun">);</span><span class="pln">
- pinMode</span><span class="pun">(</span><span class="pln">SOUND_PIN</span><span class="pun">,</span><span class="pln"> INPUT</span><span class="pun">);</span><span class="pln">
- pinMode</span><span class="pun">(</span><span class="pln">IR_PIN</span><span class="pun">,</span><span class="pln"> INPUT</span><span class="pun">);</span><span class="pln">
- </span><span class="com">// read initial state of switch</span><span class="pln">
- OLD_SWITCH_STATE </span><span class="pun">=</span><span class="pln"> digitalRead</span><span class="pun">(</span><span class="pln">SWITCH_PIN</span><span class="pun">);</span><span class="pln">
- </span><span class="com">// set serial port</span><span class="pln">
- </span><span class="typ">Serial</span><span class="pun">.</span><span class="kwd">begin</span><span class="pun">(</span><span class="lit">9600</span><span class="pun">);</span><span class="pln">
- </span><span class="pun">}</span><span class="pln">
- </span><span class="kwd">void</span><span class="pln"> loop</span><span class="pun">(){</span><span class="pln">
- </span><span class="com">// initialize function variables</span><span class="pln">
- </span><span class="kwd">int</span><span class="pln"> start_time</span><span class="pun">;</span><span class="pln"> </span><span class="com">// game start timestamp</span><span class="pln">
- </span><span class="kwd">int</span><span class="pln"> end_time</span><span class="pun">;</span><span class="pln"> </span><span class="com">// game end timestamp</span><span class="pln">
- </span><span class="kwd">int</span><span class="pln"> ir_threshold </span><span class="pun">=</span><span class="pln"> </span><span class="lit">180</span><span class="pun">;</span><span class="pln"> </span><span class="com">// Used to detect when IR sensor is tripped</span><span class="pln">
- </span><span class="kwd">int</span><span class="pln"> sound_threshold </span><span class="pun">=</span><span class="pln"> </span><span class="lit">40</span><span class="pun">;</span><span class="pln"> </span><span class="com">// Used to detect absence of sound</span><span class="pln">
- </span><span class="kwd">int</span><span class="pln"> current_switch_state </span><span class="pun">=</span><span class="pln"> digitalRead</span><span class="pun">(</span><span class="pln">SWITCH_PIN</span><span class="pun">);</span><span class="pln">
- </span><span class="com">// switch state is different from past switch state</span><span class="pln">
- </span><span class="com">// trigger game start</span><span class="pln">
- </span><span class="kwd">if</span><span class="pln"> </span><span class="pun">(</span><span class="pln">current_switch_state </span><span class="pun">!=</span><span class="pln"> OLD_SWITCH_STATE</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
- </span><span class="com">// assign active game flags</span><span class="pln">
- IS_END_GAME </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">false</span><span class="pun">;</span><span class="pln">
- DID_PRINT </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">false</span><span class="pun">;</span><span class="pln">
- </span><span class="com">// start sound</span><span class="pln">
- tone</span><span class="pun">(</span><span class="pln">BUZZER_PIN</span><span class="pun">,</span><span class="pln"> </span><span class="lit">1000</span><span class="pun">);</span><span class="pln">
- </span><span class="com">// begin stopwatch (record current timestamp)</span><span class="pln">
- start_time </span><span class="pun">=</span><span class="pln"> millis</span><span class="pun">();</span><span class="pln">
- </span><span class="pun">}</span><span class="pln">
- </span><span class="com">// game is active</span><span class="pln">
- </span><span class="kwd">if</span><span class="pln"> </span><span class="pun">(</span><span class="pln">IS_END_GAME </span><span class="pun">==</span><span class="pln"> </span><span class="kwd">false</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
- </span><span class="com">// ball has landed in cup</span><span class="pln">
- </span><span class="kwd">if</span><span class="pln"> </span><span class="pun">(</span><span class="pln">analogRead</span><span class="pun">(</span><span class="pln">IR_PIN</span><span class="pun">)</span><span class="pln"> </span><span class="pun">></span><span class="pln"> ir_threshold</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
- </span><span class="com">// terminate game</span><span class="pln">
- IS_END_GAME </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">true</span><span class="pun">;</span><span class="pln">
- </span><span class="com">// IR sensor --> sound transducer</span><span class="pln">
- noTone</span><span class="pun">(</span><span class="pln">BUZZER_PIN</span><span class="pun">);</span><span class="pln">
- </span><span class="pun">}</span><span class="pln">
- </span><span class="pun">}</span><span class="pln">
- </span><span class="kwd">else</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> </span><span class="com">// game has ended</span><span class="pln">
- </span><span class="com">// Time taken to complete game has not been printed on screen</span><span class="pln">
- </span><span class="kwd">if</span><span class="pln"> </span><span class="pun">(</span><span class="pln">DID_PRINT </span><span class="pun">==</span><span class="pln"> </span><span class="kwd">false</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
- </span><span class="com">// stop stopwatch (record game end timestamp)</span><span class="pln">
- end_time </span><span class="pun">=</span><span class="pln"> millis</span><span class="pun">();</span><span class="pln">
- </span><span class="com">// print time elapsed in seconds</span><span class="pln">
- </span><span class="typ">Serial</span><span class="pun">.</span><span class="kwd">print</span><span class="pun">(</span><span class="str">"Congratulations! It took you: "</span><span class="pun">);</span><span class="pln">
- </span><span class="kwd">int</span><span class="pln"> time_elapsed </span><span class="pun">=</span><span class="pln"> </span><span class="pun">(</span><span class="pln">end_time </span><span class="pun">-</span><span class="pln"> start_time</span><span class="pun">)</span><span class="pln"> </span><span class="pun">/</span><span class="pln"> </span><span class="lit">1000</span><span class="pun">;</span><span class="pln">
- </span><span class="typ">Serial</span><span class="pun">.</span><span class="kwd">print</span><span class="pun">(</span><span class="pln">time_elapsed</span><span class="pun">);</span><span class="pln">
- </span><span class="typ">Serial</span><span class="pun">.</span><span class="pln">println</span><span class="pun">(</span><span class="str">" seconds."</span><span class="pun">);</span><span class="pln">
- </span><span class="pun">}</span><span class="pln">
- </span><span class="com">// sound sensor --> sound detector. LEDs have not blinked yet</span><span class="pln">
- </span><span class="com">// DID_PRINT ensures LED's are only blinked once</span><span class="pln">
- </span><span class="kwd">if</span><span class="pln"> </span><span class="pun">((</span><span class="pln">analogRead</span><span class="pun">(</span><span class="pln">SOUND_PIN</span><span class="pun">)</span><span class="pln"> </span><span class="pun"><</span><span class="pln"> sound_threshold</span><span class="pun">)</span><span class="pln"> </span><span class="pun">&&</span><span class="pln"> </span><span class="pun">(</span><span class="pln">DID_PRINT </span><span class="pun">==</span><span class="pln"> </span><span class="kwd">false</span><span class="pun">))</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
- </span><span class="com">// sound detection --> light transducer</span><span class="pln">
- </span><span class="com">// begin light show</span><span class="pln">
- digitalWrite</span><span class="pun">(</span><span class="pln">LED_PIN</span><span class="pun">,</span><span class="pln"> HIGH</span><span class="pun">);</span><span class="pln">
- delay</span><span class="pun">(</span><span class="lit">500</span><span class="pun">);</span><span class="pln">
- digitalWrite</span><span class="pun">(</span><span class="pln">LED_PIN</span><span class="pun">,</span><span class="pln"> LOW</span><span class="pun">);</span><span class="pln">
- delay</span><span class="pun">(</span><span class="lit">200</span><span class="pun">);</span><span class="pln">
- digitalWrite</span><span class="pun">(</span><span class="pln">LED_PIN</span><span class="pun">,</span><span class="pln"> HIGH</span><span class="pun">);</span><span class="pln">
- delay</span><span class="pun">(</span><span class="lit">500</span><span class="pun">);</span><span class="pln">
- digitalWrite</span><span class="pun">(</span><span class="pln">LED_PIN</span><span class="pun">,</span><span class="pln"> LOW</span><span class="pun">);</span><span class="pln">
- delay</span><span class="pun">(</span><span class="lit">200</span><span class="pun">);</span><span class="pln">
- digitalWrite</span><span class="pun">(</span><span class="pln">LED_PIN</span><span class="pun">,</span><span class="pln"> HIGH</span><span class="pun">);</span><span class="pln">
- delay</span><span class="pun">(</span><span class="lit">500</span><span class="pun">);</span><span class="pln">
- digitalWrite</span><span class="pun">(</span><span class="pln">LED_PIN</span><span class="pun">,</span><span class="pln"> LOW</span><span class="pun">);</span><span class="pln">
- </span><span class="com">// LED flash and text print has been performed</span><span class="pln">
- </span><span class="com">// Set to so that it does not happen again (only once)</span><span class="pln">
- DID_PRINT </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">true</span><span class="pun">;</span><span class="pln">
- </span><span class="pun">}</span><span class="pln">
- </span><span class="pun">}</span><span class="pln">
- </span><span class="com">// update switch state for next step</span><span class="pln">
- OLD_SWITCH_STATE </span><span class="pun">=</span><span class="pln"> current_switch_state</span><span class="pun">;</span><span class="pln">
- </span><span class="pun">}</span>
Comments are closed.