Sunday, July 10, 2016

Homemade Handheld Videogame Console: Part 2: Setting up the RPi

After I finalised my case design, I shifted attention towards getting the Raspberry Pi configured to run games in the way I wanted. I basically wanted to be able to run existing python/pygame games on the device, making sure that the screen, audio and input from buttons via GPIO would all be working smoothly.

I started with the 27-05-2016 build of Raspbian, standard config for expanding the boot partition and configuring for a 104 key keyboard. I followed this guide for installing the kernel modules for the PiTFT 2.8 support. I wanted to use pygame and have support for the touchscreen, so I followed this guide to ensure the SDL version underneath pygame would support the screen (apparently needs to be SDL 1.2, there are reports of issues with SDL 2.0). I wrote a simple pygame app to test the touchscreen and test pre-installed gpio-connected buttons that came with the screen. I added a line at the top of the script before pygame.init() to ensure the SDL output was set to the framebuffer:

os.putenv('SDL_FBDEV', '/dev/fb1')

The touchscreen was working great, and very conveniently linked straight into the mouse drivers, such that touches come up as mouse click events in pygame. I added these lines in to get this happening:

os.putenv('SDL_MOUSEDRV', 'TSLIB')
os.putenv('SDL_MOUSEDEV', '/dev/input/touchscreen')

I used the python RPi.GPIO package, that came pre-insalled, to try and read button presses and at this point discovered the performance was fairly underwhelming: I was using event detection, and tried a combination of logic rules to read whether the pin was high or low, to detect short presses and long button holds, also tried playing with the bouncetime argument: all to no avail. I ended up realising that Adafruit had actually written a really nice c-based daemon, "Adafruit-Retrogame" which would map gpio events to key strokes: exactly what I wanted! And it worked perfectly: configured it to the keys I wanted, compiled it and added it to /etc/rc.local to run in the background on boot up.

Wireless: I setup my RPi to connect automatically to my wireless access point using this guide. I really wanted to get wireless working, as I knew from the case shell I wanted, it would be hard to feed one of the USB ports to the side for a keyboard or usb drive etc. (the other alternative for debugging would be a Bluetooth keyboard, but I still also wanted to be able to copy games on/off the device). I found the wireless would drop out constantly: turned off the pre-installed wireless power management: single line "sudo iwconfig wlan0 power off" added to /etc/rc.local to turn off every time on boot: wireless then working perfectly.

The last thing I did was to test the performance of one of my previous pyweek entries to see how it would go on the pi. The first thing I noticed was considerable audio lag for sounds (music was ok, but sounds would play at least 300-400 ms after being triggered) ... Found out I could fix this by reducing the buffer size using the following pre initialisation line in all python/pygame code:

pygame.mixer.pre_init(44100,-16,1,512)

More details on this here. The game was set to run at 30 fps, but I was only getting about 22-23 fps and the graphics were pretty choppy. I tweaked the PiTFT frame rate and SPI frequency by editing the settings in /boot/config.txt editing the relevant line to:

dtoverlay=pitft28r,rotate=90,speed=42000000,fps=30

After a bit of experimentation, these settings seemed the best balance for a not too choppy graphics and enough CPU left over to run the game smoothly.

Now that the Pi was setup, it was time to start putting all the hardware together!

No comments:

Post a Comment