Intro: Homemade Game Console- "NinTIMdo RP"
Link to webpage with more in-depth explanations, parts list and files
This project was to create a portable gaming system that could also double as a portable computer. The goal was to create a console that was functional as well as aesthetically pleasing.
Step 1: Print Case
To print the device download my 3D model files and send them to your 3D printer. The printer I used was a Prusa i3 Mk2 along with black plastic filament. Printing quality was found to be best in a medium resolution setting. Be sure to add structural material under in the device (Hand holds will look poor without it). Back pieces were printed with the back flush with the platter. Front pieces were printed with the front face flush with the platter. If I were to print another case I would want to use a new color such as atomic purple to show off the internals.If you're like me and have an 8inch printing bed to work with you will need to print the 4 piece version which will be assembled after printing. However, if your bed is large enough to do as a single piece, print the front and back plate as a single unit and avoid the pain of piecing them together.
Step 2: Case Assembly
To assemble first join the front right and left pieces by inserting a metal dowel into the alignment holes. Next place super glue on the joints and secure half together. Repeat the process for the bottom right and left haves. After this you should be left with a assembled front and back half. Now it is time to attach the 5 metal standoffs for merging the front and back plates. The easiest way to do this is to first get the stand offs to the correct length. 13 mm depth in back 5 mm depth in the front. So make the standoffs 18mm or slightly less. I did this by placing a longer standoff in a vice grips and using a grinder to shave down the size. Be sure to only grind off one side because you will need the threads on the other. After you get the correct length glue all the grinder off sides to the front face using regular gorilla glue and let it dry. Be sure they are all standing up straight during this process. Once dry scrape the excellent glue that foamed up so that the faces can be flush when put together. Now see if you can insert the back plate onto the standoffs to join with the front. Screw together through the back plate to secure. Glue screen on by lining the frame with the duel tube Gorilla Epoxy. I put too much on when I did this and it overflowed onto the screen. Luckily it rubs off! Clamp and let dry for a while then line the backside with regular Gorilla glue.
**Note: Try not to get thin CA glue (super glue) on the exterior as it will "burn" the PLA and stain a white color.
Step 3: Circuitry
Capturing all the button presses is done using a Teensy ++ 2.0. Digital pins on the microcontroller are used for any binary press buttons. The analog pins are used for buttons that have multiple states such as the joysticks. To wire the digital pins simple wire the digital pin to the switch, have the other end of the switch wired to ground. When the button is pressed it will pull the high voltage pin down for the controller to sense. You do not need to worry about resistors as they are included on the Teensy board. To wire the analog pins you will need to bias your analog device with a high and low voltage and read a voltage level with in that range on the analog pin. For the joysticks there are 3 inputs for each axis. Supply a 5V to one of the pins, GND to another and the voltage read line to the last. Be sure to hook this up correctly or it will not work (use a multimeter to see if the output voltage changes on the correct pin.) Essentially the joystick is a variable resistor that works like a voltage divider. The output voltage on the read pin will vary between 0 and 5V depending on the joysticks position. (Usually the bias 5V and GND are on the outer input pins of the joystick and the middle one will be your variable voltage read pin. If 5V and GND are different than mine your controls will be inverted, this can be fixed in software or rewiring).
The three cell Anker battery supplies power to the entire device. To turn the device on/off, the output of the battery regulator is wired to a switch and then then Raspberry Pi. Because the device can draw up to 2A a simple 250mA toggle switch cannot handle the current requirement. Instead you can use the switch to control the gate voltage on a PMOS transistor to serve the purpose of a switch. Wire the 5V of the battery to the source of a PMOS transistor and the switch. The other end of the switch is wired to the gate of the PMOS transistor and to a 10K resistor connected to GND (when switch is open to prevent the gate from floating it ties it to GND through resistor). The Drain is wired to the 5V input on the Raspberry Pi along with the ground. To charge the battery simply wire the micro USB female breakout board to the correct charging pins (extends input to case). I hid this switch in the air intake in the back of the device. Originally I was planning to instead have the battery button turn the device on and off by holding it for a certain duration, unfortunately I ran out of room and had to do the simple implementation. This alternative design is shown in the schematic below.
For the audio I wanted sound to naturally play out of the speakers (if not muted) and redirect into headphones if they are plugged in. Fortunately, many of the female 3.5mm head phone jacks are mechanically capable of doing this. When a male plug is inserted the speaker leads will bend and create an open circuit, thus preventing the signal from reaching the speakers. Since the speakers are a larger load the audio signal must be amplified to be able to hear it. This is done using a stereo class D amplifier I found on adafruit. Simply bias the amplifier with 5V and GND. We do not have differential audio inputs so wire the left and right speakers to the positive terminals and tie the negative terminals to GND. Gain is adjusted using the jumper. I set the gain to the maximum and am changing the output audio signals amplitude via software to adjust volume. To mute the device I have a NMOS transistor controlling the 5V bias. This NMOS transistors gate is controlled by the Teensy. An issue I have is a constant high frequency noise is present in the external speakers. I will analyze this on an oscilloscope, may be coming from the 5V bias because of some regulator switching at the battery or the lines may be picking up RF somewhere. Also, be sure to twist the right and left lines to minimize electromagnetic interference (EMI).
Step 4: Peripheral Circuitry
This circuitry includes the USB mounts and LED indicator. Order the PCB in my link and cut in half along dotted line using band saw. On the USB side all solder the two female USB ports onto the board. On the LED side solder the 5 LED's and 5 resistors in series. 5V, GND, D+, D-can be extended using wires from the Raspberry PI's desoldered USB's to the PCB. The LED PCB can be placed so that the light shines through the holes on top of the case. Wire 5 PWM outputs of the Teensy to the LED's along with GND. By varying the duty cycle you can alter the brightness of the LED's.
Purchase PCB: https://www.pcbway.com/project/shareproject/Ninti...
Step 5: Programming
If you wired it exactly the same as me you can just use the code I provided on Github. However, I would recommend writing it yourself as you will understand the system better and be able to easily manipulate and customize it to your liking. Programming is very simple, it really comes down to writing a bunch of if statements to check if your buttons were pressed. A helpful instruction set from PJRC. You can use the Arduino IDE to write your code in as well as upload to Teensy.
This example shows me checking to see if digital pin 20 was pressed and then outputting the correct serial joystick command. You can choose any 1 through 32 for the button since Retropie does a controller mapping setup at the beginning anyways. Joystick.button(buttons: 1-32, Pressed=1 Released=0)
In the example, the right joystick vertical is wired to analog pin 41. The analogRead(pin) function receives a voltage level between 0 and 5V and returns a value of 0 to 1023. An ideal center position would correspond to 2.5V or 512, however this was not the case for my analog stick so adjustment needed to be made. This was done through a remapping shown below. After that I needed to check if the bounds were not exceeded 0 to 1023. Lastly the analog joystick command was sent over serial to be the analog button Z using Joystick.Z(value 0 to 1023).
Step 6: Optional Dock
This build wouldn't be complete without a dock for charging and easy TV hookup so I designed one in the pictures below. The 3D models are available with the others in my Github package.
Step 7: Results
In hindsight I wish I did the HDMI out port with a PCB instead of a pre bought female wall mount. This would have saved on a lot of space in actuality I had to tuck the cable in a spiral to avoid cutting it and re-soldering the 19 wires. I am torn about going with a smaller battery because the cell height was my limiting factor in the thickness of the entire device. However, reducing this would negatively impact my battery life.
In total this cost me around $350 to make. This does not include the raspberry pi I broke trying to shave down the size... Still happy I tried it out. It was a fun summer project to see if I could make it as compact as possible while at the same time fitting a lot of cool features inside.