I would have had it done a little sooner, but I dropped my first screen and cracked it


*** UPDATE ***
If you want to give this build a try, also check out my second attempt which has some 3D-printable brackets to make this much easier.
***
Highlights:
- 2.4in SPI Screen (with ~60fps - most of it is visible, but the left side is cut off a little, with overscan)
- "Safe" Shutdown on the power switch
- 2500mah battery =~ 5.5+ hours of gameplay
- Silicon shoulder buttons
- I2S Digital Audio with Digital Volume controls
- ADS-1115 Battery Monitor
- Full-size external USB port
- External SD Card access from original power switch spot
- Pi Zero W
- 2500mah 3.7v battery (actually left-over from my very first GBZ build that I had to cannibalize)
- Aftermarket GBC shell with standard buttons from some rando AliExpress merchant
- GBP buttons for X/Y from Handheld Legend
- Button board from glitch'd gaming
- "Easy" button boards for shoulder buttons from kitsch-bent
- GBA Silicon for shoulder buttons also from kitsch-bent
- Clear screen guard from kitsch-bent
- 2.4in ILI9341 SPI Screen - the working one was from rando E-Bay
- 23mm 8ohm 2w speaker
- SPI Adapter from pocketadventures
- Power Assist Basic, including Safe Shutdown, 5v boost, and recharge from pocketadventures
- ADS1X11 for battery monitoring (this one works with 1115 settings, even though I keep trying to get 1015s)
- UV LED light for front "power"
- Printed mounting hole (I needed to file it down some in spots, to fit with this build - If I do another, I think I would remix this to fit better with these builds)
- Power switch for a GB DMG (I had this for a little while, and don't remember where it came from, but most likely with HHLegend, RetroModding.com or Kitsch-Bent)
- "Clicky" tactiles for volume control
- Tiny DPDT switch for power-on, and safe shutdown/off, and to cut off battery from ADS
- PJ-328 audio jack (Although, if you can get one that fits the stock model, the button board would handle it better - this is just what I had on-hand, and it fit pretty good with the existing shell cut-outs for the standard one)
- 30awg silicon coated wire (perhaps the most important part in this list!)
- Custom designed screen border
- RetroPie 4.3 (because it's worked better for me than 4.4, with the SPI driver, for whatever reason)
- JUJ FBCP LCD Driver for SPI Display
- detailed instructionsShowI discovered this method through VeteranGamer's posts, so this is cribbed from that mostly, but adapted to suit the orientation and overscan for this build.
Here are the commands you will need to execute:Code: Select all
git clone https://github.com/juj/fbcp-ili9341.git cd fbcp-ili9341; mkdir build; cd build cmake -DARMV6Z=ON -DILI9341=ON -DSPI_BUS_CLOCK_DIVISOR=6 -DGPIO_TFT_DATA_CONTROL=24 -DGPIO_TFT_RESET_PIN=25 -DSTATISTICS=0 .. make -j
Then add it to the startup process:If you get an error that cmake isn't installed...ShowI have never needed to install it here, but, you can run this to install it and then continue with the "cmake" line when it finishes:Code: Select all
sudo apt-get install cmake
Add this line somewhere above "exit 0":Code: Select all
sudo nano /etc/rc.local
Here are the overscan settings I found work best.Code: Select all
/home/pi/fbcp-ili9341/build/fbcp-ili9341 &
Paste these in, but make sure you do not have other conflicting settings for these in the config elsewhere. If you do, add a # to the beginning to disable them.Code: Select all
sudo nano /boot/config.txt
Code: Select all
########################## ### Small Screen Sizing ## ########################## framebuffer_width=284 framebuffer_height=240 ########################## ### Overscan Placement ### ########################## disable_overscan=1 overscan_scale=1 overscan_left=42 overscan_right=2 overscan_top=0 overscan_bottom=0 ########################## # Disable SPI ########################## dtparam=spi=off
- Adafruit (by way of Pimoroni) I2S Audio Amp
- Install CommandShow
Code: Select all
curl -sS https://raw.githubusercontent.com/adafruit/Raspberry-Pi-Installer-Scripts/master/i2samp.sh | sudo bash
- RetroGame Controls
- Mapping configShow
Code: Select all
sudo nano /boot/retrogame.cfg
Code: Select all
UP 22 # Joypad up DOWN 1 # Joypad down LEFT 23 # Joypad left RIGHT 0 # Joypad right ENTER 12 # 'Start' button SPACE 5 # 'Select' button A 16 # 'A' button B 14 # 'B' button X 26 # 'X' button Y 6 # 'Y' button L 20 # Left shoulder button R 15 # Right shoulder button ESC 12 5 # Hold Start+Select to exit ROM
- Minty Battery Monitor (Sixteenbit's fork) for battery monitor
- Updating for ADS-1115ShowOpen up the script file:Find the line "adc = Adafruit_ADS1x15.ADS1015()" and update to "adc = Adafruit_ADS1x15.ADS1115()"
Code: Select all
sudo nano ~/Mintybatterymonitor/MintyBatteryMonitor.py
Adn then scroll down to the convertVoltage method and update the line "voltage = float(sensorValue) * (4.09 / 2047.0)" to read "voltage = float(sensorValue) * (4.09 / 32767.0)"
- Safe Shutdown
- detailed instructionsShowGetting the safe shutdown working was a bit of a challenge. PocketAdventures has some information over here. Unfortunately, some of it does not work out-of-the-box on older Raspian/RetroPie images.
I was able to get it working using two methods.
Both methods require an overlay added to startup, that should keep the "Signal On" to the PSU active, until the "poweroff" happens and sets it to low (cutting the power).Code: Select all
dtoverlay=gpio-poweroff,gpiopin=4,active_low="y"
Using Minty Battery Monitor / ShutdownShowI think this is the easier option, if using an ADS-1x15 for battery monitoring.
Bring up the script:Scroll to the bottom and update the Shutdown and Monitor buttons:Code: Select all
cd ~;sudo nano Mintybatterymonitor/MintyShutdown.py
I use 0.3 seconds for shutdown to try and improve the responsiveness, but any numeric value should work.Code: Select all
# Interrupts shutdown_btn = Button(17, hold_time=0.3) monitor_btn = Button(7, hold_time=2) shutdown_btn.when_held = shutdown monitor_btn.when_held = togglestate pause()
Using config.txt with overlayShowThe gpio-shutdown overlay needs to be installed on RetroPie 4.3, in order to call shutdown using config.txt. I found the instructions through here.
First, get the overlay code:Next compile it (you should be able to ignore any Warnings):Code: Select all
wget http://www.stderr.nl/static/files/Hardware/RaspberryPi/gpio-shutdown-overlay.dts
Copy the command code to the overlay folder:Code: Select all
dtc -@ -I dts -O dtb -o gpio-shutdown.dtbo gpio-shutdown-overlay.dts
Finally, we need to add a uDev rule file for a power key:Code: Select all
sudo cp gpio-shutdown.dtbo /boot/overlays/
Paste in this code:Code: Select all
sudo nano /etc/udev/rules.d/99-gpio-power.rules
And now we can register it in config:Code: Select all
ACTION!="REMOVE", SUBSYSTEM=="input", KERNEL=="event*", SUBSYSTEMS=="platform", \ DRIVERS=="gpio-keys", ATTRS{keys}=="116", TAG+="power-switch"
Add in:Code: Select all
sudo nano /boot/config.txt
Code: Select all
dtoverlay=gpio-shutdown,gpio_pin=17
- Digital Volume
- detailed instructionsShowHere's a little python script I hacked together for doing digital volume controls, since I wasn't able to find one on a (relatively short) google search-and-find. It's very basic - it doesn't log or provide any onscreen feedback. It just increases and decreases the volume when you hit one of two buttons (up and down). Props to HoolyHoo and all the other open-source scripters out there, for enough examples to pull this together pretty quickly:
First, create the file:You should have a blank text file. Paste the content in - if you used pins other than GPIO 13 for Up and 27 for Down, then change those near the top:Code: Select all
sudo nano volume.py
that will also create a file to store the current volume setting (to persist when you reboot) named volume.txt in the pi root.here's the codeShowCode: Select all
from gpiozero import Button from signal import pause import os # Location of perisitant state file statePath = "/home/pi/volume.txt" # Initial volume setting vState = 60 # Minimum/maximum volume and how much each press adjusts vStep = 2 vMin = 0 vMax = 100 # GPIO pin configuration volumeUpBtn = Button(13) volumeDownBtn = Button(27) # Functions def volumeDown(): global vState vState = max(vMin, vState - vStep) os.system("amixer sset -q 'PCM' " + str(vState) + "%") def volumeUp(): global vState vState = min(vMax, vState + vStep) os.system("amixer sset -q 'PCM' " + str(vState) + "%") def readData(filepath): with open(filepath, 'rb') as file: return file.read() def writeData(filepath): with open(filepath, 'wb') as file: file.write(str(vState)) def doVolume(): while True: if volumeUpBtn.is_pressed: volumeUp() writeData(statePath) elif volumeDownBtn.is_pressed: volumeDown() writeData(statePath) # Initial File Setup try: vState = int(readData(statePath)) os.system("amixer sset -q 'PCM' " + str(vState) + "%") except: writeData(statePath) os.system("amixer sset -q 'PCM' " + str(vState) + "%") # Doin its thing volumeUpBtn.when_pressed = doVolume volumeDownBtn.when_pressed = doVolume pause()
finally, you need to set it up to run the script at boot time:Add a line above "exit 0" with this text:Code: Select all
sudo nano /etc/rc.local
Code: Select all
sudo python /home/pi/volume.py &
I also ended up removing the connector on the SPI adapter board, and soldering its flat cable directly to the board, to save another mm or so.
Front shell cutouts and 1st battery cut. Mounted USB and volume buttons.: USB cut:
I used Game Boy Pocket buttons, since they do not have the A/B printed into them, and I used a button well to match, and also the silicon from a GBP. It's important, if you do this, that you line up the slots on the wells with the silicon pad. they are pre-cut to fit in certain spots, so you won't get good action on the button if you don't. I also cut off the little hoop that would normally fit around a case peg, and that let it fit perfectly with the GBC silicon.
I trimmed the little flap off of the switch, that would normally hold the game cartridge in place on a GB, and filed a little bit around the case in that area, and it fit pretty well. There is not a lot of give/take though, so you can see into the case some when it is switched to one side if it's not mounted just right. I used a very small DPDT (2P2T) switch so I could also cut the battery off from the ADS - the motion isn't very wide, but it works well and keeps the button pretty much within the cutout for it.
Another thing that I did, that worked well when the switch is too far to one side, is to use the flap that I trimmed off to cover up some of the opening, so that when the switch is to one side, you can't see into the case. But, I was able to position the switch just right so that it doesn't need it in there.
I also removed some of the area around where the lanyard would normally go, to mount the battery monitor toggle button there.
I also ended up cutting off the lower half of the cart model (just under where the PSU sits in it) to give that bit of space over to the battery to use.
- Coming