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.
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 adafruit.com) 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.
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).
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.
- 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.
- 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.
Here is a high-level summary of the final algorithm running on the LPC810 microcontroller.
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.
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.)