Introduction: SatellitePi - Raspberry Pi Zero in an NES Satellite

About: I am a husband, dad, and software developer. I really like to tinker.

I've built quite a few Raspberry Pi powered RetroPie/emulationstation consoles. Some of my favorites include this NES Controller build: https://www.instructables.com/id/RetroPie-Inside-a... and this Pi Cart build https://www.raspberrypi.org/blog/pi-cart-retropie-...

For this build I borrowed bits and pieces from both.

I wanted to build a console that had the original NES controller ports so I could use the original NES controllers without modifying them in any way. I searched Ebay for broken NES consoles that I could either use the entire case plus the ports or just salvage the ports for my own enclosure. To my surprise even broken NES consoles sale for a decent price. Then I stumbled on the NES Satellite. It looked absolutely perfect. It looks like a console and it only cost me 8 bucks! The Satellite was an official infrared multitap peripheral adding wireless gameplay and support for up to 4 players. Note: the Satellite I purchased didn't have the receiver unit that would plug into the NES. Of course this part isn't necessary for this build.


Goals of the Project:

  • Use at least 2 of the 4 controller ports.
  • Do as little modifications to the outside of the enclosure as possible.
  • Make use of the LED and some of the buttons if I can.

Materials:

The modded USB controller ports are optional but if you plan on doing them you'll need

  • 2 x USB cables with USB A Female connectors that you don't mind cutting up
  • 1 x cheap 4 port USB hub(I used this)

Tools and other Materials:

  • Soldering Iron, Solder, and Desoldering braid
  • Wire (I used 22 gauge solid core)
  • Wire Strippers
  • Phillips Head Screwdriver
  • Hobby Knife or box cutter
  • Dremel

Step 1: Disassemble

I was happy to see that the unit is held together by 6 phillips head screws instead of those crazy gamebit screws Nintendo likes to use. Remove these and the bottom should come right off exposing the circuit board and battery terminals.

The first thing I did was remove these corroded terminals.
Next there are 4 screws holding the PCB in place. Remove these and you can then lift the board up.

Step 2: Remove Barriers Inside the Enclosure. Create Opening for HDMI and MicroUSB Extension Cables.

The wall running down the center of the bottom half(dark grey) was easily removed with by gently bending it back and forth. It eventually broke away fairly clean.

On the other half(light grey) there are 2 tabs in the center that I was also able to remove by gently bending them back and forth. I used a dremel to carefully remove the little wall meant to guide the batteries.

On the backside of the IR cover I carefully dremeled out a rectangle for the HDMI cable on the left side. I had planned to do a smaller square for the microUSB extension but constraints in the enclosure forced me to remove the entire rectangular piece and move the HDMI port to the right side.

The female ports where then super glued(very well) in the opening.

Step 3: Pi Zero Software Setup

Before moving forward I went ahead and setup the software side of things for the Pi Zero.

Go to https://retropie.org.uk/download/ and grab the Zero specific image and flash it to an microSD card. I'm not going to get into the details too much here because there are plenty of resources online explaining this process.

On first boot I didn't configure any controller inputs in EmulationStation. Simply press F4 to exit to the terminal and start the configuration portion.

pi@retropie:~ $ sudo RetroPie-Setup/retropie_setup.sh
# From here you'll need to configure wifi to be able to install the needed gamecon gpio driver.
# Goto:
# C Configuration / tools >
# 829 wifi - Configure wifi
# Once your connection is configured, back out to the main menu. Then goto:
# P Manage packages >
# driver Manage driver packages >
# and select '809 gamecondriver'
# After the driver is installed DO NOT configure 2 SNES controllers which is offered.
# Just exit back out to the terminal.

Make sure /etc/modules contains 'gamecon_gpio_rpi'.
If it doesn't use 'sudo nano /etc/modules' or 'sudo vi /etc/modules' to add it. The driver installation has always handled this for me

pi@retropie:~ $ cat /etc/modules
# /etc/modules: kernel modules to load at boot time.
#
# This file contains the names of kernel modules that should be loaded
# at boot time, one per line. Lines beginning with "#" are ignored.
uinput
gamecon_gpio_rpi

Now we need to configure the module to let it know what type of controllers and which GPIO pins we will be using. A more in depth overview can be found here https://github.com/retropie/retropie-setup/wiki/G...

Create this file

pi@retropie:~ $ sudo vi /etc/modprobe.d/gamecon.conf

And make it look like this

options gamecon_gpio_rpi map=0,0,2,2,0,0

Step 4: Wiring the Controller Ports

I ended up only wiring up the Player 1 and Player 2 ports. Both are on the bottom of the PCB. I'll do my best attempt at explaining how I did this and provide a diagram.

For this step I wanted to use as much of the existing circuit as I could. There are a few places on the board I decided to cut the trace with a hobby knife to prevent power going to the rest of the board. I did this because I didn't want any unintended shorts and wanted to isolate the port circuit as best as I could.

Fortunately there are a few shared traces between the ports that are very useful and limit the number of wires we need to go from this board to the Raspberry Pi.

  • Ground (Black) - (Pin 6 on Pi) is shared. Only need one wire.
  • Power (White) - (Pin 1 on Pi) is shared. Only need one wire.
  • LATCH (Green) - (Pin 23 on Pi) is shared. Only need one wire.
  • CLOCK (Red) - (Pin 19 on Pi) isn't shared on the bottom 2 ports for some reason so I created a bridge.
  • DATA (Yellow) - (Player 1 Pin 7, Player 2 Pin 26) each port will need it's own wire for DATA.


After this hook up some controllers, plugin HDMI and your microUSB power supply and test your work!
When emulationstation starts it should prompt you to configure your controllers.
Hold a button on the player 1 controller.
If all is well it should see your controller and allow you to configure all your buttons.
After that the first, press start, select Configure input, and repeat the process for the second controller.

Step 5: Add USB Ports to Controller Port Housings.

  • First I removed half of the sheath around the female ends of my USB cables. This will make them more flexable and take up less room when closing up the enclosure.
  • Next I dremeled around the Player 3 and 4 Controller port pins. Here I realized I needed to desolder the pins to be able to remove the cut piece of circuit board. I used Desolder Braid for this.
  • Once the pins were free I could pull the cut piece away and remove the Port Housings from the other side.
  • I used a dremel to cut around the pins on the back side of the housing.
  • Then I used some super glue to mount the new USB Female connectors into the Controller port housings.
  • I also applied some hot glue on the back side for added support.
  • Next I put the housings back in place with the cables coming through the backside of the circuit board.
  • While I had my iron heated up I removed the front turbo switch to make room for the HDMI Cable when reassembling.
  • I applied some hot glue to hold both of the turbo buttons in place since I wont be using them.
  • Lastly I prepped the cables to be attached to the USB Hub
    • Clip the micro USB connectors off.
    • Strip insulation exposing the 4 usb wires (ground, data-, data+, power)
    • strip a small amount of insulation from 4 wires and tin them.

Step 6: Connect USB Ports to USB Hub

  • Remove housing from hub.
  • Replace standard USB male connector with a micro USB connector. This will save some space and remove the need for a converter.
  • Remove 2 of the female ports on the hub and connect the 2 cables coming from the controller port housings.
  • After this step would be a good time to test your new ports on your Pi.
  • Hot Glue your connections for greater good.

I went ahead and plugged in my wifi module to one of the remaining ports and I've still got one free.

Step 7: LED and Safe Shutdown Button(update)

Hardware Stuff

Before starting this I took the opportunity to shorten that 3 ft. power cable making things much more spacious! One note on the power extension cable, since it is only used for power there was no need to mess with the data wires. After cutting the cable I only had to reconnect the positive and negative wires and wrap it up with some electrical tape.

Wiring up the LED and Power button turned out to be pretty straightforward. Since the NES Satellite PCB has a path to GND via the work done on the controller ports, we only need to run the positive leads to the GPIO pins. Most of the heavy lifting is done at the software layer.

Wiring

  • LED Anode Pin to GPIO 16 with a 10ohm resistor inline
  • Power Switch + Pin to GPIO 5
  • I cut the trace beside the power switch + pin to isolate the pin. See images for reference.

Note: I didn't place a resistor inline between the power switch and the GPIO 5 pin. I read somewhere that GPIO 2 and 5 both have pull-up resistors on the board but I can't seem to find that reference now. It might be worth adding one anyway. Only 3.3v is being supplied to the NES Satellite board so I'm chancing it for now but don't blow up your Pi based on my bad advice!

So that is it for the hardware. On to the software bits!

Software

LED

Using a device tree overlay I effectively told the Pi to use the LED wired up to GPIO 16 instead of the onboard ACT LED. The external LED now functions like the onboard one did, blinking during periods of activity. If I recall the onboard ACT LED blinks in response to SD Card read/write activity. I configured the new one to respond to cpu activity instead. In depth information on device tree overlays can be found here https://www.raspberrypi.org/documentation/configur...

Dts stuff came from this post: http://www.sudomod.com/forum/viewtopic.php?t=1113#...

1) Create overlay 'source' file (with your editor of choice)

pi@retropie:~ $ vi act_led.dts

Make it look like this:

<p>/dts-v1/;<br>/plugin/;</p><p>/ {
	compatible = "brcm,bcm2708";
	fragment@2 {
		target = <&leds>;
		__overlay__ {
			/*
			 * External LED to show CPU activity.
			 * Active-high, GPIO 16
			 */
			ext_act_led: act {
				label = "ext_act";
				linux,default-trigger = "cpu0";
				gpios = <&gpio 16 0>;
			};
		};
	};
};</p>

Now we compile the overlay and copy the output to the overlays directory:

pi@retropie:~ $ dtc -O dtb -o act_led.dtbo act_led.dts
pi@retropie:~ $ sudo cp act_led.dtbo /boot/overlays/act_led.dtbo

And now we need add this line to the bottom of /boot/config.txt ( sudo vi /boot/config.txt )

dtoverlay=act_led

Safe Shutdown Button

The Power Button on the unit does not function as a 'Power' button meaning that if the unit is in a halted stated and the button is pressed, it will not power on. Like all pi's, plugging in the power supply will turn the unit on. Given the unit is booted, when the power button is pressed, it will initiate a 'safe shutdown'. This is currently done via a python script running in the background listening for input on the GPIO 5 pin. In the future I would like to find a hardware solution to eliminate the potential overhead of this software solution. Note that I haven't experienced any slow down in game play due to this process running but I feel a hardware solution would be much cleaner.

This post was most helpful https://www.element14.com/community/docs/DOC-78055...

pi@retropie:~ $ mkdir scripts<br>pi@retropie:~ $ cd scripts<br>pi@retropie:~ $ touch shutdown_pi.py<br>pi@retropie:~ $ vi shutdown_pi.py

Add the following:

<p>#!/bin/python  <br># Simple script for shutting down the raspberry Pi at the press of a button.  
# by Inderpreet Singh  
  
import RPi.GPIO as GPIO  
import time  
import os  
 
# Use the Broadcom SOC Pin numbers  
# Setup the Pin with Internal pullups enabled and PIN in reading mode.  
GPIO.setmode(GPIO.BCM)  
GPIO.setup(5, GPIO.IN, pull_up_down = GPIO.PUD_UP)  
 
# Our function on what to do when the button is pressed  
def Shutdown(channel):  
    os.system("sudo shutdown -h now")  
 
# Add our function to execute when the button pressed event happens  
GPIO.add_event_detect(5, GPIO.FALLING, callback = Shutdown, bouncetime = 2000)  
 
# Now wait!  
while 1:  
    time.sleep(1)</p>

Now edit /etc/rc.local (sudo vi /etc/rc.local)

<p>#!/bin/sh -e<br>#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.</p><p># Print the IP address
_IP=$(hostname -I) || true
if [ "$_IP" ]; then
  printf "My IP address is %s\n" "$_IP"
fi</p><p>sudo python /home/pi/scripts/shutdown_pi.py &</p><p>exit 0</p>

Now reboot and test everything out!

Step 8: Button It All Up and Play Some Games!

Cable arrangement and fitting everything in was a bit of trial and error. The 3 foot power supply extension gave me the most trouble. I had to move things around a few times to be able to put the battery cover back on but in the end it all came together. Just be patient and don't force things!

Happy Hacking!