Wednesday, December 21, 2016

3D Printed Nintendo Christmas Tree Decorations


Following on from my last 3D print, and to celebrate the recent release of the NES Classic Edition Console, I made some 3D printed Nintendo character Christmas tree ornaments. The sprite art is taken from Nintendo Entertainment Systems games The Legend of Zelda (Link), Metroid (Samus), Super Mario Bros. 3 (Mario) and Kirby's Adventure (Kirby).


I made the models using OpenSCAD and by importing in arrays that contained the pixel values. I then created a separate 3D object for each colour set, matching up the colours to the available colours of filament I had. Like in my previous multi-colour print, I made the pixels 2 mm squares, but subtracted a small buffer in size of 0.25 mm for edges that adjoin onto different colours. Because some of the sprites were kind of complicated, and I didn't feel like having to glue any pieces, I designed a black border around the sprites, so everything would be nice and self contained and just snap into place. It took a fair bit of time to put them all together, but it was kinda fun, like doing a jigsaw puzzle.


You can download all the stl files here: Nintendo Christmas Tree Decorations (Thingiverse)

Merry Christmas!

Sunday, December 18, 2016

Procedurally Generated Island Overworld Map


I've had a mild interest in procedurally generated worlds for video games for a while now. I recently found this article by Amit Patel from Red Blob Games on building procedurally-generated game worlds using randomized voronoi diagrams and a graph-based approach to defining spatial attributes. I had played a bit previously using Perlin noise to define world elevations, and then basing spatial attributes on elevation contours, which is cool but always ends up with pretty random, unrealistic looking landscapes. This graph-based approach seemed to provide a bit more flexibility in how the landscape looked and how to add additional objects into the world (like rivers, roads etc) in a way that seemed to provide a bit more control. I also found this 8x8 pixel micro tileset, which sparked my interest to try and build up a random island overworld generator, based on the tiles here.

I wanted to generate landscapes that could form the overworld of an adventure style game. Basically something where the player has a constrained world to explore that contains a variety of different biomes (provided by the tileset), villages, roads and locations representing the entrance to caves or dungeons that would form the basis of the objective of the game (enter caves, defeat monsters, recover treasure etc).


Working in python, I started by defining random points in a 2D space using stratified random sampling, to make sure points were not too 'clumpy'. Instead of using voronoi diagrams to generate polygons, I went straight to using a Delaunay triangulation to define the local connectivity of points (using this nice pure-python implementation). The triangulations would later be used to rasterise landscape tiles and define paths and distances between locations. Following from Amit's approach, I created a series of points regularly spaced around the border of the map and defined them as water. I then selected a fixed number of the other random points and defined them as land. I then performed flood fills along the triangulated network to define all remaining points as land or water based on whichever predefined node is closest. I then incremented through triangles, and those that contained a majority of land nodes were rasterised into land tiles, where the remaining tiles were labelled as water/ocean.

This gave me a bulk of land surrounded by water, usually as one island but some times split into two. Each node on land is then labelled by it's distance to the closest water/ocean node, which helps define what type of tile is used (light/dark grass, light/dark dirt) and the probability it will be occupied by a trees or mountains. I then added a few lakes by defining random starting locations on land and seeded some water patches using region growing. I added some villages: one that appears on a random mountain tile, one in a forest (distance layer with probability of tree being 1.0) and two on the coast (distance to water less than one edge on the triangulated network). I then finally drew roads between the mountain village and the forest village and biggest coastal village using A* paths along the triangulated network.


The micro tileset has tiles for a temperate landscape and for mid-winter, as well as one devoid of trees (like a desert or devastated terrain). Originally I had wanted to integrate all of them into one map with different biomes, but they didn't really look that good together. So in the end I decided to make the rendering of the map seasonal, so for every map there is one rendering for summer and one for winter. For the winter rendering I also add in a few icebergs in the surrounding waters.

I'm not sure exactly what I'm going to do with this yet, but I'll probably end up expanding upon it to make an adventure game. I was thinking about also making a random dungeon generator that utilises the dungeon portion of the micro tileset.

For now, source code available here: mit-mit-randomprojectlab/RandomOverworldGenerator

Saturday, December 17, 2016

Random 3D Printing Projects


Thinkspace had a 24 hour 3D design and printing competition a few months ago for which the design brief/theme was jewellery. I only had a hour or two to spare so I did up a quick puzzle ring: its designed to be printed in four separate parts, in four separate colours, each a little ring with tabs that click into each other. The tabs are positioned so there is a unique way of arranging the pieces (like a puzzle). It's not that hard to solve or anything. I made it in OpenSCAD. It's pretty much just a series of cylinders with holes, and the tabs are just rectangular pegs and cutouts.

OpenSCAD script and stl model files available here.

Working on this design got me excited about making 3D prints that could be put together from multiple parts printed in different colours, so I played with this idea a bit more. I made a little pixel art model of Link holding up the triforce from the original NES Legend of Zelda. It's a cool sprite because it's a small number of pixels and only requires three colours. I used an OpenSCAD to build the models from an array that contained the sprite data.


Since the sprite is mostly green, I printed the green layer to have a backing that would support the rest of the design. The pieces from the orange and "skin" coloured layers sort of just snap into the remaining gaps. First time I did the print, I designed all parts to have a pixel size of 2mm. When I went to snap them in I found they wouldn't fit, as the printer seemed to have a tiny bit of 'bleed' such that a 2mm pixel that stuck out didn't exactly fit into a 2mm gap. I redesigned the parts such that any pixels that were designed to adjoin another layer were about 0.25mm smaller such that they would smoothly fit together. The resulting prints worked well, but some bits required glueing, as they otherwise would float off the side.


Continuing on the Legend of Zelda theme I made some little heart containers and Link's sword. I ended up turing them into pairs of earrings by supergluing some sterling silver earring posts and backs on the 3D prints.

The 3D parts for the earrings can be found here.

Wednesday, November 16, 2016

Electric Piano Part 2: Raspberry Pi SF2 Synth


This is a continuation of a previous post on re-building the electronics for an old, broken electric piano keyboard. After getting the keyboard working as a MIDI device, I decided to add in a Raspberry Pi to act as a synthesiser to actually generate out different instrument sounds based on the MIDI data from a Teensy which is used to read the keyboard state.

I found some good instructions here for running Fluidsynth, an open-source, command-line based synth on the Pi that uses Soundfont sf2 files. The great thing about soundfont is that I can download and pick and choose form thousands of different instruments for free in the internets, which will make for a more interesting playing experience than the simple square waves that I can generate on the Teensy. After install Fluidsynth, I connected up the MIDI/USB connection from the Teensy into a Raspberry Pi 2 model B, and ran: "fluidsynth -a alsa /usr/share/sounds/sf2/FluidR3_GM.sf2". I then put Fluidsynth into the back ground using cmd-z and ran: "aconnect 20:0 128:0" to route the MIDI input from the Teensy (client 20, port 0) to Fluidsynth (client 128, port 0 on my machine). I could now hear a standard piano instrument when playing the piano, but the sound is fairly delayed through the HDMI audio (a latency of maybe 250 ms by my guess). Tried changing audio output to headphones using "amixer cset numid=3 1", and the delay is slightly less noticeable, but the sound quality is dreadful.

A bit of digging around on the internets regarding Raspberry Pi audio quality, and I came across this, an experimental firmware update for improved headphone jack audio quality, using a different DAC interface. I ran "sudo rpi_update" (I ran it on Oct 12th) and went and added two lines to my /boot/config.txt file: "audio_pwm_mode=2" and "dtparam=audio=on", rebooted and re-tested audio. The quality improvement is very noticeable; at least through my headphones, the quality of sound is now acceptable.

I turned my attention to trying to get amplified audio out of my setup. I connected up a class D audio amp I had left over from a previous project to the 3.5mm audio jack on the RPi, powered it using the 5V out from the RPi GPIO and connected it up to a 4 ohm 2.5W speaker that was inside the original piano keyboard. After configuring the RPi audio volume to 80% using "amixer cset numid=1 -- 80%" I was getting a reasonable sound coming out when playing. I ramped up the volume to 100% on the gain pot on the amplifier and played again: now quite loud and a little bit distorted. When I power cycled the RPi I was getting a fairly loud popping sound coming from the speaker, and also when the RPi booted up again. When I had the volume up to max I was getting a little lightning bolt brown out warning coming up on my screen too ... I decided to tune the volume down to a slightly more modest level of 80% again. Didn't notice the brown out issues again. I added a pot to the signal line coming out of the RPi and into the amplifier for volume control.


I did a bit of configuring in my /etc/rc.local file on the Pi to start everything up automatically:

amixer cset numid=3 1
amixer cset numid=1 -- 80%
fluidsynth -s -i -a alsa -z 256 -c 6 -f fs_config.txt /usr/share/sounds/sf2/FluidR3_GM.sf2
sleep 10
aconnect 20:0 128:0

The -c and -z flags are for controlling audio buffer sizes and number of buffers in fluidsynth/alsa: setting these I'm able to find an acceptable middle ground between low latency and infrequency of audio stuttering: I still sometimes get a little bit of stutter on instruments with complex, long lasting waveforms, but the latency is now at an acceptable level (I haven't figured out yet how to measure it precisely, but I mean from a playing/responsive feel perspective). I also setup a configuration file for Fluidsynth so I can automatically set the instruments for different channels (fs_config.txt).

Next thing I'm going to do is add some more controls onto the Teensy and then package the whole thing up in a new custom designed case. Stay tuned!

Tuesday, October 25, 2016

Chameleon Softie


I stumbled upon this light colour sensor while trawling around the Internets, and got the idea of using it to build a softie that would change its colour based on what it sensed around it (like a chameleon). This colour sensor uses four different photosensitive sensing elements with different band pass filters for sensing the proportions of red, green, blue and clear (visible?) light. It also has a white LED on board that can be used to illuminate a target surface that sits close to the sensor, in order to provide consistent colour readings under different ambient light conditions. I got the 'Flora' version of the sensor (3.3V only and with sewable pads), but there is also a standard breadboard breakout version of the sensor too which allows for 3.3-5V with the addition of logic level conversion, so it can be used with pretty much any Arduino or other microcontroller. The sensor uses I2C for communication with the micro.

I had a few spare Gemmas sitting around, so I wanted to use this board instead of the larger Flora (of which I had none). A bit of reading here on the Gemma pins and it looks like it's got what I need: I2C comms through pins 0 and 2, which leaves pin 1 for driving some neopixels to light up the chameleon different colours.

I downloaded the library for the colour sensor from here and a library for I2C communication on the ATTiny (micro used on the Gemma and Trinket) from here. I modified the Adafruit_TCS34725 library to use TinyWireM, instead of "Wire" (the built-in Arduino library for I2C communications on larger boards). This pretty much was just replacing every instance in the code of "Wire" with "TinyWireM", a class that provides essentially all the same functionality. I then wrote a sketch that connected to the colour sensor and to four neopixels, and in a loop would read the colour values and basically cut and paste them into the RGB values for the neopixel. The code switches on the illuminating LED on the colour sensor and leaves it on.


Initial result was that I could discern the colours of objects I put in front of the sensor, but the output was very "white", i.e. very low colour saturation values. I wrote a function that would take the RGB values and maximise the colour saturation. I started off by writing a function to first compute the hue from the RGB values, and then produce another set of RGB values of that same hue but at full saturation and value. Unfortunately, I ran out of program space ... the Gemma is super restrictive! I re-wrote the function to do things in one step: set the maximum channel to 255, minimum channel to zero, and intermediate channel scaled between 0 and 255, based on it's relative difference to the max/min values. I just managed to scrape in under the maximum program space (after shaving off a few options in the modified Adafruit_TCS34725 library), but the results were not great: the colour would sort of flick randomly: I think I was saturating the sensor and getting a lot of white signals, which would saturate to random colours.

I ended up going for a simpler solution in which I would subtract a set of calibrated values from each of the RGB channels, to try and get a more saturated output signal. I experimented with several differently coloured objects, including white paper, and tweaked the gains, until I got the desired range of colour replication.


Once I got the electronics working, I turned my attention to building and sewing the chameleon. I wanted to make it entirely out of white felt with the neopixels mounted inside and surrounded by stuffing to diffuse the light out a bit. I experimented a bit to see how close I would need to mount the neopixels from each other and how much stuffing to use to try and get the illumination from the neopixels spread out as evenly as possible. Once I had this sorted I cutout and section of felt and sewed up the Gemma and neopixels circuit using conductive thread. I designed the Gemma to sit on one eye of the chameleon, and the colour sensor on the other, such that the Gemma was accessible for turning on/off. I then designed the chameleon's outside body, cut it out of felt, and sewed it together with the nexopixel circuit. Once completed, I sewed on the colour sensor to the other eye and sewed all the conductive lines to the Gemma. I stuffed the insides with soft fill in order to puff out the chameleon and diffuse some of the light from the neopixels, such that it would look like the chameleon was sort of glowing.


The end result was OK. I had to fiddle around a lot with the calibration gains on the colour channels to get good matching for various colours. I was a bit disappointed I couldn't add more functionality to the programming ... I would have liked to have a bit more intelligence in inferring when the chameleon was moving or still, so I could decide to actively flash the white LED and get another reading, otherwise if still, just leave it off. One of the limitations of the ATTiny85 on the Gemma ... still, it's cool that its so small.

The code for the sketch is available here.

Friday, October 14, 2016

Rolling Ball Maze on Carvey


My local maker space, Thinkspace, has had a Carvey for a couple of months, and I've finally gotten around to giving it a try. I decided to make a little rolling ball maze by using Carvey to carve a 3D maze path into a piece of wood and cover it from the top using some clear acrylic.

I found some python code here for randomly generating orthogonal mazes using a simple random depth first search algorithm. I modified to code to take the resulting maze and calculate the set of 2D line segments corresponding to the inner space of the maze (what I would be carving). I then added code in the python script to output the set of lines at an SVG vector graphics file that could be read into the Carvey software Easel. SVG line segments in Easel/Carvey get treated as a single pass by the carving bit, and hence the line thickness is dictated by the thickness of the drill bit used. The largest milling bit available was 1/8 inch, and so the path of the maze was pretty narrow. I went ahead and tried it out anyway, just to see that it worked.

In order to provide mazes with a larger channel width, I tweaked my python script to also output SVG files in which each line segment was represented by a rectangle object. I tried carving a maze with a 1/4 inch channel thickness using a 1/8 inch milling bit, and results still looked good. I found some information here that explained that Easel assumes the coordinates in the SVG file during import correspond to 96 pixels per inch, and hence I scaled my maze coordinates accordingly to make the distance between channels twice the milling bit diameter, such that the maze channels and walls were equally thick.


For the finished product I added a cut out around the maze with rounded edges. I also created a second piece carved out of clear acrylic to cover the maze so that the ball doesn't fall out. For the acrylic cover, I also added four holes so that I could screw on the cover to the wood. I wanted the screws to sit flush with the acrylic surface, so each hole has one diameter that goes straight through the material and a second larger diameter hole that just goes 2 mm in, and acts as a countersunk hole. Once Carvey had finished milling out the two pieces, I placed a little silver bead inside the maze and screwed the cover on top with four screws. I also used a hand drill to put in some pilot holes for the screws: I was going to do this with Carvey, but I was using a 1/8 inch milling bit and my screw threads were smaller than this.

You can get the python script to generate your own maze including acrylic cover here: generate_carvey_ballmaze.py. Import the generated SVG files one at a time into Easel. These files assume a 1/2 inch thick piece of material for the maze and a 3 mm thick acrylic with 1/4 inch diameter screws.

Wednesday, October 12, 2016

Electric Piano Part 1: Turning an old piano into a simple synth and MIDI device


Recently, my father in law donated an old electronic piano keyboard for me and my son to play around with, an old Yamaha PSR 8 from the 1990s. When we brought it home, my son accidentally pulled off the tip of the 9V DC adaptor that came with it and when I plugged it back on I got the polarity wrong and we broke it (sad face). Yah, I know, I know ... I got lazy and thought I definitely had it the right way (who knew there was no standard for the polarity of DC power pack tips? Now I do) ... will always check with the multimeter from now on.

So I opened up the case and had a peak around. Can't see any obvious physical damage (no burnt out or broken components). Had a search online for some repair manuals for this keyboard and found a few pages, but to be honest wasn't that keen on trying to find replacements parts. So ... only one thing left to do: gut it and rebuild the electronics again from scratch!


I unscrewed and pulled away the actual keyboard assembly from the rest of the case. Had a look at the keyboard itself and contacts for keys. Running along the back of the keys is a single long PCB with contacts for each key and a bunch of diodes on it (one for each of the 49 keys) that all map back to a 15 pin connector. A bit of googling and it looks like this is a switch matrix. I found this helpful reference which seems to explain how this circuit works: keys are grouped into nine rows, each with a set of six keys (except for the last row which contains a single key), where each key in a row shares a common ground, and the first pin of each row shares a common contact on the other end of a diode, as does all the second pins etc. The state of each of the 49 keys can be read by selectively reading from 6 digital input pins while incrementally setting 9 output pins to ground one at a time.


I decided to use my Teensy 3.2, which I hadn't previously used, to do the reading of keyboard state. I installed the teensyduino add on for Arduino 1.6.11, tested out an LED blink code and got a 4 ohm speaker working with simple melody. I then got a simple, single switch working with a INPUT_PULLUP mode, all good, lighting up pin 13 LED. Then I wrote a sketch to flick back and forward between two pins, both in INPUT_PULLUP mode and to a common ground, by setting the other pin OUTPUT/HIGH while reading the other (diodes built into the keyboard to stop current pulling between pins when both keys are down). Working well.


I snipped and stripped the ribbon cable I found connected to the 15 pin connector coming off the key switch PCB, plugged it into my breadboard and connected to 15 digital pins on the Teensy. I wrote a sketch to implement a basic matrix to read out all 49 keys. I found I had to add in a 10 us delay between setting Teensy pins to INPUT_PULLUP mode and reading them (as suggested by the Teensy instructions on their website) and also found I had to add a 50us delay between subsequent reads of each key on the matrix to get things to work such that more than one key could be read at a time. Once all keys read, wrote a program to output the tone corresponding to the highest key. Basic monophonic piano implemented!

I decided to round off this design my modifying the Teensy built in tone function to produce four simultaneous tones using the 4 PIT timers available. I modified the standard Teensy tone implementation to use up to four timers simultaneously and prioritised timers to the higher keys on the piano. I used four pins each connected through a 330 ohm resistor back to the speaker and I also chucked on a potentiometer for volume control. Working fine, and I could now play polyphonic tunes pretty well (up to four simultaneous key presses). The square waves sounded pretty ordinary through the little 4 ohm/500mW speaker, so I also tried connecting the ends to an RCA co-axial cable and plugging it into an external amplifier, which was a little better.

The code for running this all can be found at:
https://github.com/mit-mit-randomprojectlab/keyboard_multitone

At this point I decided to try an alternative direction for the design: instead of doing the sound synthesis on the Teensy, what if I used an additional computer or micro to do it for me? I decided to try and get the keyboard working as a MIDI device. I changed the code to output MIDI "noteon" and "noteoff" messages on key presses and configured the teensy to output MIDI, using the options available in the Arduino IDE. The teensy library in teensyduino makes this very easy: there are a bunch of send/receive midi functions built in, no need for any additional code or external libraries.

The code for running this all can be found at:
https://github.com/mit-mit-randomprojectlab/keyboard_midi001

Once i got the keyboard working as a MIDI device, I downloaded and installed "Fluidsynth" on my macbook to read in the MIDI messages and play sounds. I used the "General User GS v1.47" font by S. Christian Collins and started up Fluidsynth from the command line using the following settings: ./fluidsynth GeneralUser_GS_v1.47.sf2  -o midi.driver="coremidi" -o audio.driver="coreaudio"
I then used a software package called "MIDI Patchbay" to patch the output from the Teensy to Fluidsynth, and voila! I can play synthesised piano through my laptop. Once in fluidsynth, I used "prog <channel> <inst>" to set different instruments.

So thus far I've managed to (a) make a simple synth (square waves) which is OK, but lets face it, my son will only find squares waves interesting for a short amount of time! and (b) make a MIDI keyboard, which can play all sorts of cool sounds, but only when connected to and setup on my laptop, so my son can't really go and turn it on and play himself. I am going to try and keep going down both design routes and (a) get a synth working on the teensy that can play a wider variety of tones/waveforms and (b) try connecting the MIDI keyboard up to a dedicated raspberry pi for doing the audio synthesis. Stay tuned!

Monday, September 26, 2016

PyWeek 22: Beneath the Ice


"Beneath the Ice" was our entry for PyWeek 22 (September 2016), a twice yearly video game development competition that gets competitors to build a complete game from scratch in seven days using the python programming language. This competition's theme was "You can't let him in here!" and we made a submarine exploration game and puzzle solving adventure, in which you must uncover the secrets of a mysterious pariah who doesn't want to be found, who can't let you in! The game was developed under the collaboration "Team Chimera" (myself and Lucid Design Art, who did all of the game's artwork). This is Team Chimera's third game in a PyWeek comp, after "The Wizard's Data" and "Adrift".

We were super excited to win both the Team Entry and overall winner with a score of 4.41 out of 5.0. Our score also makes "Beneath the Ice" the second highest ranking game in PyWeek history! (almost one thousand games over more than ten years!), so it suffices to say we were pretty pleased with the result :).



Here you can find the latest version of the game. We are currently in the process of cleaning the game up a bit (bug fixes, graphical updates and gameplay tweaks) and this page will be updated again over the next few weeks. The game is currently available for Mac OS 10.6+, Windows or as a source code distribution (multi-platform: windows/osx/linux) that requires the pre-installation of python and pygame (see instructions below):

Game Play Videos:


Downloads:

Mac OSX 10.6+: 
Beneath_the_Ice_pyweek22_osx_v100.zip

Windows:
Beneath_the_Ice_pyweek22_win32_v100.zip

Source code distribution (compatible with Windows/Mac OSX/Linux, requires python and pygame):
Beneath_the_Ice_pyweek22_source_v100.zip

Game can also be downloaded from the links on the PyWeek game page here.

Instructions for running the source distribution:

(1) Install python 2.7.11 (currently not working with python 3): go to https://www.python.org/downloads/ and download the installer for your platform.
(2) Install pygame: Once python is installed, pygame 1.9.1 can be installed using these instructions.
(3) Download the zip file above, unzip to a location of choice. Open a terminal (osx) or the command prompt (windows), change directory to the path of the game and type "python run_game.py".

If you are having trouble getting the game to run, or have a bug/crash to report, please email: randomprojectlab@gmail.com




Friday, September 2, 2016

Softie Rainbow Flower


Recently I ran an introductory workshop on Arduino and wearable/softie electronics; I took a lot of inspiration from a previous wearables workshop I had attended at the MAAS. The workshop was to run for only two hours, and I wanted to have participants walk away with a finished project, so it had to be relatively uncomplicated and not too time consuming to build. I ended up making a little rainbow flower using a Gemma, tiny lipo battery, single Neopixel, conductive thread and felt.


I found from previous projects that conductive thread is a bit finicky when you are working with it for the first time, and with little sewing experience (like me!). Lots of neopixels are great, but that requires lots of sewing, so I decided to just use one, so there's only three lines that need to be made (power, ground and one data line). Neopixels are pretty bright, and I've found they can be a bit harsh on the eyes after a while, so I found that covering the Neopixel with a little bit of cotton wool/stuffing helped to scatter the light a bit. I placed white felt in front of the stuffing to hold it in place and the Neopixel still shines through well.

I've posted some step-by-step instructions on how to build the flower, plus the sketch/code below, for those interested:

Softie Rainbow Flower:

Parts:

  • 1 x Adafruit Gemma
  • 1 x Flora type Neopixel RGB LED
  • 1 x Small 100mAh Lion Battery
  • Micro USB to USB-A cable
  • conductive thread, felt, small piece of stuffing/cotton wool
Code:

You can download the sketch/code to run this project here. (Update 26/10/2016: A slightly modified version of the code to run two neopixels here).

Steps:
  1. Download and install the Arduino IDE. Open the Arduino software and you should be able to see a folder in (your home directory)/Documents/ called "Arduino".
  2. Download the Adafruit Neopixel library from here. Unzip and copy the whole folder into the "libraries" folder within the "Arduino" folder. Close the Arduino software (if it is still open) and re-open. Click on "tools/board" and change to "Arduino Gemma". Click on "tools/programmer"and change to "USBtinyISP".
  3. Download the sketch/code form the link above (this one for one neopixel or this one for two neopixels). Create a new folder called "simple_rainbow" in your "Arduino" folder and copy this file (simple_rainbow.ino) into this folder (if using the two pixel code, name you folder "simple_rainbow_2pixels" to match the file name).
  4. Place the Gemma and Neopixel onto a piece of brown felt (or other colour of your choice) as shown in the picture below. The "GND" pad on the Gemma should be on the top left, "D1" pad up and the "Vout" pad on the top right. The Neopixel should have the "-" pad on the left, "+" pad on the right and in next to the arrow that points in towards the white square in the middle of the board at the bottom.
  5. Using conductive thread, stitch three lines using three separate pieces of thread between the pads on the Gemma and neopixel as shown in the image: "GND" to "-", "D1" to "arrow" and "Vout" to "+". Make sure the thread is making a nice, tight contact with the pad and use a tight, neat running stitch along the felt. Make sure to snip off any loose bits of thread to avoid any part of the thread touching a different set of pins and potentially short-circuiting the design.
  6. Switch the Gemma off by using the very small switch on the front. Using a micro USB cable, plug one end into the Arduino and the other end into your computer/laptop (make sure you have a USB2 port available: Gemma has been known to act-up/flat-out not work with some USB3 ports).
  7. In the Arduino software, click on the tick button in the top left corner to compile the code. Switch on the Gemma and while the red led on the front is flashing, you can click on the arrow/upload button to upload the compiled code to the board. You get about 10 seconds to do this: if you miss it, no probs, just turn it off and on again (or press the small circle reset button on the board). If everything is working, you should have to wait a few seconds and your neopixel should start to cycle through a rainbow sequence of colours.
  8. You can now switch off the Gemma and unplug the USB cable. Plug in the battery using the black JST connector on the Gemma (make sure the polarity is correct: the plug will only fit in one way, even if it is a little tight and difficult to get in).
  9. You can now stitch on any design to the front of the felt using normal thread and felt. I made a little pocket (looks like a flower pot) to hide the Gemma and hold the battery out of view. You can leave the Neopixel uncovered if you like it that way, or place a small dab of cotton wool/stuffing in front of it to give it a more soft appearance (mine is stitched underneath the circle of white felt in the center of the flower). Cut away any of the excess felt that doesn't make up your design and be careful not to chop off any bits of the conductive thread!
  10. You can modify the code to display any pattern of colours you like. Try changing the "i" in line 60 of the code (setPixelHue(0, i);) to a number between 0 and 360 to have a single static colour of your choice. Re-compile and re-upload using the USB port (you should be able to leave the battery connected while doing this).



Monday, August 22, 2016

Cubey: Arduino-based Video Game Console


I've just finished (mostly) a new video game project: It's an Arduino-based video game console, and I've nick-named it 'Cubey'.

Cubey plugs into a TV via a set of RCA cables to provide a low-res, black and white video game experience roughly equivalent to video game consoles of the late 1970s and early 1980s. It has a custom 3D printed case, is compatible with the Nintendo nunchuk controller (supporting two players) and currently features four built-in games (I'm in the process of working on more). On the inside Cubey uses an Arduino Mega 2560. The Mega is used to input data from the nunchuk controllers via I2C, run game logic and drive an analogue PAL video signal with two colours (black and white) at resolution of 120 by 96 pixels and a mono-audio signal with four channel sound/music.



Initial Design:

About two years ago I had been playing around with the awesome Arduino library 'TV-out' using an Arduino UNO. I was using the UNO to run an implementation of the game 'snake' using two digital input pins and two momentary buttons to turn the snake left or right. 'TV-out' provides a bunch of basic functions for generating PAL video signals using interrupts on the Arduino and a pair of digital output pins to construct a two colour video signal via a 2-bit DAC (the library documentation page provides a really good explanation on putting this together using a pair of resistors). I hadn't gone any further with this project, so I picked it back up recently and decided to make something a bit more sophisticated. I was inspired by and drew heaps of ideas from a bunch of other Arduino-based video game projects including the HackVision, The Box and Gamebuino. I wanted to make something that would support multiple games and at least two players. To reduce the complexity of the project, I decided to make the console compatible with an existing game controller, rather than build my own. I found this example for using the Nintendo nunchuk controller (an accessory that plugs into the Nintendo wii-mote) with Arduino and thought this would work perfectly. The nunchuk has two buttons, an analogue joystick and three-axis accelerometers all packaged up in something you can buy for about $5 to $7 (aftermarket models).


I started off by building a breadboarded version of the console to systematically test out the various things I wanted to get running. I started off by connecting up my UNO to an RCA output jack using a 2-pin DAC with a pair of resistors and did a test run of the TV-out library: all working fine. I downloaded a library for communicating with the nunchuk controller via I2C here and compiled this into a project to read joystick state and move a pixel around the screen: all working fine, everything compatible.

Getting two-player control to work:

I really wanted to have at least one more controller hooked in so that I could run two player games. Problem with I2C is that there is only one set of pins on the Arduino for this. Normally this would be OK: multiple I2C devices can be slaved on one line as long as they have different addresses. Unfortunately all nunchuks use the same 0x52 address, so I found I couldn't talk to two simultaneously on the same line. One option was to run a software I2C for one of the nunchuks, but this didn't seem ideal. I found this solution which connects two nunchuks to the I2C clock line (SCL) and uses a pair of transistor switches to toggle the data line (SDA) using two additional digital pins on the Arduino. I wrote up a test sketch that basically switches on the first SDA line (nunchuk A) and switches off the second line (nunchuk B) before grabbing data (nunchuk A), then reverses the switches and grabs data again (nunchuk B). Breadboarded it up and it worked perfectly! I had a couple of npn type transistors sitting around from a previous project ... probably a bit over spec'd for this, but they work! I used 1kohm resistors to connect the transistor bases to the digital output pins from the micro. Voila: two player control with two nunchuks.

So at this point I was thinking "why not put in another nunchuk for even more players?" I guess I am only limited by how many unused digital output pins I have (twelve in total on the UNO). I think the main thing stopping me here was (a) making games on a 120 x 96 pixel screen with only two colours (to specify what player is which) for more than two players is hard (b) I only own 3 nunchuks anyway (c) the likelihood of getting more than four people together to test it out seemed low ... plus the nunchuk cables are quite short, so it would start to get a bit squashy sitting around playing with that many people in close proximity (actually, I guess this could potentially enhance the 'social' experience of playing together :) ).

Initial software tests and switching over to the Mega:

I thought it prudent at this point to try and get some game code running with what I had working so far, so I started implementing a clone of the game Missile Command (a popular Atari title from 1980). Problems began. Everytime I would do any relatively larger drawing to the screen (using TV-out library functions "bitmap" or "print"), I would lose I2C connectivity with the player two nunchuk, requiring a power cycle. Eventually I found I could sort of overcome this by adding in "delay(1)" call in-between any graphics intensive call.

About halfway through programming the game, I hit a wall: running out of RAM. The Arduino IDE indicates the amount of memory being used by global variables during compilation. I was lulled into a false sense of security when I saw that my program was only using about 30-40% of available memory on global variables. Then I realised that I was not accounting for memory taken up by local variables/functions on the stack; my sketch was compiling fine but wasn't running, presumably because of stack overflow ... so I was about half way into the code for my first game and already running out of memory. This seems to confirm what I was seeing. I guess the old ATmega328 (chip inside the UNO with 2K of RAM) wasn't going to cut it. OK, so I wasn't really being super memory-conscious when writing the code, but I wanted more than one game up and running and I didn't really want to have to be skimpy with my game design, so I made the choice to switch over to the Arduino Mega (with 8K RAM), because I have two sitting around not doing anything at the moment.

3D printed case design:

I played around with a lot of ideas for the case. I had a look around on Thingiverse hoping to find a cool 3D model I could slice an enclosure into, but didn't see exactly what I wanted. I kind of had the idea that it would be cool to make the enclosure a giant dodecahedron, but it seemed like a fair bit of wasted space seeing as the mega is quite long on one axis only. At some point I was going to make a space invader shaped case, but it had to be pretty big to fit things properly, so I abandoned it. I ended up doing some sketches of some tetromino-inspired shapes, and settled on a little thing built out of cubes. I nicknamed him 'Cubey'.


I built him up in Openscad. He's broken up into a few sections so I could print him without too many supports: it was a real pain picking off the support material from my last print project (in fact most of it is still stuck on the case because it was just too damn hard to get off). I made ports for the two nunchuks, RCA cables and power and usb from the Mega. His mouth is a reset switch for the Mega and, because I had so many available ports on the Mega, I added some leds in his eyes for some blinky fun :). I printed him mostly in white except for some small detailing around the eyes which were printed in black as separate pieces and then super glued onto the final design.


Problems with the case: I had a few issues with the case after printing. Firstly, I had real problems getting the raft off the main body. There were sections that were literally fused into the case, and at some point I had to abandon a 1.5 hour effort to cut them off. I ended up filing it down as best I could. Unfortunately this interfered with the sockets for where the back legs were originally designed to fit into, so rather than reprint the piece (seven hour print and probably face the same issue), I redesigned the clearance on the leg parts before printing them. I also realised that the holes and corresponding plugs didn't fit (the tolerance on the size of these bits wasn't as tight as I thought it would be), so needed a reprint anyway! Other problems with the case: I had only allowed for a 1 mm tolerance for the space to fit the mega: not enough apparently, so I ended up breaking off the support that would have held the reset switch in place and improvising. I ended up cutting a small strip of perfboard and soldered the switch to that before sticking it in the small gap between the Mega and Mega protoboard (which was to hold all of the electrical components for nunchuk switching, the DAC etc.), held in place with a little bit of bluetac :). I redesigned the nose button so it was about 5 mm thicker at the back to compensate for the extra reach. One thing that did work was the support for the RCA cables: clipped together like dream (after a tiny bit of filing :) ). I had to print the legs a number of times due to issues with tolerances on 3D printed parts connecting together and bits in the nunchuk connector spaces that didn't fit right. Eventually they were printed such that they fit with a bit of give and I used superglue to connect them to the main body.

Putting Cubey together:


On top of the Mega I used a protoboard (especially designed to fit and line up exactly with the Mega) to hold additional electronic components. This provided space for the resistors made up the DAC and that connected up the digital pins for driving the video and audio signals to the RCA cable connectors, resistors for the led eyes and the transistor circuits. I used a female-to-female RCA adaptor to connect the lines from the board to an external plug. I got two nunchuk connector adaptors (Nunchukies) to use in my controller ports. These came with convenient "wings" at the side of the board to help click and hold the nunchuk connector into place, but I found they got in the road of my design, so I hacksawed them off and made my own indentations built into the 3D printed controller port. I screwed these boards into the cavities of Cubey's front legs such that they sat flush with the controller port/socket. I then soldered the power and data lines from these up to the Mega protoboard where they were interfaced to the Mega. The front and back legs were then super glued on and the top case just clicks into place (so I can open it up again to if I needed to).


Getting some music:

I had tested the audio through RCA jack when I setup my original breadboard model, working great with 470ohm resistor in line with pin 10, and was able to generate a single channel of sound: a square wave generated via an implementation of Arduino's 'Tone' function built into the TV-out library. I wasn't very satisfied with the ability to only play a single audio tone at a time: I wanted cool video game music and any decent music needs harmony and melody, so I wanted to have some level of polyphonic sound. Reading a bit about how the Arduino built-in tone library works, I came upon this library which seemed to be exactly what I wanted. I ported over the functionality described within to use Timer 3 on the Mega as a counter for an interrupt routine that would flip the output to produce a square wave. Everything seemed to work fine when playing tones on their own, however, when this was run alongside the video signal generation using the TV-out library, it was producing a nasty clicking mess. From what I can gather, the interrupts being driven for video signal generation were messing with the timing for the tone interrupts.

I found this library for running PWM signals using different timers on the Arduino, without the need for an explicit interrupt routine to switch the output, but instead using a PWM mode of the timers and a register value to store the direction in which to flip. I ported over this implementation, and it worked perfectly: I now had two simultaneous square wave tones that I could play. I ended up implementing an additional (third) channels using this method on Timer 4 on the Arduino such that I had three square wave generators (three simultaneous tones at any one time) and no interference with first audio channel or video signal generation. I found that I could vary the duty cycle to 25% on one of the three channels to produce a slightly different timbre of sound such that there was a bit of audible distinction between the different channels/voices in the music.

Good music requires some sort of beat or percussion, so I used my last available timer on the Mega (timer 5: Timer 0 is used for game logic timing and Timer 1 is used by the video signal generation) to do this. I used Timer 5 to drive an interupt that would randomly assign a high or low value at a fixed frequency to a fourth channel in order to create a white noise signal that would emulate the sound of a drum or other percussive instrument. I found this page on using a Fibonacci Linear Feedback Shift Register as an efficient means of generating a pseudo-random signal for the noise. I found I could emulate an acceptable kick-drum by running this routine at ~1kHz and an acceptable snare at ~5kHz. Since the video signal generation interfered with these interrupt-driven signals, I had to make the sounds limited to a duration of 20ms (inside the time between video updates), which was fine for a basic beat.

Now that I had the ability to generate three square wave tones and one percussive sound simultaneously, I was ready to make some music. I wrote a routine that would read in arrays of data containing pitch and note duration information for each channel and play them at a fixed speed of 50 Hz (in line with the video signal). I found I could store music data in the flash memory on board the Mega (256K available, also used to store image and sprite data) and read it in as it was played.

At some point I will upload my updated version of the TV-out library containing these extra functions (and my game code): stay tuned!

Games:


So far I've written four games: 'Space Blast': a two player space shooter, 'Missile Command': a clone of the popular Atari title, 'Breakout': another clone of an old Atari game, and 'Achtung!', a clone of an old DOS PC game called "Achtung, Die Kurve!". I'm currently working on a few more: I'm keen on writing something that can exploit the accelerometer/motion sensing on the nunchuk in a cool way, but haven't quite got a good game concept working yet. Work in progress!

Overall, I've had a lot of fun with this project, however it did take a decent amount of time (about 6-8 weeks total). In the end I was super hyped about getting the four channel sound to work: I learnt a lot about how old video games made the sorts of sounds they did and how composers had to work within these constraints, which I've found really interesting. I may end up trying to expand on this in a future project, perhaps some sort of Arduino-based chiptune player project. Although the black and white video was sufficient for simple games, it probably would have been nice to try and get a few more shades of gray in (or even colour signals!), however it was a bit outside of the scope of my knowledge: if I did a follow-on to this project, this is something that I would definitely attempt.

Sunday, August 7, 2016

Twinkle the Starfish (retrospective)

This was a project I did as a present for my young son last christmas. At the time he was really into the Octonauts. There's an episode that features a deep sea starfish called Twinkle who is lost and needs the Octonauts to help her find her way home. My son really loved this episode, so I thought it would be cool to give him his very own Twinkle with blinky eyes. I had a Gemma and some neopixels sitting around from a previous project, so electronically speaking, this project was in the bag, just needed to do some sewing.

I made a star shaped section for Twinkle's front, added a mouth and some embellishment and cut two neopixel-sized holes for the eyes. I hand stitched two black felt circles on the front of these holes that in turn had smaller holes cut into them about 4mm in diameter; big enough such that when the neopixels sat behind the black felt, the LEDs would poke through. I used a single rectangle of felt to make a sewed circuit that connected up two neo pixels and a clicky momentary button to the Gemma. I powered the whole thing using a small 300mA lipo battery. I then stitched this to the back of star such that the neopixels were positioned over the eyes and the button was Twinkle's nose. I then machine sewed this all to the back half of another star (back-to-back) and folded the whole thing inside out and stuffed it with stuffing.

Unfortunately, I didn't really have enough time to put in a proper switch on the battery line, or think about a good way to recharge it, so I left a small finger sized hole on one corner of the star so I could reach in and pull the battery out when needed and so I could switch it on and off using the very small switch on the Gemma. This was probably the most disappointing part of the final design: next time I need to look into how to design this properly with a click switch connected to the battery.

For the code, I setup Twinkle to run in two 'modes'. In the first mode, Twinkle's eyes would just run a predefined pattern. Pressing her nose would cycle through the available patterns: a rainbow sequence and pink lights that would fade in and out. In the second mode, Twinkle's eyes would display a single colour, and pressing her nose would cycle through a list of available colours. To switch between modes, one holds down Twinkle's nose for one second.


The neopixels are surprisingly bright: me and my son like to turn off all the lights and use Twinkle as a colourful torch to explore around in the dark (pretending we are deep under the ocean in the 'midnight' zone). Great fun!

Monday, July 25, 2016

Jump-activated rainbow beanie (retrospective)

This was a project I did about a year ago after attending a workshop on arduino wearables. The project was run at the MAAS, which does some great events for kids and young adults, but doesn't often run events for adults. So I was happy when I heard they were doing an adults course, and came along. I'd seen some super cool wearable projects, and the mix of electronics and textiles/soft surfaces seemed cool. During the workshop everyone was given an arduino Gemma, some neopixels, a bunch of little sensors and some conductive thread and encouraged to see what we could make. I ended up connecting four neopixels up to the Gemma with a little vibration switch and sewed them all into a beanie: voila! a jump activated rainbow beanie.


The neopixels take power, ground and are driven by one digital output pin that transmits individually addressed RGB data to each and every neopixel attached along a chain. The vibration switch is triggered when shaken or given a good jolt, and one of the Gemma pins was used to read its state. The code on the Gemma would then just trigger a preprogrammed rainbow sequence along the neopixels.


All of connections were made using conductive thread sewed into the rim of the beanie and powered from a small 500 mAh lipo battery. Because the beanie was quite stretchy, I had to sew the conductive thread lines in a sort of zig-zag fashion: this meant they would sort of flex with the beanie when someone stretched it over their head (instead of just snap). Definitely the most time consuming part of the project was sewing the conductive thread circuit!

Here's the final code for my project sketch:

/* rainbow_jump_hat.ino - arduino sketch using four neopixels 
displaying a rainbow pattern triggered by a vibration switch
*/

#include 

#define LED_PIN 0
#define VIBSWITCH_PIN 1

Adafruit_NeoPixel strip = 
    Adafruit_NeoPixel(4, LED_PIN, NEO_GRB + NEO_KHZ800);

int VibSwitchState = 0;
int event = 0;
int eventcount = 0;

void setPixelHue(int pixel, int hue)
{
  while(hue < 0)
  {
    hue += 360;
  }
  
  float h = hue % 360;
    
  float sectorPos = h / 60;
  int sectorNumber = (int)floor(sectorPos);
  float fractionalSector = sectorPos - sectorNumber;
        
  float q = 1 - fractionalSector;
  float t = fractionalSector;
        
  switch(sectorNumber)
  {
    case 0:
      strip.setPixelColor(pixel, 255, 255 * t, 0);
      break;
    case 1:
      strip.setPixelColor(pixel, 255 * q, 255, 0);
      break;
    case 2:
      strip.setPixelColor(pixel, 0, 255, 255 * t);
      break;
    case 3:
      strip.setPixelColor(pixel, 0, 255 * q, 255);
      break;
    case 4:
      strip.setPixelColor(pixel, 255 * t, 0, 255);
      break;
    case 5:
      strip.setPixelColor(pixel, 255, 0, 255 * q);
      break;
  }
}

void DoRainbow() {
  for(int i = 0; i < 360; i++) {
    strip.setBrightness(255);
    setPixelHue(0, i);
    setPixelHue(1, i + 90);
    setPixelHue(2, i + 180);
    setPixelHue(3, i + 270);
    strip.show();
    delay(10);
  }
}

void setup()
{
  strip.begin();
  strip.setBrightness(255);
  strip.show();
  pinMode(VIBSWITCH_PIN, INPUT);
}

void loop()
{
  // Look for motion
  VibSwitchState = digitalRead(VIBSWITCH_PIN);
  if (VibSwitchState == HIGH) {
    event = 1;
  }
  else {
    event = 0;
  }
  
  if (event == 1) {
    DoRainbow();
    DoRainbow();
    event = 0;
  }
  else {
    for(int i = 0; i < 4; i++) {
      strip.setBrightness(0);
    }
    strip.show();
    delay(10);
  }
}

Friday, July 15, 2016

Homemade Handheld Videogame Console: Part 4: Games


Once I had the hardware finished up, I was ready to finalise the on-board software and load up a few games. I already had three ex-pyweek games ready to go: all I needed was some sort of main menu that would come up when the console was switched on and would allow the player to navigate options and choose games using the dpad and buttons. I wrote a quick and dirty main menu interface using pygame that allowed the player to choose between the three games (I will probably come back and upgrade this to something more visually impressive somewhere down the track). I added a line to the end of /etc/rc.local to run this on start-up.

To get the menu interface to quit itself and start up a selected game, I used "os.execv", a nice function that does just this: shuts down the current instance of python and finally runs another command on the shell with specified arguments. I set it up so when a game was selected, the code would run:

pygame.quit()
os.execv('/usr/bin/python', ['foo', resources.gamedata[select_ind].path])

I used the same mechanism to get games to shift control back to the main menu when the player quit them. This was convenient, because it meant I had to make very little change to the existing game code.

All games were working nicely. I also adapted an existing game that used the mouse to work with the touchscreen input. Here's the console in action:


Current Games:

"The Wizard's Data": pyweek 20 entry by Team Chimera
"Adrift" pyweek 21 entry by Team Chimera
"Underworld": a beta version of a game I've worked with on and off for about a year :)

Overall I was super happy with the outcome for this project. There are however a few things that I learnt and would do differently for next time:

Buttons: I didn't really like the buttons in the end, they make an annoying loud clicky sound and don't depress far enough. To their credit they look nice and are responsive. They just don't feel as good as a proper games controller: next time I do this sort of thing I will definitely invest in some proper arcade buttons, or at least something that has a built-in spring or rubbery inside to produce a smooth, but still responsive feel.

Audio Volume: I don't know why, but the audio volume is super quiet. Not sure if I botched something or not. I'm pretty sure I've got the trimpot ramped up correctly ... will try to figure this out somewhere down the track.

Sunday, July 10, 2016

Homemade Handheld Videogame Console: Part 3: Building


When my case was fresh off the printer, I started lining up all the components to see that everything would fit as I'd planned. I think I had convinced myself that I would have gotten at least one measurement wrong somewhere and that this first print would be just a test run. I was happy to discover that I had actually not stuffed up anything too critical and that I could get it all to work. The thing that didn't really work as well as I had hoped was the standoffs for the smaller components (amp and boost converter): I had designed a cylinder to fit through the small mounting holes on these PCBs with a diameter of 1.6mm, but when they came out of the printer, these parts of the structure were just a stringy mess: I guess they were just a bit below the resolution the printer was capable of. The standoff cylinders for the pitft screen and RPi mounting holes were 2.5mm diameter, and these came out fine, but they were pretty fragile. In the end, I decided to break them off, drill 2 mm holes in their place and screw the pitft, RPi and larger holes on the boost converter onto the standoffs: lesson learnt for next time!

Once I was happy that everything would fit, I started assembling the buttons, RPi and screen into the case. I cut two square(ish) sections from perf board to hold the buttons (main buttons and dpad) on either side of the screen, and drilled 2 mm holes into these so I could screw them down to standoffs on the case. Buttons were then soldered on before screwing the perf board onto the case.

At this point I realised I'd miscalculated the heights of the standoffs for the dpad side: it was short by about 2 mm such that the buttons would be pressed down permanently upon screwing it in. I didn't have any washers that were small enough, so, because I'm super impatient, I improvised with snipped off bits of wall plugs :) ... Total hack, but hey, it did the job. A little bit of bluetack on the back of each button stopped them from have that slightly annoying rattle.

I then screwed in the tft screen to the case; the RPi would then slot on top of the 40 pin header; conveniently the tft also provides an additional breakout of this same header, which I connected a 40 pin ribbon cable connector to, chopped off at one end so I could feed out the GPIOs/ground to the buttons and 5V/ground in from the boost converter. I soldered up all those connections, plugged the pi on top and powered it up to check all the buttons were working well.

Next I wired up the amp to the speaker, and positioned these in the case. The standoff pins in the case for the amp hadn't come out properly in the 3d print, but it was ok with no further modification, found the board could sort of float in the case with no issue. Next step was to screw in the boost convertor to the case using two of the four mount holes. Soldered the power out pins to the RPi (via header cables) and across to the amp.

Placed the battery into the case, held in place with a tiny bit of gaffer. I fit the slide switch into its hole in the case and soldered it on to the boost convertor. Last step was to solder the signal pins from the amp to the solder points on the RPi PCB that sat adjacent to the 3.5 mm audio jack. Closed the case up, switched it on and everything was working a-ok!