Sunday, April 8, 2018

boomCHUCK - 2018 Moog Circuit Bending Challenge

The boomCHUCK is a circa '90s drum machine plus custom analog circuits, all controllable with two nunchuck controllers.

My inspiration began with an old nunchuck controller and previous experience interfacing a similar controller with a different microcontroller.  I have been thinking about alternative instrument interfaces lately, and this seemed like a good chance to try something different.

After hearing about the challenge, I spent the first two weeks looking for a suitable sound making device and writing code for my chosen microcontroller to talk to the nunchuck.

The third week was spent reverse engineering the drum machine and deciding how to modify it.  Then, it took 2-3 more weeks to assemble everything and finish the software.


The software runs on an NXP LPC810 microcontroller which I started exploring earlier this year both to learn about bare metal microcontroller programming and to be able to use something significantly less expensive than an arduino board.

I began by writing an I2C driver to talk to the nunchuck controller and an SPI driver to talk to the DAC.  Later I wrote the Multi Rate Timer code to generate repeating events and of course the main loop that interprets the nunchuck movements to modify the boomCHUCK's sound. 

My code is on github.  I compiled it using GCC for ARM microcontrollers (arm-none-eabi-gcc).  I loaded it on the LPC810 using a USB-serial programming cable (from with lpc21isp, an in-circuit programming (software) tool that supports the LPC810.

References I relied upon are the LPC81x Datasheet and User Manual, the I2C specification, and the Wiibrew Nunchuck Extension Controller wiki.

Hardware Design:

Here is the bill of materials.  Here are the schematics for the circuits I built to augment the drum machine.  Below is a picture showing how the hardware is connected at a high-level.

The first thing I did with the drum machine was identify the various major parts of the circuit.  Here is a picture of the front and back of the circuit board.  (Click to see it larger.) 

Parts I identified from left to right:
  • The power circuit, powered by 6 AA batteries (9V) and regulated to around +5.5V.
  • The TA8207K power amplifier which sends audio to the onboard speaker and the line out.  
  • The C4570 dual op-amp circuit.  This amplifies the audio signal from the main chip and filters out noise before the signal is fed to the power amplifier.
  • The Yamaha YM3419B, the main chip, according to this webpage is used in drum rompler synths.  This led me to believe that at least one of the other two chips were drum sample ROMs.  Following the traces to and from the rightmost chip revealed that it is mostly for the 7-segment display and onboard button interface.
  • So, of the three large Yamaha chips, the middle one is the sample ROM.  I identified its power pins and listened to its other pins as sounds were playing.  Pins 1, 31, and 32 are Vcc, and pins 16, 22, and 24 are GND.  Some of the pins sound really high pitched, so they are probably the control input pins.  Whereas, the other non-power pins sound and look like modulated pulse waves for various aspects of the sample.  I did not end up using these pins in the final design because they are pretty harsh and noisy taken individually, but it could be interesting to find more information about the codec and try to mix the signals in a novel way with a DAC and/or microcontroller.
  • Along the top edge are four identical trigger circuits that limit the current and voltage generated by piezo sensors when the drum pads are struck.  The resulting four signals are fed into the main Yamaha chip to trigger drum sample playback.
As the schematics above show, the nunchuck controller interface circuit is built around an LPC810 microcontroller.  The nunchuck communicates with it via I2C, and the LTC1660 DAC communicates via SPI.  The purpose of this circuit is to map nunchuck controller movements to control voltages and drum triggering pulses.  I built this circuit twice, once for each nunchuck.  Here is a picture to commemorate the first one I got assembled and working.

The second circuit I built consists of a 4-stage all-pass filter phaser style circuit followed by a diode clipper circuit.  I chose the phaser style circuit so there would be multiple filters to to affect drum machine sounds across a wide frequency range.

The diode clipper circuit adds distortion to the signal.  I chose it for soft distortion and because I had 2 more op-amps to use in the second LM324 quad op-amp chip.

I included the onboard op-amp circuit on the schematics for the all-pass filter and clipper circuit to show how they connect.  I basically split the two onboard op-amp stages and inserted my op-amp stages in-between.

Testing and Building Instructions:

I soldered wires to the signal and power points on the drum machine's PCB.  On the front side are connections to the four drum triggers along the top and, in the middle left, connections to Vcc (red), Vcc voltage divided by 2 (white), and ground (black).

The blue wire and green wire seen on the back side of the PCB shown below connect to the outgoing line from the first op-amp and the incoming line to the second op-amp, respectively.  This is where my filter and clipper circuit are inserted.  I accomplished this by removing the 6.8k resistor at the front of the second op-amp stage.  The two wires are connected to the two sides, and the resistor is mounted on a protoboard to send the signal outgoing from my circuit back through it and into the second op-amp stage.

After the wires were broken out and mounted to a protoboard (the green one shown below), I built the filter and clipper circuits on breadboards.

Once I was confident of the circuit, I assembled a protoboard for the filter and clipper with LM324 op-amps but leaving off the seven photoresistors, the green blobs in the picture below.  The photoresistors provide the voltage controllable interface for the filter and clipper circuit. 

I made the photoresistors by hand.  For each, I used a light dependent resistor and an LED taped together facing each other.  The green is the "liquid insualtion" I used to seal them.  

I was not sure of their electrical characteristics, so I tested them by programming the microcontroller to output 3 voltages from the DAC, 2 seconds at a time.  Their resistance range depends on the current limiting resistor placed in series with the LED side.  So I measured the resistance all seven photoresistors at three voltages with four current limiting resistor values in series with the LEDs:  R = 10k, 20k, 47k, and 100k.  Here is my raw data.  I built a quadratic model to relate DAC input voltage and the resulting R--it's not linear.  But in the end my code operates as if it is linear because floating point math requires much more memory than available in the LPC810.  At least I got an idea of what variable resistance ranges were available for a given series resistor.  (Conservative measurement of the ranges are also noted on the schematic.)

I chose photoresistors along with a series resistor based on my measurements and soldered them to protoboard.  I connected all the boards together to test:  two nunchuck to DAC boards (left and upper right), one power and signal distribution board (upper left), and the photoresistor (bottom middle) and op-amp (bottom right) boards together comprising the filter and clipper circuit.

Final Software:

At this point I finished the software by writing code for the LPC810 to interpret the nunchuck movements as changes to the sound.  Each nunchuck has two buttons, an X-Y joystick, and a 3D accelerometer.  I implemented the following controls.

Left nunchuck:
  • Z button triggers the sound assigned to drum pad 1.
  • Shaking down while holding the Z button down triggers a flam of that sound.
  • C button triggers the sound assigned to drum pad 3.
  • Holding the C button triggers that sound repetitively with frequency changing in relation to tilting forward and backward.
  • Tilting left and right change the cutoff frequencies of the lower two all-pass filters--essentially a notch filter.
  • Joystick X controls the all-pass filter dry/wet mix.
  • Joystick Y controls the all-pass filter resonance.
 Right nunchuck:

  • Z button triggers the sound assigned to drum pad 2.
  • Shaking down, same as for left.
  • C button triggers the sound assigned to drum pad 4.
  • Holding the C button, same as for left.
  • Tilting left and right change the cutoff frequencies of the higher two all-pass filters--also a notch filter.
  • Joystick Y controls the amount of clipping from the clipper circuit.
All the original drum machine buttons work, and they can be used to assign different samples to each button (and corresponding drum pad). 

Here is a high-level summary of the final algorithm running on the LPC810 microcontroller.

Startup phase:
Initialize hardware pins for I2C and SPI.
Initialize the I2C configuration.
Initialize the SPI configuration.
Initialize the Multi Rate Timer configuration.
Initialize the DAC via SPI.
Initialize the nunchuck via I2C.

Main loop:
Turn off all drum triggers.
Try to read the nunchuck controller values.
If successful, then:
    Trigger drum 1 if button Z is pressed.
    Trigger drum 2 if button C is pressed.
    Trigger drum 1 flam if Z is pressed and nunchuck is shaken down.
    Trigger drum 2 repeatedly if C is pressed and held.
    Update the filter cutoffs per to the left-right tilt.
    Update the filter mix per left joystick Y.
    Update the clipping amount per right joystick Y.
    Update the filter resonance per left joystick X.
    Update the drum 2 repeat speed per the forward-backward tilt.
Multi Rate Timer Interrupt:
Interrupt the main loop per the repeat speed, and trigger drum 2.  (Then, return to main loop.)

Final Assembly:

I put all five of my circuit boards in the original case since there is plenty of space beneath the speaker.  I cut slots with a dremel in the sides for the nunchuck cords to go thru and tied knots to prevent pulling them out.

Friday, November 17, 2017

Plastic Pitch Microtonal MIDI Machine

I made this other Arduino microtonal MIDI device a couple years ago, and I wanted to try a different approach.  It's certainly interesting to play with more than 12 tones per octave, but it's also awkward on a piano style keyboard.  (How do you reach an octave when playing with 17 tones per octave?)

So I limited Plastic Pitch to 12 tones per octave to take advantage of the muscle memory that every keyboard player already possesses, but I gave each of the tones an independent pitchbend setting.  This allows the player to tune each of the 12 notes according to however the pitchbend range is set on the connected MIDI synth.  For example, if the synth's pitchbend range is set to 2 semitones (a whole step), then the knobs on Plastic Pitch range from down a whole step to up a whole step.  Change the pitchbend range on the MIDI synth, and the knob range changes accordingly.

Another design consideration that is different for Plastic Pitch is that I opted for what I would consider more of a musician's approach than an engineer's approach to microtuning.  An engineer might approach microtuning as I did with my previous device by using very precise pitchbend values that are carefully calculated to match specific numeric frequencies.

In contrast, I kept the interface simple and immediate.  Simple because the only indication of relative tuning is the line on each knob.   Twelve o'clock is neutral, left is down in pitch, and right is up.  And, immediate because tunings can be changed dynamically while playing in response to what is heard, not unlike how a violinist, for instance, makes small tuning adjustments as they play.

But why?

Am I just destroying all that is good about music?  I don't think so.

My initial pursuit into microtonality was inspired by the book Tuning, Timbre, Spectrum, Scale by William Sethares.  It presents a methodology that relates timbres to musically interesting microtonal scales.

The common 12-tone equal temperament (12-TET) scale works fine for timbres that are rich with harmonics, like the ones produced by all the traditional Western musical instruments.  However, if timbres are chosen that feature prominent inharmonic spectral content--gamelan is one example in the book, then a scale other than 12-TET would be more musically suitable for creating the interplay between consonance and dissonance that often characterizes tonal music.

The book has computational methods for coming up with possible scales for a given inharmonic timbre.  That is great for approaching microtonality as an engineer, however, as noted above, Plastic Pitch is an attempt to approach this differently, perhaps as a musician.

I want one!

Here are the schematics, parts list, and Teensy code if you'd like to build you own.

Please contact me with the form on the right sidebar if you'd be interested in purchasing parts, a parts kit, or even a fully assembled one.  I am not sure about prices, but I'll see what I can come up with if others are interested.  I for one would like to hear more microtonal music.

Technical notes:

It has two standard MIDI 5-pin DIN ports, one IN and one OUT.  The IN port listens for MIDI Note On (key press) and Note Off (key release) events from any MIDI channel.  The OUT port sends Note On, Note Off, and Pitchbend events on the first twelve channels.  All other MIDI events are ignored.

When playing a monophonic or non-multitimbral polyphonic synth, only the pitchbend for the last played note is used.  This is possibly a feature or possibly a problem to workaround depending on perspective.  The simple workaround is to only play one key at a time and not hold down multiple keys.  Or, do hold multiple keys, and get unpredictable pitch behavior.

Monday, May 15, 2017

GameSquare Software Notes

Introduction here.  Hardware notes here.

The Raspberry Pi 3 is running the current standard Raspbian image.  Here are the relevant contents of my /boot/config.txt file.


I wrote two custom programs:  "WiiClassicPi" allows the Wii Classic Controller plus volume knob and halt button to control the Raspberry Pi, and "" is a bare-bones file browser for launching games.

WiiClassicPi code and configuration:

WiiClassicPi reads the Wii Classic Controller data over I2C and translates it to virtual keyboard presses thru the linux uinput device and system commands.

Set up the uinput device by adding a line for "uinput" in /etc/modules.  Make it accessible for all users by adding the following line to /etc/udev/rules.d/99-com.rules: KERNEL=="uinput",MODE="0666"

After a reboot, confirm that it shows up with read/write privileges for all.

pi@raspberrypi:~ $ ls -l /dev/uinput
crw-rw-rw- 1 root root 10, 223 Feb  2 13:36 /dev/uinput

I installed libsuinput to generate keyboard presses thru /dev/uinput.  I installed Wiring Pi for the I2C library.  I2C can be enabled on the Raspberry Pi using raspi-config.

The delay times after I2C transactions can be customized at the top of my code.  The delay times provide enough time for I2C transactions to occur.  They probably can be less, but the values I've chosen seem to work okay.  According to wikipedia, input lag becomes distracting around 200 ms, so keep the delay times much less than that.

The valid key codes to be listed in the keys[] array can be found in /usr/include/linux/input.h.  The key codes should be listed in the same order as the commented list of Wii Classic buttons.

Notice that the ZL button is mapped along with the select (-) button to perform a system halt, and the LX analog joystick is mapped to the 10 K potentiometer and used to adjust the volume.

Also, line 147 of the code contains a workaround for a glitch.  When the Raspberry Pi is running something CPU intensive (like an emulator) the I2C read sometimes results in garbage (0xFF)) in the 2nd and 3rd of the 6 bytes.  So the code throws away those reads and moves on.  This might cause some noticeable controller latency if too many reads in a row produce garbage, but I haven't noticed any problems.

Compile using:  gcc -lwiringPi -lsuinput WiiClassicPi.c -oWiiClassicPi

Run as "./WiiClassicPi verbose" to see controller data. code and configuration:

I initially considered using RetroPie, however it would not recognize the virtual keyboard presses from /dev/uinput.  I also find it way too complex for such a simple thing as launching an emulator, especially on a small screen.

So I wrote, a Python 3 barebone curses-based frontend for launching emulators.  All the customization happens at the top of the code.  The keys are mapped to work with WiiClassicPi (except for the exit key (F1) to be used with an attached keyboard), and the extensions, directories, and launch commands have corresponding entries for each system.

# GUI keys
exit_key = curses.KEY_F1
up_key = curses.KEY_UP
down_key = curses.KEY_DOWN
left_key = curses.KEY_LEFT # back 1 page
right_key = curses.KEY_RIGHT # forward 1 page
launch_key = ord("j")
a_key = ord("x") # back 5 pages
b_key = ord("z") # forward 5 pages

# rom file extensions
file_ext = [".gb", ".gbc", ".nes", ".smc"]

# rom directories
romdir = ["/home/pi/roms/gb",

# emulator launch commands
emulator = ["/home/pi/emu/./gambatte_sdl -i j g x z up down left right -s 8",
            "/home/pi/emu/./gambatte_sdl -i j g x z up down left right -s 8",

GameSquare Hardware Assembly Notes

Introduction here.  Software notes here.

First, some photos for inspiration and reference.


The case slots together from the laser cut parts, and the screws and standoffs hold it together.  The four longer (31 mm) standoffs go in the four corners of the case, and the four shorter standoffs (25 mm) go in the back of the case to hold the controller PCB in place.  The screws fit snugly in the laser cut holes, so take care to ease them in the first time.

The two switches, three buttons, one potentiometer, headphone jack, and micro USB jack panel mount on the case.  The LCD is hot-glued on the face plate.  The controller buttons just sit on the PCB and are carefully wiggled into place when the face plate is fastened.  Velcro holds the battery, the speaker, and the Raspberry Pi in place.  I also used some Lego to hold the Raspberry Pi in place when plugging in a USB device.  Hot glue and electrical tape were used as needed to fasten parts and to prevent accidental short circuits.

LCD screen:

The plastic outer case can be pried open.  This photo shows where the composite video (yellow), ground (black), and 5V (blue) wires are to be soldered to the control board for the LCD.  (I used different colored wires in the final assembly shown above.)

Wii Classic Controller:

Open the controller case with a tri-wing screwdriver, and separate the PCB with a phillips screwdriver.  Desolder all the connections at J1, J2, J3, J4, ZL, and ZR.  Save the main PCB and the buttons and membranes on face of the controller.  I snipped off an empty corner of the PCB under J4 to make it fit in the case.


In initial tests the 2500 mAh LiPo battery provides about 2 hours of play time.  When the battery goes low, the LED next to the power switch turns off.  The next thing that happens is the I2C bus stops working.  This is problematic since system halt (without an attached keyboard) relies on buttons connected to the I2C bus.  (If I can stop playing video games) I may add functionality to monitor the Powerboost 1000C LBO pin with a Raspberry Pi pin to force a system halt when it drops to ground (indicating low battery).

Powerboost 1000C:

Powerboost 1000C documentation 

PAM8302 audio amplifier:

PAM8302 datasheet


The wiring schematic shows all the relevant parts except the Raspberry Pi 3.  The Raspberry Pi pins are simply labeled.  This is a good reference for the forty-pin connector.  The PP# pins are labeled on the underside of the PCB near the analog audio/video TRRS connector.  I made all the Raspberry Pi connections by soldering to pins on the underside.

Presenting the GameSquare!

Design Considerations:

I wanted to design my own Raspberry Pi handheld gaming system.  I logged most of my gaming hours in the early '90s.  So I have a soft spot for games from that era, and I particularly like the Wii Classic controller for its SNES-like layout.  

I knew from a previous project that Wii controllers can communicate over an I2C bus such as the one available on a Raspberry Pi.  I chose a 5" LCD screen based on being a similar width as a Wii Classic Controller.

When designing the case I realized the dimensions were roughly square.  So I decided to make it square and the name came naturally as an homage to the GameCube.  

The case is 160 mm x 160 mm x 37 mm.  The face has D-pad, select (-), home, start (+), A, B, X, and Y.  The back has the L and R buttons.  The bottom has a headphone jack and micro B USB jack for charging.  The right side has access to two of the Raspberry Pi USB ports which is good for connecting a keyboard.  The top has heat vents, a power switch for the external amp/speaker, a volume knob, a halt button, a power switch, and an LED that indicates battery high or low.  In initial tests I am getting about two hours of play time running on only the battery while using the external amp/speaker and with the Wi-Fi turned on. 

Parts List:

Purchase the Inkscape design file for the laser cut case here.  My case was laser cut by Ponoko using a P2 sheet of Amber Bamboo.

See the hardware assembly notes here.   

See the software notes here.

Tuesday, February 14, 2017

Simple Emulator Frontend for Raspberry Pi

I was annoyed by how complex the Raspberry Pi emulator frontends are, and I was looking for an excuse to write my first Python program.  So, here it is, a barebone curses-based frontend for launching emulators.  But really it could also be used to launch anything, like videos, ebooks, etc.

All the customization happens at the top of the code.  The extensions, directories, and launch commands will need corresponding entries for each emulator to be included.

# GUI keys
exit_key = 27 # ESC key
up_key = curses.KEY_UP
down_key = curses.KEY_DOWN
left_key = curses.KEY_LEFT
right_key = curses.KEY_RIGHT
launch_key = ord("j")
a_key = ord("x")
b_key = ord("z")

# rom file extensions
file_ext = [".gb", ".gbc", ".nes", ".smc"]

# rom directories
romdir = ["/home/pi/roms/gb",

# emulator launch commands
emulator = ["/home/pi/emu/./gambatte_sdl -i j g x z up down left right -s 8",
"/home/pi/emu/./gambatte_sdl -i j g x z up down left right -s 8",

Thursday, February 2, 2017

Wii Classic Controller over I2C to Raspberry Pi

I wanted to connect my Wii Classic Controller to my Raspberry Pi 3.  Here is how I did it.

The Hardware:

The Wiibrew extension controller page explains how to connect an official Wii Classic Controller via I2C.  (I tried a cheap ZettaGuard one, and I couldn't figure out the appropriate I2C initialization codes to make it work.)

The site Robot Electronics has an I2C tutorial that explains the need for pull up resistors when making I2C connections.  I used two 10 K pull up resistors and connected the four pins (3v3, SDA, SCL, and ground) from the Wii Classic Controller to the Raspberry Pi connector (pins 1, 3, 5, and 6).

The Software:

I am using a stock Raspbian image (as of January 2017).  The goal is to read the Wii Classic data and translate it to virtual keyboard presses thru the linux uinput device.

First, set up the uinput device by adding a line for "uinput" in /etc/modules.  Make it accessible for all users by adding the following line to /etc/udev/rules.d/99-com.rules:

After a reboot, confirm that is shows up with read/write privileges for all.
pi@raspberrypi:~ $ ls -l /dev/uinput
crw-rw-rw- 1 root root 10, 223 Feb  2 13:36 /dev/uinput

Now, this page has useful lower level info about writing C code to use uinput, but ultimately I installed libsuinput to handle the details.

I installed wiringPi to use the I2C library.  I2C can be enabled on the Raspberry Pi using raspi-config.

Here is my code.

The delay times after I2C transactions and keys to output can be customized.  The delay times provide enough time for I2C transactions to occur.  They probably can be less, but the values I've used seem to work okay.  According to wikipedia, input lag becomes distracting around 200 ms, so keep the delay times much less than that.

The valid key codes to be listed in the keys[] array can be found in /usr/include/linux/input.h.  The key codes should be listed in the same order as the commented list of Wii Classic buttons.

Compile using:  gcc -lwiringPi -lsuinput WiiClassicPi.c -oWiiClassicPi