The #µGame project works much better than I expected, and I'm going to keep working on it. However, it also showed its limitations, mainly in terms of available memory.
This project's goal is to find a solution that would let me build a µGame-compatible device, with all the good parts kept (easy access to the filesystem, WAV sounds, small size, reasonable price), but with additional improvements (more memory, better speaker, larger screen, more convenient layout).
At the moment it's a research project — don't expect a new device any time soon, this is going to take at least six months if not longer, and might actually never be finished, if it turns out the improvements are not worth it.
While still waiting for parts, I'm going to think about connectivity a little bit. This is something that I almost completely ignored in #µGame, and only at the end added a small header with four pins that I had free. Due to routing difficulties, that header is right in the middle of the PCB, normally under the battery, and so not very useful. Oh, there is also a debugging interface broken out, but that's also of limited use.
This time I want to do better. The SAMD51 has much more pins that will remain free, so it makes sense to break them out on a header somewhere on the edge of the PCB. If I also break out all the pins that are used for buttons, that would make it possible to connected external controllers to it.
Another option I'm considering is to use Seeedstudio's "grove" connectors, at least for some I2C/UART pins. This standard seems to be getting popular, and it would make it easy to connect additional sensors.
If I end up using one of the ESP chips, I will have wireless connectivity for free — even though it's a bit tricky to use. Writing some libraries for simplifying communication for games seems like good idea then.
Even with the SAMD51, I might want to add an IR LED and sensor. That would allow for some multiplayer games, and maybe things like trading. Plus, it could double as a TV-be-gone then.
I'm not planning on any kind of SD cards or flash cartridges, even though the software supports it. Somehow I always preferred to have all the games in one place, with a menu to select them.
If you have read the very first log on this project, you know that I'm considering at least three different microcontrollers for this version of µGame. While I have already tested the ESP8266 option briefly, and I'm still waiting for an ESP32 devboard I want to use, there currently are very few options for testing SAMD51. Thanks to the generosity of Adafruit I have an early Metro M4 board, but I want to test with a little bit bare bones setup. There was a mouser order being made, so I decided to order two ATSAMD51J20AAU chips — the smallest package that has 256kB RAM.
The original #µGame is surprisingly good mechanically, given its small size of only 42×50mm. The width is dictated by the screen size (and it being asymmetrical), and the height is dictated by the size limit for cheap PCBs. The buttons are spaced as far apart as possible. The layout is well known from Gameboy and similar devices, and I didn't really have much choice at this size and with this screen.
For µGame Turbo I want to try the PSP/DS/Switch layout, with the buttons on the sides of the screen. Since the PCB will need to be bigger than 50mm anyways, due to the screen size, I can as well make the whole thing easier to hold. Here's a mockup:
As you can see, I want to use the same buttons — ALPS SKPMAPE010 — as they have a very nice, soft feel, and are quiet. I will also still try to fit all the components on the same side of the PCB, to make the assembly easier and cheaper. That means that the USB and Audio sockets have to be on the bottom edge of the board, next to the display on either side. The audio components, including the volume control, will then sit under the fire buttons, and the microcontroller — under the d-pad. The power switch might go anywhere, but probably on the right edge.
The number of buttons will remain the same, for compatibility reasons. I considered adding additional buttons, but I'm not really sure they would really add to the games, and they would make it impossible to play the µGame Turbo games on the µGame, which would be a shame for everyone who already have the µGame.
I want to add a header of pads on the top back of the console, with some ports exposed for possible tinkering or extensions. The battery will either go on the back, like in µGame, or under the display — which would allow the back to remain clear. The mounting holes are going to have plenty of room around them, this time.
Audio is the least researched part of this project, and it will probably take the most work. The original #µGame has a tiny 4mm speaker connected through a PAM8301 amplifier directly to the DAC pin of the SAMD21. CircuitPython has an audioio module that is capable of playing .wav files directly from the disk in the background. The quality is not great, but enough to distinguish a "pewpew" from a "boom".
Now I would like to have some improvements. For starters, I want volume control (with the ability to mute the sound completely), and a headphone jack. A bigger speaker would be nice for better sound quality.
Next, depending on the microcontroller used, I might be needing some kind of a low-pass filter to convert PWM to sound, and a proper library to generate the PWM from .wav files in the background. I might even be forced to use an external chip for this (such as VS1053B or some MP3-player chip).
Then there is the question of adding a second channel — for background music. Not sure how that would be done, and it would depend on the chosen microcontroller a lot too. Maybe a separate chip again? Originally I was planning to have a separate chip in there to do the buttons and sound, I might need to revisit this idea (especially if I'm going to need a 32u4 for the USB for ESP chips anyways).
The µGame used the cheapest color display available on the market, the 128×128 1.44" version of ST7735. It large enough pixels to be clearly visible and for the pixelart to make sense, but is small enough to fit on a pocket device. Sadly, it doesn't have hardware scrolling, and the 1.44" is actually a little bit too small, especially for older people. It works with up to 40MHz SPI. What are the alternatives?
The SSD1351 has the same resolution and size, but is an OLED display — meaning battery savings and better contrast and viewing angles. I used in in #Ye Olde Nowt with some success. However, it requires extra electronics for the high-voltage power for the LEDs — I'm a bit afraid of that, since so far I have only ever used it on a ready module. It's also pretty expensive — just the display easily the price of the whole µGame.
The ILI9341 is the second most popular and also second cheapest display around. It's 320×240 and usually comes in 2.2" and 2.4" versions (but even as large as 2.8" versions exist). Like the ST7735 it works with 40MHz SPI, though there are much more pixels to transfer. It has hardware scrolling, but only in the long axis — so I guess a Mario clone would be possible, but not River Raid. The pixels are really tiny at this resolution, so unless I upscale it to 2×2, pixelart will be hard to appreciate.
I could use the 160x128 1.8" version of the ST7735 module. It is a little bit bigger overall, with larger pixels, and in compatibility mode with µGame I could display status (battery, etc) in the extra space.
There is also the HX8353D, which on the first sight looks like the 1.8" ST7735, but has hardware scrolling like the ILI9341 (in the long dimension only, again). It seems equally cheap, but not as popular, though I suspect that many displays sold as ST7735 are actually HX8353Ds. The ILI9163 seems to be another compatible chip from this family. They also have a 1.77" version.
The HX8340 (or ILI9225G) is actually interesting. At 220×176 resolution it could fit a gameboy emulator with just a small frame around the picture (gameboy is 160x144), and at 2.2" is actually pretty large. It also has hardware scrolling in one dimension. It seems to be a bit tricky to source, though.
All of those displays also come in versions with the parallel protocol pins broken out, so I could try to get that to work — which would possibly result in considerable speedup of the refresh rate, and make software scrolling possible.
Are there any other cheap, easy to source, color displays with relatively big pixels out there?
Update: looks like the "hardware scrolling" is not really what I hoped — it basically adds an offset to data being written to the display, so you would still need to refresh the whole display to get scrolling. Disappointing.
The µGame uses a SAMD21 microcontroller, with 32kB of RAM, running at 48MHz, and uses 24MHz SPI to send data to the screen. What we need is more RAM and faster screen communication.
There are several possibilities for that:
The new SAMD51 microcontroller is a big brother of the SAMD21. It still runs at the same 48MHz, but is faster due to richer architecture (floating point support, etc.). More importantly, it has up to 256kB of RAM and can do at least the same speed of SPI communication, possibly better (the display stops working above 40MHz anyways). Adafruit is working hard on a port of CircuitPython for it — it will have at least the same features, if not more. It is about twice as expensive.
The good old ESP8266 actually packs quite a punch. Running at 80MHz, it can do 80MHz SPI communication — more than the limit of the display. It has ~90kB of RAM, but the layout is a bit strange and not all of that is usable for the programs. It also has WiFi, which is an interesting thing for multiplayer games. There is a port of CircuitPython for it, but it's not as stable and finished as the SAMD21 one — it lacks some love. The main problem, however, is lack of audio support in CircuitPython, and lack of USB access to the filesystem. The latter can be fixed with something like #ESP8266 with True USB, the former would need some development, possibly porting NodeMCU's PCM suport.
Two cores at 240MHz, 520kB of RAM, very fast SPI, WiFi and BLE, and not very expensive. Has the same problems as ESP8266, though, with the additional complication that there is no CircuitPython for it as of yet, and the two MicroPython ports are still in beta.
I'm sure there are tons of other microcontrollers that could be used for this. However, they would all require considerable effort in porting CircuitPython, getting USB to work, etc. — so they are out of consideration for now.
The SPI speed is also not a very important parameter, as at this point it would make much more sense to use the display in parallel communication mode — of course that requires new special drivers and more research.