A few months ago we posted about writing a Flappy Bird running on an Arduino, and displaying on a max7219 8x8 led matrix. We thought it as so much fun that we followed up and wrote Space Invaders, Lunar Lander, Breakout, Snake and Defender. Code for all of these is in the current Sniff release examples.
We liked it so much we decided that we needed to build some kind of handheld game console to run these that we could use as the basis of workshops. We wanted kids to be able to come in, and build their own then write a game to run on it.
What followed was a few months of intense design work. What's left is something that (as J Ive would say) looks effortless... its a very basic "obvious" design, but every aspect was deliberated over. Here are just some of the design issues we grappled with:
An Arduino Uno was used for the original tests, but for a while we intended to swap it out for a Nano. These are functionally identical, but smaller. We also found a screw terminal board for the Nano which in theory would make it simple to attach components semi-permanently to the board. However when we actually tried to assemble a system based on the Nano, we found the screw terminals incredibly fiddly to work with, and something we wouldn't inflict on kids! (We do use screw terminals to connect motors in our robot workshops, but they're a bit larger). With that tested and rejected we went back to the Uno!
One of the things we learned from writing games on the red matrix was that 8x8 pixels was actually a really great size to code games on. The Arduino can handle it easily and you don't need to worry about performance. There's also something really pure about these games - there's no artwork or other asset creation. They're 100% game mechanic. However we did find that it was sometimes hard to know what each pixel was supposed to be - one red dot looked a lot like every other!
That could be solved by adding colour support, and we recently posted out findings from testing every 8x8 matrix we could get our hands on. Our favourite was the bi-colour red/green display using the tm1640 driver. These are a bit hard to find, but they give just enough colour at a price and size that we liked. The next step up would be a neoPixel solution, which was just a fraction above our budget. The cost needs to be sufficiently low that every student gets to take one home, without costing us a fortune.
The original design had several different control configurations. We quickly got a design with a thumbstick and a button, but when we started refining it into something we could make, we couldn't find a nice button that didn't cost more than the thumbstick, and the thumbstick includes a button. We then briefly considered the idea of two joysticks - one basically replacing the button. This would have been fun, even allowing for two plays games, but it proved impossible to lay out the components in a way that would be a comfortable size and shape to hold. In any case it was just too complicated, so we simplified and just went with a single thumbstick and its built in button.
One slight niggle is that the switch in the thumbstick connects the output to 0v when the button is pressed, otherwise its open circuit. Negative logic is needlessly confusing for kids (the pin turns OFF when its pressed!), but the alternative of wiring the power to it in reverse (which would work!) is also pretty nasty. We also needed to add a pull-up resistor - its easier to solder an extra resistor to the board so that it just works, rather than to explain pullups in a workshop context.
We used a buzzer so that you can just set it to "on" to get a sound. As an alternative you could use a speaker, so that you need to send a square wave to it, but we just need a few beeps. Just having the thing beep when something happens makes a big difference to the feeling of playing a game, and while we could do more, as with the controls we were happy to go with something simpler.
In the initial design we were going to use AA batteries - Probably 3 of them connected directly to the Arduino's power bus. However then we'd need to worry about getting the right polarity, having some kind of power switch, and it was difficult to find a layout for the case which would hold batteries. We also considered using a USB power pack - the sort that are meant for recharging your phone when it goes flat, and you're away from home. These work great and are very cheap, so we will probably bring some along to the workshop, but in the interested of simplicity we decided to stop short of building a power supply into the design. We can power via the USB port - not exactly portable, but you can always use an external USB battery.
Physical AssemblyA big part of this project is that we wanted something that was relatively solid and robust, while still being "made". We spent hours trying to work out how to juggle all the parts into something that would feel right, and many of the decisions made for the components were influenced by whether we could put them together and lay them out nicely (and cost effectively).
The easiest way to construct a custom case was from two layers of 3mm acrylic - a base to hold everything and a top layer to protect it (we did consider some designs with three layers but again it added to complexity). The base could be coloured, but top clear so that the screen could be underneath it. We included mounting holes for that Arduino, as it has a well defined spec, but the rest of the components are attached with double sided foam tape. This is easily strong enough to hold everything in place and avoids the problem that the screen lacks any mounting holes, and each batch of joysticks we buy has the holes in different places!
The final piece of the puzzle was making it as easy as possible to wire all of this up in a way that would be easy to do in a workshop, but still relatively robust. The Uno isn't really designed for this as is has female headers. Male header pins, and female jumper cables are much stronger than female headers, and male jumpers.
The screen requires 0v, 5v, plus two data pins, and comes with female jumper cables. Our first trick is to attach these to the Arduinos ICSP pins!
The cluster of six pins at the end of the Uno (that you probably never use) can be used to program the board, but they're actually just pins D11, D12, and D13 broken out. We chose to use pins 11 and 12 to attach the screen so that we could connect them here rather than in the usual female headers.
The added bonus is that not only are they stronger, and use the supplied cable, but they're lower than the regular headers, so this makes the whole device thinner. This is important if we mount the joystick on the base plate and poke it through a hole in the top plate.
Unfortunatly the Uno doesn't have any other male headers so we need to get really creative... We took a sheet of strip board 9 strips wide, and soldered two sets of 4 straight pins and two sets of 4 angled pins on to it.
The straight pins will fit perfectly into the analog and misc/power headers, with the angle pins pointing inwards and down so they take up no extra space. Then we can easily attach female jumper cables to them, making a simple, secure and low profile connection.
The joystick connects to A0,A1,A2 0v and 5v, leaving a spare 0v and A3 to connect the speaker to! The joystick can use a regular strip of female jumper cables so the only soldering we have to do is to make up the angle connector, and solder some headers onto the speaker. This is a big deal when you have to make up a batch of components before a workshop!
With everything mounted and connected we just have to attach the top sheet of acrylic using spacers and we're good to go! We used 25mm spacers for the prototype, but that leaves plenty of space, and we're using 22mm for the next batch (20mm would probably be OK too!).
And here it is...
After an innuendo packed brainstorming session we completed the project by picking a name for our creation. We've named it the Sniff 64, or S64 for short. After all it does have 64 pixels.
Code to run on it is included in the examples/Embedded/maxGamer folder in the current release. The code should be set up for the "official" hardware, but if you want to run it on a different screen you should just have to change the first few lines of code.
We put Snake on it and left it "lying around" near some kids, and it proved very popular.
If you'd like to build on then the details here should make it pretty easy to put one together yourself. The only "tricky" part is getting the acrylic cut - if you've got access to a laser cutter, then its pretty easy (I'll post the DXF here once its final-final, or get in touch). Otherwise you can just mount it to any single sheet, and forgo the top layer, or get creative see what you can come up with.