Project
Tic Tac Toe is a plywood based project, a ‘gizmo’. An Arduino controlled mechatronic device, my project allows you to play a game of Tic Tac Toe against a computer, while watching the moves displayed live.
Concept
I have made a robot which will play Tic Tac Toe against you. To create an interactive experience, the machine talks to you through headphones, and you can talk back to tell it what move you would like to make through a microphone.
I am fascinated by the idea of mechanical computers - purposefully choosing not to use modern technology (i.e a touchscreen), to create a more magical and engaging user experience. Furthermore, by having clear acrylic sides, the user is able to see the machine in action as the blocks rotate to display the moves.
I have used 9 plywood blocks to display the current moves on the board. Each of these blocks is connected to a servo, and so can rotate between three faces - blank (no move), naught, and cross. As a result, it is a fun and interactive game that anyone can play!
Components
In order to create my device, I was required to use many different components so that I could implement the desired functionality to create a good user experience. For each of these components, I had to work out firstly which type and brand I wanted (i.e for the servo what strength servo was required), and then how to wire it to the Arduino and code it to perform as intended.
SG90 SERVO MATRIX
In order to control the 9 servos required for the game, I decided to create a matrix with ‘I’ and ‘j’ values in the code containing the pin numbers of each servo.
unsigned char
servo_pins[3][3] = {22, 24, 26,
28, 30, 32,
34, 36, 38,};
unsigned char servo_pins[3][3] = {22, 24, 26,
28, 30, 32,
34, 36, 38,};
I also needed a similar matrix for the board, to store the position of each servo. 0 for no move, 1 for user move and 2 for Arduino move. With these two matrices I could check the state of a tile with board[I][j], and set the position of a servo with servos[I][j].write(180).
As a result of using 9 servos, I had to use an external power supply just to power the servos. This meant that each servo had one pin going to ground, one to a digital input on the Arduino, and the other to the 5V 10A external power supply. I chose to use servos instead of motors as they retain their position when switched off and so are easier to use here.
KEYPAD MEMBRANE
As the voice recognition does not always work, especially with other people’s voices I have included a keypad. A keypad is a very intuitive interface so this allows users the freedom to enter a move either by speaking or by clicking on the keypad.
SD CARD READER
An SD card reader is required to read the SD card containing all the audio files. These are used for when the Arduino talks to the users. E.g. to say “your move”. I had to run a sequence of code in the setup to check for the inserted SD card to avoid bugs in the code.
TOGGLE SWITCH
To make the game elegant and portable, I have included two toggle switches and ports to plug in the two power adapters. This allows for easy transport and means the arduino will not be out of sync with the motors as you can turn both on together.
AUX JACK OUTPUT
I wanted to allow the user to have the freedom of using headphones or an external speaker when playing the game to hear instructions from the computer. This meant I used a headphone jack, and wired it to pins on the arduino.
VOICE RECOGNITION
I used this voice control module to allow the user to dictate which move they want to place. The module works by recording 3 sets up to 5 commands, then finding a best match when you speak into it. Therefore, the user has to first say what row, then what column they want to place a move in. One problem of having a module like this means that it only works well with my voice as I programmed it with my voice.
As a result of the processor of the Arduino being very poor, I was unable to implement machine learning or any ‘smart’ voice control as this would crash the Arduino while operating. Instead all of the computation is done within the module as it looks to see if the incoming audio matches any samples stored and tells the Arduino there is a match.
KEYPAD
As the voice recognition does not always work, especially with other people’s voices I have included a keypad. A keypad is a very intuitive interface so this allows users the freedom to enter a move either by speaking or by clicking on the keypad.
SD CARD READER
An SD card reader is required to read the SD card containing all the audio files. These are used for when the Arduino talks to the users. E.g. to say “your move”. I had to run a sequence of code in the setup to check for the inserted SD card to avoid bugs in the code.
TOGGLE SWITCH
To make the game elegant and portable, I have included two toggle switches and ports to plug in the two power adapters. This allows for easy transport and means the arduino will not be out of sync with the motors as you can turn both on together.
AUX JACK OUTPUT
I wanted to allow the user to have the freedom of using headphones or an external speaker when playing the game to hear instructions from the computer. This meant I used a headphone jack, and wired it to pins on the arduino.
VOICE RECOGNITION
I used this voice control module to allow the user to dictate which move they want to place. The module works by recording 3 sets up to 5 commands, then finding a best match when you speak into it. Therefore, the user has to first say what row, then what column they want to place a move in. One problem of having a module like this means that it only works well with my voice as I programmed it with my voice.
As a result of the processor of the Arduino being very poor, I was unable to implement machine learning or any ‘smart’ voice control as this would crash the Arduino while operating. Instead all of the computation is done within the module as it looks to see if the incoming audio matches any samples stored and tells the Arduino there is a match.
SG90 SERVO MATRIX
In order to control the 9 servos required for the game, I decided to create a matrix with ‘I’ and ‘j’ values in the code containing the pin numbers of each servo.
unsigned char servo_pins[3][3] = {22, 24, 26, 28, 30, 32, 34, 36, 38,};
I also needed a similar matrix for the board, to store the position of each servo. 0 for no move, 1 for user move and 2 for Arduino move. With these two matrices I could check the state of a tile with board[I][j], and set the position of a servo with servos[I][j].write(180).
As a result of using 9 servos, I had to use an external power supply just to power the servos. This meant that each servo had one pin going to ground, one to a digital input on the Arduino, and the other to the 5V 10A external power supply.
I chose to use servos instead of motors as they retain their position when switched off and so are easier to use here.
Development Process
To create the final product, there were many stages of development. Firstly I created CAD models of the entire system to see how everything would fit together and interact. Then I 3D printed some parts to test - for example here to see if the servo motor would fit into its housing. Finally once I was happy, I cut the parts on a laser cutter, then spray painted them to finish off.
Iteration
Throughout the design process, there were many parts that were iterated on, here is one example. Below are three attempts at designing a method of fixing the servo in place. The problems with the first design were that there were no screws, only friction fit. This meant the motor could quite easily move. The second design included screws and improved on the previous design by being able to be laser cut. However, this actually caused problems as the laser-cut parts were not straight when glued together and were too small and fiddly.
Finally, the last design used square nuts and M2 bolts to secure the servo to a 3D printed mount, which was then screwed into a laser-cut backplate. Three screws were also used to prevent any rotation.
Logic Flow Chart
To illustrate the flow of logic in the code written for the Arduino I have created this flow chart which explains every decision the algorithm makes when running the game, as the Arduino has very limited memory and so can only run basic logic like this.