Yet another pi zero retro handheld game console.
To make the experience fit your profile, pick a username and tell us what interests you.
We found and based on your interests.
The PCB for the power button arrived some time ago, and recently the last of the parts made it into my mailbox — the pair of mosfets in a single package. So I went and assembled everything, and powered it up, and what do you know, it didn't release blue smoke. But it also didn't work — it was always on. So I went through the schematic again, and then asked on the hack chat channel for help. Rubber-ducking helped and I noticed that I have swapped the P and N mosfets in my design. Ugh. I also tried the PCB on the zero, and turns out it doesn't fit quite right — the HDMI socket is a little bigger than I thought and needs a deeper cut out. So here's a new version of the PCB:
Hopefully that one will work better.
The second version of the PCB arrived some time ago already, but I was struggling with the ways to power the raspberry pi and didn't really try them. Now I confirmed that the new layout of the buttons works perfectly fine with just the device tree overlay. I didn't test the memory for storing that overlay yet — there will be a separate update log for that.
I assembled all three of the PCBs I got from OSHPark this time, and with the second display I used a low-profile female header, instead of soldering the module's pins directly into the board — so now I can unplug the display. I also experimented with two kinds of switches: the standard through-hole clicky switches, and a weird SMD switch with very soft and springy action. I'm not yet entirely sure which ones I like better, to be honest.
Oh, and I still didn't try the audio amplifier either.
Either way, the PCBs work, they mostly use through-hole components for the basic functionality (minus the sound and the memory), and you can order them from OSHPark here: https://oshpark.com/projects/TfXEKJ7T
Independently from hacking the LiFePO4 power module, I decided to try and make a small module with a soft power button on it — the same I linked two logs ago. I will use a thin PCB, so that it can be inserted between shields.
The schematic is based on several designs from various forums — I'm not smart enough to figure it out myself. Pressing the button switches the power on and latches it. Subsequent pressing of the button does noting, except pulling the GPIO4 down to let the Raspberry Pi know that we want to shut down. A long press (or pulling the GPIO4 low) forces it off.
It's a little bit more complex than I'm comfortable with, but we will see how well it works.
Both the new PCB and the #LiFePO4wered/Pi arrived while I was away, so I can now get back to hacking. But what is this? It's too long for the the Raspberry Pi Zero, as it was originally designed for the Raspberry Pi B, which is a little bit longer. But fear not, I anticipated that problem and ordered a smaller LiFePO4 battery, that should be just the right size. Now it's just a matter of replacement of the battery basket:
I guess I will need to cut that PCB a little bit too. Oh well. I also removed the female headers from the power module, in order to solder it flat on top of the hat. Unfortunately, there is one pesky SMD resistor getting in the way there, so it won't be completely flat.
In other news, I'm really happy with the through-hole buttons, they are much easier to solder and fit in that tight space -- although I didn't find color ones.
I still need to get a display for this -- either order another one, or desolder one from the first prototype.
The ZeroLiPO module doesn't work very well with this power-hungry display. Adding a big capacitor across the power helped somewhat, but you can still see problems when the display has a lot of white to show.
For now I'm just powering the whole thing from a 1S LiPO battery directly, without any boost converter or other circuit. That works well, due to reasons described in this project log, and I'm actually quite happy with this. However, there is no overdischarge protection, and I need to manually switch the power off after the raspberry pi shuts down – there should be a better way to do it.
So I started looking around for a ready module for that – what can I say, I'm lazy – and was quite surprised that I couldn't find anything like that. OK, fine, I will just have to build my own. I looked around a bit for similar projects to steal from, and found this one: http://www.mosaic-industries.com/embedded-systems/microcontroller-projects/raspberry-pi/on-off-power-controller – it's a very nice schematic, and it only uses one GPIO pin to both signal the pi to shutdown, and see when it finished. I might still make this, because it's generally useful, but for now I have a better idea.
That project log I linked, it's for a project that exactly fits my needs. And that project is available to buy on Tindie. It's a battery, a charger, a touch pad button for switching it on and off, and I2C for battery monitoring and low power shutdown. It does everything I need. I will probably try to put a smaller battery in it, so that it fits the size of the pi zero better, but that's it.
After a bit of research and experimenting, I can now conclude that my initial PCB design has a number of flaws, namely:
I decided to fix those flaws in a second revision of the PCB, and in also to add an EEPROM chip that will store the pin configuration and the device tree overlays necessary to use this board. In other words, I'm turning this into a proper HAT.
Here's the second version of the PCB so far:
You can see that I moved the audio filters, so that they are together, and there is a header for their output -- that's where the amplifier board will go. There are no footprints for the speakers -- they will also go on the amplifier board. There is a resistor next to the L2 button, because the BCM6 pin can go high on the old Raspberry Pi versions during the boot, and we don't want to have a short when the user happens to be holding that button down. There is an EEPROM chip with its pull-up resistors for I2C, as specified in the HAT design guide. Oh, and I switched to using through-hole buttons, because they actually use less space on the board, and will be easier to solder.
I also took the time to actually draw a proper schematic:
Then I wrote the overlay file for this board, which goes something like this:
/dts-v1/; /plugin/; / { compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; fragment@0 { target = <&gpio>; __overlay__ { pinctrl-names = "default"; pinctrl-0 = <&pwm_audio_pins>; pwm_audio_pins: pwm_audio_pins { brcm,pins = <12 13>; // gpio no ('BCM' number) brcm,function = <4 4>; // 0:in, 1:out, 2: alt5, 3: alt4, 4: alt0, 5: alt1, 6: alt2, 7: alt3 brcm,pull = <0 0>; // 2:up 1:down 0:none }; keypad_pins: keypad_pins { brcm,pins = <20 26 21 19 5 23 18 17 16 6 22 27>; brcm,function = < 0 0 0 0 0 0 0 0 0 0 0 0>; // in brcm,pull = < 2 2 2 2 2 2 2 2 2 2 2 2>; // up }; oled_pins: oled_pins { brcm,pins = <24 25>; brcm,function = <1 1>; brcm,pull = <0 0>; }; }; }; fragment@1 { target = <&soc>; __overlay__ { keypad: keypad { compatible = "gpio-keys"; pinctrl-names = "default"; pinctrl-0 = <&keypad_pins>; #address-cells = <1>; #size-cells = <0>; button@20 { label = "up"; linux,code = <103>; // KEY_UP gpios = <&gpio 20 1>; }; button@26 { label = "down"; linux,code = <108>; // KEY_DOWN gpios = <&gpio 26 1>; }; button@21 { label = "left"; linux,code = <105>; // KEY_LEFT gpios = <&gpio 21 1>; }; button@19 { label = "right"; linux,code = <106>; // KEY_RIGHT gpios = <&gpio 19 1>; }; button@5 { label = "X"; linux,code = <45>; // KEY_X gpios = <&gpio 5 1>; }; button@23 { label = "Z"; linux,code = <44>; // KEY_Z gpios = <&gpio 23 1>; }; button@18 { label = "R1"; linux,code = <30>; // KEY_A gpios = <&gpio 18 1>; }; button@17 { label = "R2"; linux,code = <31>; // KEY_S gpios = <&gpio 17 1>; }; button@16 { label = "L1"; linux,code = <32>; // KEY_D gpios = <&gpio 16 1>; }; button@6 { label = "L2"; linux,code = <33>; // KEY_F gpios = <&gpio 6 1>; }; button@22 { label = "start"; linux,code = <28>; // KEY_ENTER gpios = <&gpio 22 1>; }; button@27 { label = "select"; linux,code = <57>; // KEY_SPACE gpios = <&gpio 27 1>; }; }; }; }; fragment@2 { target = <&spi0>; __overlay__ { status = "okay"; #address-cells = <1>; #size-cells = <0>; spidev@0{ status = "disabled"; }; spidev@1{ status = "disabled"; }; oled_display: oled_display@0{ compatible = "ssd,fb_ssd1351"; ...Read more »
Leaving the struggles with device tree overlays on the side for a moment, I decided to try and get the audio to work. When designing the board, I followed instructions by Adafruit on how to get PWM Audio on the Pi Zero. Except that instead of headphones I have two tiny SMD speakers in there.
Of course the device tree method didn't work -- results in a Segmentation Fault as soon as audio is used. Poking around a bit, I found this tutorial that lets you do it by only editing the config.txt, without your own overlay, and this worked: https://www.raspberrypi.org/forums/viewtopic.php?f=38&t=168084
Of course, without an amplifier I expect the sound to be very quiet. It is in fact barely audible. What's worse, the noise from the display, and the noise from the display signal induced in the speaker, are orders of magnitude louder!
I think I will either need an amplifier module for this, or just give up on the sound. For now I ordered an amplifier and will see how it will work.
A quick PCB surgery, and I cut the trace from near the pin 1 of the pi connector from display's vcc, and connected that to the nearby 5V connector that I left there for power. That solved the weird behavior of the display and the restarts, but it's still making chirping noises. The images below show the changes:
In other news, I managed to move the whole configuration of the display into an overlay, and also got the keys work with gpio-keys driver -- except one of the fire buttons, which uses gpio 7, and which is a second CS pin for the SPI controller. The SPI driver just won't give that pin up.
I already started designing second version of the PCB that would use other pins -- tested working -- but I'm still not entirely sure if I'm going to be ordering that. De-soldering this display now would be a little tricky without hot air. I guess it all depends on whether there are more mistakes to be found in the audio system, which I didn't test yet.
I'm also still thinking about bet option for powering this. Right now I'm leaning towards a flat lipo sandwitched between the two boards, because that would be small, but it's really getting hot in there, so I'm not sure.
As I'm getting more of it to work and testing with Pico8, I'm starting to see that I have a serious problem with the display. As soon as there are white vertical lines on it, it starts making high-pitched noises and do "tv noise" for some frames, and then the whole Raspberry Pi hangs.
Looking at the schematic, I think I made a big mistake connecting the display's power to pi's 3.3V pin. Sure, the display can run both on 3.3V and 5V, and since there is no communication from the display to the pi, there is no problem with voltage incompatibility. I suspect that this display takes a bit too much juice for the pi's regulator.
The solution? I will try to un-solder the VCC pin of the display, and use a wire to connect it to the 5V pins. We will see how that works. One downside is that won't look so good anymore.
If that doesn't help, there is one more possibility -- the display drivers in the kernel may be simply buggy, sending to the display some weird commands that trip it up.
Pretty much every GPIO pin not used for the display or audio is used for the buttons. I decided to make it simple and just use a separate pin for every button. The list looks like this:
In addition, pins 13 and 18 are used for audio, and pins 8, 10, 11, 24, 25 are used by the display. I didn't plan the pins for the keys too much -- I just connected whatever was closest to the physical button. That means that, for example, L1 is using the same pin as the ZeroLiPO module uses to signal shutdown... but I think I can move that.
In any case, initially I planned to use Adafruit's RetroGame daemon that constantly polls the pins and then generates keypress events. But someone on the #raspberrypi channel on Freenode suggested that I can use Device Tree Overlays instead. I got interested and decided to try it.
As with all the Linux Kernel stuff, there is practically no documentation, you have to read the source code. Fortunately I found a pretty nice example for configuring a GPIO keyboard. I tested it on a few of my keys, and it worked great! Awesome, that was easier than expected! I quickly added the rest of my keys to the overlay file, compiled it and restarted, expecting it to work. Of course it didn't. Checking dmesg let me see error messages suggesting that the kernel driver can't claim pins 7 and 20, because they are being used by the SPI peripheral. Of course I can't disable SPI, because that's how my display is connected. But I'm not using all those pins. How can I tell the driver that?
After a few hours of searching the Internet, trawling through source files, trying various things, etc. I finally realized that I'm wasting my time. I just deleted all this overlay nonsense, installed the Adafruit demon, configured it quickly and that's it. Somehow the demon doesn't have any problems with any pins being used by something else.
But there is one more thing I learned, which might make me re-thing the pin mapping and actually try to get this to work. Apparently Pi HATs can have on them a small EEPROM memory chip, to which we can record the overlays that this shield needs. That means that with a little work (and fixing some bugs in the kernel, I'm sure), it would be possible to build a shield that would require no manual configuration: just connect it switch it on, and it just works. That would be great, *if* it worked.
Create an account to leave a comment. Already have an account? Log In.
It is published on OSHPark (https://oshpark.com/shared_projects/TfXEKJ7T), but I would recommend taking a look around here and Tindie a bit for better pi zero-based consoles.
It's always nice to see your projects.
You are the one that gave me the desire to start to solder SMD components.
I'm currently waiting for last components to assemble a BasicEngine, then it will be one of your projects :)
I'm really happy to hear that! Don't hesitate to ask about anything.
As soon as I'm ready to start on one of your project, you'll hear me asking components values for example here.
love it!!! Glad to be of inspiration :) I do have one of those modules on the boat from china. I love the OLED for its vibrancy and viewing angles, but like you said, the extra bits are a pain.
I did find an OLED that actually has the boost circuit in its ribbon, but they are super expensive, the driver isnt available for fbtft, and they are 128x160 - http://uk.rs-online.com/web/p/oled-displays/6686142/
PS, i LOVE the swiss cheese holes!!
Writing a driver is not such a big problem. I think you can even use the existing driver and provide a custom initialization sequence. And it's not really more expensive than the module I used. And the extra resolution would be handy, you could play gameboy games on it without squashing -- meaning the RPG games would have readable text. Hmm...
yeah the driver is probably very similar to the one you are using. you can get the bare SSD1351 screens for $10 a piece on aliexpress, probably less if you buy in bulk.
adafruit are pretty good at giving schematics. if i fall in love with the OLED when it arrives (im sure i will) i think i will transplant OLED into TinyPi using this
Become a member to follow this project and never miss any updates
Can I buy this PCBs anywhere?