The core concept of our project is a physical version of the classic Pong arcade game, where users bounce a ball back and forth with paddles while attempting to score goals by hitting the ball past the opposing player's paddle. Along with the regular two-player mode, we integrated computer vision into our project, providing the option of single player against a computer opponent, or a completely automated game.
To connect the AS5600 encoder to the B-G431B-ESC1 motor drivers, we need to make the following connection :
+--------------------+ +----------------------+
| B-G431B-ESC1 | | AS5600 |
| | | |
| Z (SCL) <--+-------+--> SCL |
| B (SDA) <--+-------+--> SDA |
| 5V <--+-------+--> VCC |
| GND <--+-------+--> GND |
+--------------------+ +----------------------+
The pins on the AS5600 are well labeled
To control the driver with an Arduino with Serial, we will need to use the RX/TX ports. We will also connect GND in order to have a shared ground and on one of the two drivers will be connect the 5V to the VIN of the Arduino in order to power the arduino. Schematic from
+--------------------+ +----------------------+
| B-G431B-ESC1 | | Arduino |
| motor 0 | | |
| | | |
| GND <--+-------+--> GND |
| 5V <--+-------+--> 5V |
| TX <--+-------+--> RX (Pin 8) |
| RX <--+-------+--> TX (Pin 9) |
+--------------------+ +----------------------+
+--------------------+ +----------------------+
| B-G431B-ESC1 | | Arduino |
| motor 1 | | |
| | | |
| GND <--+-------+--> GND |
| TX <--+-------+--> RX (Pin 10) |
| RX <--+-------+--> TX (Pin 11) |
+--------------------+ +----------------------+
Schematic from To power the drivers, we connect respectively the V- and the V+ to the ground and the 12V of our powersupply. In our system, we are using some XT-60 connectors, on this connectors the flat side is the ground and the other with a sort of triangle is the +. Additionnaly we connect the female side to the power source. To be able to connect a single power source to the two motor drivers, we make a Y cable.
To connect the motor to the driver, we solder 3 cables to the 3 big pads on the OUTPUT side.
To control the motors manually, we need to connect two potentiometers to the Arduino. Both potentiometers send output through the analog pins. We use the following connection (the potentiometer pins are labeled 1-3):
+------------------------+ +----------------------+
| Slide potentiometer 0 | | Arduino |
| | | |
| | | |
| 1 <--+-------+--> GND |
| 2 <--+-------+--> A0 |
| 3 <--+-------+--> 5V |
+------------------------+ +----------------------+
+------------------------+ +----------------------+
| Slide potentiometer 1 | | Arduino |
| | | |
| | | |
| 1 <--+-------+--> GND |
| 2 <--+-------+--> A1 |
| 3 <--+-------+--> 5V |
+------------------------+ +----------------------+
To allow the users to progress through the game flow, we need to connect two buttons (with corresponding LEDs) and an LCD screen. Both + and NC for the LED and button respectively utilize the digital pins. We use the following connections:
+---------------------+ +----------------------+
| Button 0 | | Arduino |
| (next/player 0) | | |
| | | |
| - (LED) <--+-------+--> GND |
| GND (BUTTON) <--+-------+--> GND |
| + (LED) <--+-------+--> 12 |
| NC (BUTTON) <--+-------+--> 6 |
+---------------------+ +----------------------+
+---------------------+ +----------------------+
| Button 1 | | Arduino |
| (enter/player 1) | | |
| | | |
| - (LED) <--+-------+--> GND |
| GND (BUTTON) <--+-------+--> GND |
| + (LED) <--+-------+--> 13 |
| NC (BUTTON) <--+-------+--> 7 |
+---------------------+ +----------------------+
For the screen, we first solder the I2C converter to the back of the LCD screen, making sure the labeled 16 pins on the converter align with the correspondingly labeled holes on the screen. Then, we use the following connections:
+---------------------+ +----------------------+
| I2C converter | | Arduino |
| | | |
| | | |
| GND <--+-------+--> GND |
| VCC <--+-------+--> 5V |
| SDA <--+-------+--> SDA |
| SCL <--+-------+--> SCL |
+---------------------+ +----------------------+
To make wiring easier, we chose to use a shield board.
First, laser cut and 3D print the necessary parts. To laser cut for the main box:
To 3D print for the main box:
To laser cut for each potentiometer:
To 3D print for each potentiometer:
First, assemble the game board shell using the laser cut walls as shown in the 3D model (exploded view in cad/README.md). Leave the outermost walls on the left and right side to attach after motor assembly.
To assemble the motor and belt system, first construct the motor reduction gear by cutting an appropriate length of belt and gluing it into the groove in the gear, effectively adding teeth to the gear. Screw this gear on to the motor, followed by the magnet case with the magnet in it (this should be glued in place)
Place the motor bearing and encoder in the 3D printed motor encoder holder as such:
Then place the motor encoder holder on top of the magnet with encoder facing up to give the completed motor assembly:
The motor can then be screwed into the base of the game board using the corresponding screw holes. Then, insert linear bearings into the appropriate clasps on each paddle mount print. Use screws (four per paddle mount) to tighten the linear rail clasps.
Screw the belt attachments onto the paddle mount and attach the belt to one end by first placing a nut into the hexagonal indent on the belt attachment
pinching the belt into the notch, and turning a screw down the center.
To insert the rails, first screw the rail-to-box mount into the side of the box with the corresponding screw holes. Push both rails through the rail/box mount attached to the box wall and clamp with screws.
Continue pushing the rails through the paddle mount with linear bearings and the corresponding rail holes on the opposite side of the game board. Loop the belt around the motor reduction gear and opposing belt bearing and attach the other end of the belt to the paddle mount with the belt attachment similar to before.
The paddle mount should now be connected to the motor via the belt and should slide along the rails. Repeat on the other side. Then, wire the encoders and microcontrollers to the Arduino as shown above.
To assemble the game board, first sand the plexiglass to prevent glare from interfering with the computer vision. Then, run the ARUCO marker generation script (scripts/gen_aruco.py
) and print the four markers. Attach these to the sanded game board, making sure that the detected corners align with the corners of the game board.
Attach velcro strips along the back and front walls of the game board as well as the TPU wall linings. Ensure that the furry side of a velcro strip is attached on the back wall of the game board as this will ensure that the game board is able to be removed to access electronics.
Glue the gutter system together as shown in the 3D model. Insert the entire gutter system into the game box.
Both buttons come with a plastic "nut" that holds the button together as seen here:
On the front of the board, unscrew the nut on each button and insert the button through the hole in the front of the box. On the inside wall, place the button backing plate and screw the plastic nut back on. The button's nut should now be compressing both the backing plate and the frontmost panel of the game box, securing the buttons in place.
Additionally, screw the screen into the screen mount and attach to the top of the game board. Wire the screen and both buttons as mentioned above.
To construct the joysticks, first assemble the laser cut finger joint box. Then, snap the bottom half of the joystick onto the slider.
The top half of the joystick can then be glued on, forming the complete handle.
On the top plate, screw in both rails leaving one screw undone. Insert the slider between the rails, and secure the final screw.
Then, attach the potentiometer to the joystick and screw the potentiometer into the top plate. Feed the potentiometer wires through the hole in the back of the box, and connect to the Arduino as mentioned above.
For the camera, first insert the metal rod through the corresponding holes on the rear upper panel and bottom panel of the game box.
Attach the camera to the printed hinge mount and push this mount onto the top of the metal rod. Secure the rod in place.
Once all wiring is complete, attach the Arduino Mega to its mount and secure the mount to the bottom of the board. Place the power supply brick in its mount and secure to the bottom of the board as well. Glue the gutter system together and fit it along the inside walls of the game box and attach the collection bowl to the front of the box. The game board can now be inserted, the wall linings attached, paddles clipped in, and the product is ready to play.
To run the project, we have to upload the gameplay code to the arduino Mega board, the driver code to the two drivers (making sure to have the delay set at the beginning of the setup for one, but not the other driver in order to reduce the current peak during setup) and the computer vision code that run on a computer.
To play the game, we must first launch the Python computer vision code. The Arduino should be connected to the laptop, and the port used should be specified in the first line of the main method. The camera must be connected to any USB port on the laptop.
Once the code is launched, it starts by calibrating the camera: it first detects the four Aruco Markers and then computes the transformation matrix for the frame. Next, motor calibration takes place by detecting the red triangular-shaped paddles. The system sends "Go UP" and "Go DOWN" commands to the Arduino through the serial port. Once the boundaries are reached, a stop command is sent to the Arduino. This step is crucial to establish concrete bounds of the board and to save the zero and maximum positions of each motor.
After reaching all four edges of the board, the code enters the main infinite loop of our algorithm. It detects the blue ball and red paddles by color detection, predicts the trajectory of the ball, and then sends the motors to the correct positions at the right time to hit the ball in computer player mode. Concurrently, the algorithm checks if a goal has occurred by performing the following checks:
If the ball is close enough to an edge, moving toward it, and then it is not visible for three consecutive frames, it is considered a goal. In the event of a goal, a "goal 0" or "goal 1" command is sent to the Arduino depending on which player scored.
To exit the algorithm, press the 'q' button.