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!