Game Controller V2
Learn Make Share!
PROCESS MAP
BACKGROUND
Throughout this project, we had worked on creating a game controller which is an input device used with video games or entertainment systems to provide input to a video game, typically to control an object or character in the game. It receives inputs from a push button or tilt sensor to control arcade games on a computer screen.
This project is a re-design and a scaled-down version of the game controller developed here. The main differences are:
The development of a custom-designed board based on ATTiny85 chip.
The use of mixed fabricating materials for the enclosure.
SUPPLIES
Electronics
x7 Push button
x2 Tilt sensor
x3 0OHM Resistor
x2 100OHM Resistor
x1 560OHM Resistor
x7 1KOHM Resistor
x1 1.5KOHM Resistor
x1 22.0µF Polarized capacitor
x1 Schottky Diode
x2 3.3V Zener-Diode
USB Type B Connector
5MM Led
Attiny85
Various
Pin headers
Screws
Nuts
Fabrication
3mm Acrylic sheet
Tools
Soldering iron
Digital Multimeter
Machines
Laser Cutting Machine
3D Printer
PCB Milling Machine
Apps
Fritzing
Arduino IDE
Fusion 360
Laserworks
GIMP
Gerbv
Eagle
PCB DESIGN
We are going to develop a PCB that combines all the components required for the game controller to function correctly. This will allow us to reduce the size of the game controller.
Design Aspects
Based on ATTiny85 chip.
Power via USB or External Source.
Built-in USB to allow communication with the PC.
Contains 6 push buttons and 2 tilt sensors.
About ATTiny85
The ATtiny85 is a microcontroller in a similar vein to the Arduino, but with much less IO pins, smaller memory and a smaller form factor. In fact, when we talk about the ATtiny85 we refer to the IC itself rather than the board. The ATtiny85 can be used as a bare chip on a breadboard, as long as you can supply the correct power for the device. The ATtiny85 comes with a remarkable number of ways in which we can interface. At the most basic level, we have 5V logic digital I/O pins, three of which can also be used as analog pins for use with components such as the TMP36 sensor. Four of the available pins can also be used with Pulse Width Modulation (PWM). Also available is I2C and SPI for use with other types of sensors and devices.
Taking a look at the boards developed based on attiny85, we can find that the most popular is the one developed by Digistump which is called Digispark USB Development Board. The Digispark is an Attiny85 based microcontroller development board similar to the Arduino line, only cheaper, smaller, and a bit less powerful. With a whole host of shields to extend its functionality and the ability to use the familiar Arduino IDE the Digispark is perfect for when an Arduino is too big or too much.
We will implement a similar board to the Digispark and adjust the design to satisfy the design aspects mentioned above.
Brain Design
We will start with the brain which is the ATTiny85 connection. ATTiny85 board contains 6 I/O Pins (2 are used for USB only if your program actively communicates over USB, otherwise you can use all 6 even if you are programming via USB). Also, it contains 1 VCC pin and 1 GND pin. We will be using the GND, VCC, and RST pins for their normal operations which are a reference point for all signals, a supplied voltage to the board, and a reset respectively.
A push-button will be connected to the RST pin to be able to reset the board using this putton.
We will be adding a power LED to indicate if power is supplied or not. A resistor will be added in series with the led to limit the current through the LED and to prevent excess current that can burn out the LED. A capacitor is added to work as a bypass capacitor to prevent noise from entering the system by bypassing it to the ground. It is connected between the supply voltage (Vcc) and ground (GND) pins to reduce power supply noise and voltage spikes on the supply lines.
USB Connection Design
Now, we will implement the USB connection. We will be using USB Connector "B" Type Female. It has
Then, we will implement the USB connection. We will be using USB Connector "B" Type Female. It has
From ATTiny85 board specifications, PB3 and PB4 from it are used for the USB communication. We will be adding some zener diodes and resistors which limit their voltages.
Buttons
Since we will be using 2 pins from the ATTiny85 for the USB communication we are left with 3 Pins to be used for the I/O devices. We will only have PB1, PB2, and PB3 to connect our buttons and sensors. Now, we have 6 buttons and 2 tilt sensors that need 8 pins and we have only 3 pins. One way to solve such a problem is to combine the push buttons and connect them in a way that allows to minimize the pins needed and to be able to figure out which button is pressed.
We will be using the voltage divider concept to attach multiple buttons to a single pin.
We will connect the output to PB3, since it is the only analog pin left (be careful not to connect it to any other pin).
Extra
Now, we will be left with only 2 pins one for each sensor. We will add terminals so that we can access the used pins. Since I had faced difficulty connecting the 6 pins to 1 terminal, I had separated the 6 pins into 2 groups each group in one terminal. In addition, I had added some zero ohm resistors that are required to connect between 2 ground planes separated from each other.
So, after all the final schematics looks like the following image:
Board Generation
Now, We will turn our schematic into a board and place the components on the board so that we can fabricate it.
As we are going to place the PCB on a game controller with a specific design, it will be better to have an idea about the design of the game controller and then design the PCB to fit this design. So, I had designed first the board layout on Fusion to have a better sense of the dimension and scale of the board.
Then, after having the layout, we can export the file in a DXF format and then import it into Eagle as the layout of the board. After this step, we will be ready to place the components on the board. We will place the in a way that facilitates pressing them and matches what is found in most game controllers.
By using Polygon Tool, We will also make a big copper area connected to the ground.
Then we will add some holes at the board edges to allow us to to mount our PCB inside our enclosure.
Then, we will define the design rules for out board which are all the parameters that the board layout has to follow.
Routing
It’s time to start connecting the components together with traces. We can use either the autoroute or connect the components manually. However, the autoroute at my design didn't give a 100% routing result so I had to rout the board manually.
Now, our board is ready. We can sync between this design on eagle and Fusion so that we can import the board on Fusion and any change done at any side will affect the other side.
You can find more about Fusion 360 Integration with Eagle here.
Gerber and Drill Files Generation
Before we leave eagle we will generate the files needed for fabrication. We will use these Gerber and Drill files to make your boards. We can load up the CAM processor by clicking the CAM icon. We will only check the export as ZIP option at the top of the window and press Process Jop.
To fabricate the board we are only interested in three files generated from the CAM processor which are the bottom copper file, the profile, and the drills. We will combine the drills with the profile in one pdf and the bottom copper with the profile in another pdf using Gerbv App. Then we will export those two files to process on them at GIMP App.
After we finish processing and have the three files, we are ready to fabricate board.
ENCLOSURE DESIGN
After we had finished our board, we will begin designing the enclosure by building from the board. So, we will start by placing the board on our Fusion project and then build our enclosure.
We are going to fabricate the body using the 3D printer and the top and bottom will be made of acrylic.
Body, Top, and Bottom
We will start by making an offset from the board layout and then draw out a join which will be a triangle that will join between the 3d printed part and the acrylic part. As the acrylic's width is 3MM, the 3D printed part will be also 3MM width.
From this sketch, we can extrude the body, top, and bottom parts.
Note that I had added an extension inside the body part to mount the board inside the body.
Buttons
The buttons will be created by drawing an offset from the rectangle generated from the projection of the button on the board and then extruding the lower part which will be inside the enclosure with a width bigger than the upper part which will be the part that appears to the user.
Then , we will write text inside the rectangle and engrave it inside the part using extrude cut. For a better fit between the 3d printed buttons and the push buttons, i had created a hole at the bottom of the button with a radiuse equal to the head of the push button.
3D PRINTING
As we said before, the body and buttons will be fabricated using the 3D printer. So, after we export the models as STL, we import the files to Ultimaker Cura which is a slicing application for 3D printers. Then, we choose the 3D printer model, Prusa i3 MK2, and the printing material, PLA. Then we adjust the print setting, which includes all settings that define the printing strategy, according to the printer we are using. We will enable the generation of supports to get reliable and successful print.
LASER CUTTING
Now. Let's fabricate the top and bottom.
Testing
As it was my first time fabricating something using acrylic, I had tested the speed of cutting the acrylic. So, I had cut a small rectangle with speed 10 and power 70 to make sure that the speed and power are fine.
Cutting
Then, after ensuring that the speed and power of cutting ware fine, I had imported the top and button DXF files to LaserWorks and adjust the settings as follows:
Cut: speed 10, and power 70
Engrave: speed 300, and power 30
PCB FABRICATION
First, we get a single-layer copper board in a suitable size relatively bigger than the size of our board which is 160x68 MM. Then, we mount it to the machine table using double-sided tape. We had already three files which are buttom, drills, and profile, we are going to import those files into fab modules one by one respectively. Also, we change the tool from one process to another as the cutting tool differs with the type of process.
PCB SOLDERING
Once our board is ready, we begin soldering the components.
After connecting the components, we may check for any short circuit or undesired connection using the connectivity function at the Multimeter, in which we test if two unrelated points are the same then we fix the short circuit using the iron. However, by practice, soldering becomes easier and fewer mistakes are made.
UPLOADING THE BOATLOADER
Unfortunately, we can’t just plug the ATTiny85 MCU into a computer to program it. One of the more convenient ways to load our program data onto the ATtiny MCU is through a special program called a bootloader. This program sits on the MCU and listens for incoming instructions, and then writes new program information to the MCU’s memory. With the help of the bootloader, we’ll be able to load code from your Arduino IDE onto the ATtiny85 using the USB connection. This means that we won’t need to remove the MCU from our circuit in between programming rounds.
How to Flash the bootloader onto the ATtiny85
We can upload the bootloader by using the Arduino as an ISP, or In-System Programmer. This allows new programs to be uploaded to the ATtiny without removing the chip from the circuit it’s being used in. We are also going to flash the digispark attiny85 bootloader on ATtiny85 which runs the “micronucleus tiny85” boot-loader.
Configuring Arduino Uno as an ISP
Since the ATtiny85 is just a microcontroller, it requires an ISP (In-System Programming) to be programmed. So to program the ATtiny85, we need to first configure Arduino Uno as ISP to act as a programmer for the ATtiny85. For that, connect the Arduino Uno to Laptop and open the Arduino IDE. After that, navigate to File > Example > ArduinoISP and upload the Arduino ISP code.
Circuit Diagram for Flashing Boot-loader on ATtiny85
The complete schematic for Flashing Boot-loader on ATtiny85 is given below:
A 10 µf capacitor is connected between the Reset and GND pin of Arduino.
Now we plug-in the Arduino Uno to the laptop and open Arduino IDE. Find what COM port the Uno is connected to.
After this, download the ATtiny85 Boot-loader files from the given link. Open "Burn_AT85_bootloader.bat" and change the COM port number with whatever COM port number your Uno is connected to. Save the changes before exiting.
Now move the edited "Burn_AT85_bootloader.bat" and "ATtiny85.hex" files into the Arduino IDE root folder (usually C:\Program Files (x86)\Arduino).
After that, right-click on "Burn_AT85_bootloader.bat" and select "Run as Admin". It takes approx 5 to 6 seconds to flash the boot-loader. If all went well, we should receive this message "AVRdude done. Thank you. Press any key to continue...".
With this, the Boot-loader is successfully installed onto the ATtiny85 Chip. Now it’s time to connect USB with ATtiny85 so that we can program it directly.
INSTALLING DIGISPARK DRIVERS
To program the ATtiny85 using USB, we must have Digispark Drivers installed on our laptop, if you don’t have them, you can download it using the link given above. Then, extract the zip file and double-click on the “DPinst64.exe” application to install the drivers.
Once the drivers are successfully installed, Plug in the ATtiny85 board to the laptop. Now go to Device Manager on your Windows and the ATtiny85 device will be listed under “libusb-win32 devices” as “Digispark Bootloader”. If you can’t find ‘libusb-win32 devices’ on the device manager, then go to View and click on ‘Show hidden Devices.’
SETTING UP ARDUINO IDE TO PROGRAM ATTTINY85
To program the ATtiny85 Board with Arduino IDE, first, we need to add the Digispark board Support to Arduino IDE. For that, go to File > Preferences and add the below link in the Additional Boards Manager URLs and click ‘OK.’
After that, go to tools > Board > Board Manager and search for ‘Digistump AVR’ and install the latest version.
After installing it, now you would be able to see a new entry in the Board menu titled 'Digispark'.
ASSEMBLY
Now, everything is ready for assembly. Let's do it.
First, I had started by attaching the PCB to the 3D printed part and mounted them with screws. Next, I had added the bottom part. Then, I had added the buttons and top parts.
PROGRAMMING
At this stage, we will program our board to do the required functionalities.
We will add a library called DigiKeyboard to have the board act as a keyboard as we chose the Digispark board earlier. The DigiKeyboard library is installed by default if we had done the previous steps correctly. However, I had downloaded DigiKeyboardFr, which is an adaptation of Digispark's DigiKeyboard library, as it has a definition for the ASCI codes for all the buttons, unlike DigiKeyboard.
To download it, go to Sketch> Include Library > Manage Libraries and search for ‘DigiKeyboardFr ’ and add it to your libraries.
First, we define what are our inputs. We have buttons connected on PIN2 and 2 sensors one at PIN0 and another at PIN1. There is something to be noted about digispark is that the analog input pins are referenced by their analog port number, not their pin, and for digital inputs, the pin number matches. So, if we read the analog value of PIN2, we access it with number 1 which references the port number and if we want to read the digital value of PIN1, we access it with number 1 which references the pin number.
Next, we will define the range of analog values that our buttons pin (PIN2) would give us. Theoretically, we can use the voltage divider calculations to get the analog value that the pin would give us if each button is pressed. Then, we define a tolerance for that voltage which defines how much we would allow a difference for the measured value from the theoretical value.
Then, we declare the variables where we will store the value of each input pin at the beginning of each loop so that we avoid instantiation inside the loop every time it runs in addition any read value does not change from one line to another.
Also, we define the mode status variable which will store the value of the current play mode. We are going to use the two tilt sensors to indicate the right and left directions so the mode status will determine if we take the right and left instructions from the two tilt sensors or we take them from the two push buttons. However, the other buttons will have the same functionality at any mode.
Then, we declare the variables where we will store the value of each input pin at the beginning of each loop so that we avoid instantiation inside the loop every time it runs in addition any read pin value won't change from one line to another.
Next, we will write the logic which is the same for any game mode. The UP, DOWN, O, X buttons will have the same functionality regardless of the mode. The UP and DOWN buttons will be used as directions, the O will be used as space, the X which is engraved as (<>) on the button will be used to switch between using the push buttons or the tilt sensors to control the RIGHT and LEFT directions. Note that I had added a return line if a button is pressed as we don't have to continue the remaining code if a button is pressed.
Last, we will identify the logic related to the mode. If the mode is one, then we are going to take the LEFT and RIGHT directions from the sensors , otherwisw, we will take them from the push buttons.
FINAL RESULT
CONCLUSION
What i had learned
During this module's development, i had learned about the devlopment and fabrication of PCB. I had also devoped an understanding about mixed fabrication methods like combining parts made from different materials into a cohesive body.
I hope you have liked this project and you will build your own Game Controller so that we can share and explore the World together !
Enjoy !!