Back to Top Hardware Software Appendix
View on GitHub

PiArcade4KB

Final Project for ECE 5725

Presenting the PiArcade4KB!

We created a wireless arcade stick complete with a joystick and six arcade buttons using the Raspberry Pi 4. This stick utilizes TCP to communicate between a server and a client. The server is hosted on a laptop that will be displaying/running the game, and the Raspberry Pi acts as the client.

image

Hardware

The box measures 11.5x6.5x3" and was made using the transparent and colored acrylic sheets as well as had a 3D printed component. Everything was designed on Autodesk Fusion 360 and made use of fabrications tools such as the laser cutter and 3D printers.

Sketches when Designing the Box

The Build

The box was designed using a simple puzzle pattern so that the teeth slots could fit into one another. The walls were then super glued together so that they could stay in place. The blue wall however was not super glued in place so we could still have easy access to the pi, the TFT and the power button for the externalbattery pack. The following images show the sketches that were made on Fusion 360 before being exported as dxf files for the laser cutter to cut.

image

Top Cover

image

Short Side Cover

image

Long Side Cover

image

Bottom Cover

The Raspberry Pi and Pi-TFT were then raised to level on the top cover by designing a holder on Fusion 360 and 3D printing it.

image

Raspi and TFT Holder

The Circuit

We wanted to include a feedback system for our buttons and we decided on making a circuit that would support small LEDs so that when a button was pressed, a different colored LED would light up and on the release of the button, the lED would turn off. To accomplish this, we put the LEDs in parallel with each button. On a button press, the connection with GND is made and closes the circuit for the LED.

image

A Simplified Diagram of our Circuit

The Finished Build

The joystick was screwed in place using two M3 scews. The buttons came with screw on parts that allowed us to easily screw the buttons inbetween the acrylic without us needing to glue them in place. We also stuck velcro on the bottom of the external battery pack and on the green acrylic so that the battery pack is ensured to stay in place. The 3D printed part then rests on top of the battery pack to make up for the space so that the TFT can peek through the rectanglar hole that was cut for it.

image

The finished product!

Software

The Arcade Stick works by using the Transmission Control Protocol (TCP) to send packets between a client (Raspberry Pi) and a server ( another Raspberry Pi or PC). These packets are a buffer of inputs detected by the raspberry pi, which is then sent to the PC which converts all the inputs into keystrokes, which will control a game currently running on the PC. Additionally, the PiTFT will actively poll our inputs and give appropriate feedback depending on the buttons pressed.our code into three main sections.

Transmission Control Protocol

Transmission Control Protocol (TCP) is a standard that defines how to establish and maintain a network connection by which applications can exchange data between one another. For TCP, a connection must be established and maintained until every application ( or our devices in this case ) are finished exchanging messages. TCP introduces error-detection, which adds more latency to the communication. We thought it would be an interesting experiment to attempt to control games wirelessly with the Raspberry Pi to see how much latency it would provide to our application.

Client Code (Client_GPIO.py)

The Client-Side code is responsible for determining if any new inputs have been detected. It works by first creating a TCP socket and connects to the IPv4 address of the server (can be obtained using ipconfig). All inputs are added to a global input buffer which is converted to a string, encoded (with the string.encode() function), and sent to the server. It also keeps a history of all inputs in a log file which was very useful for debugging later on. In order to modularize our code as much as possible, we put all our callbacks in a separate module, callbacks.py.

Callbacks.py

This file contains all callbacks that the Raspberry Pi uses to detect inputs. The buttons are configured to trigger a callback on the falling edge and the rising edge, to simulate pressing, holding and releasing a button. with a very small bouncetime (approximately 20), to account for the situation where the player may want to mash a button. We also implemented some software debouncing so that the Pi would not detect multiple inputs when a button is pressed only once. We made a dictionary that keeps track of the current state of our button presses.

image

Code snippet from Callbacks.py

Server Code (server_final_v1.py)

The server host (the computer running the game) exclusively serves to receive inputs from the client, parses them, and calls the keyboard.press and keyboard.release functions to simulate buttons being pressed, held and released. Firstly, a socket is created and bound to an address, after which sock.listen() and then sock.accept() is called, which is a blocking statement that waits for a connection to be requested by a client. The server will then receive 4096 bytes ( to ensure the entire buffer is received) of data, and appropriately reconvert it into a list by getting rid of any trailing bracket characters ( as they are now part of the string). If the server receives a number from the client, it will remap the controls, and will change the function of the buttons pressed.

image

Remapping controls

GUI.py

The last thing we implemented for our Arcade Stick was an interactive PiTFT GUI, as shown below. The GUI gives visual feedback depending on which buttons are currently pressed as confirmation that the player is pressing the button they meant to. We first defined all the GUI elements: the coordinates of all the text, and any images we needed. In the main while loop, we rendered the elements on the PiTFT screen depending on what “level” we were on. The level variable simply determines which elements to generate on the screen. In order to update the elements depending on which button was pressed, we would poll, instead of using interrupts, to update the colors of the buttons and arrows which turned out to be an easier way to implement them.

image

Diagram of the GUI

Appendix

Bill of Materials

Github Repository

PiArcade4KB Github Repository

Authors and Contributors

This project was a team effort by Kofi Efah and Eli Vicarte, both Cornell ECE '22.

image