DrumKid is an "aleatoric" drum machine, meaning it uses random numbers to determine the rhythm and sound of a drum beat. It comes in a handheld, battery-powered unit, designed for live performance.
The whole project is open source. The GitHub repository contains all the code, schematics, Gerber files and DXF files, and I am also going to make the project available as a breadboard layout. When on a breadboard, the drum machine uses an Arduino, utilizing the Mozzi library to generate audio. When transferred to a PCB for the final product, the Arduino element is combined into the design, using an ATmega328.
I have tried to make the design as accessible and hackable as possible. There are breakout pins for the ATmega328, to allow extra features to be added, and the design uses standard, low-cost, easily obtainable parts.
DrumKid will be available to buy this autumn.
Drum machine are ubiquitous in modern music, but playing them live presents a challenge. When playing electronic rhythms live, whether using a drum machine or a laptop, it can often appear that a musician is simply pressing "play" on a backing track, removing much of the perceived spontaneity of a live performance.
My drum machine, DrumKid, aims to tackle this problem by using a variety of controls to alter a drumbeat live, using randomly generated drum hits which augment the original beat. Rather than being designed as a pre-programmed backing instrument, DrumKid aims to be a playable instrument in its own right, with continuously adjustable controls that work well in a live setting. My intention was to create an engaging, interactive device that, like any musical instrument, can be mastered over time with practice.
VIDEO DEMO OF DRUMKID COMING SOON
DrumKid is an open-source, hackable product based around an ATmega328 chip, as found in an Arduino Uno. The final product features a minimalist design consisting of a single PCB with buttons, knobs, and LEDs mounted on one side, and all other components mounted on the other side. Two laser-cut sections are used to protect the electronics.
I now have a fully working prototype of DrumKid, and I am happy with the audio quality, playability, aesthetics, durability, reliability, and battery life. I am planning to make a small, initial batch of DrumKid units in September to distribute to musicians for testing. After any necessary updates to the PCB design and/or firmware, I hope to build a larger batch of units and launch DrumKid for sale around November/December 2019.
DrumKid can also be constructed as a breadboard/stripboard project using an Arduino Uno - see the build instructions for details.
I've spent most of this week working on DrumKid's code. There are 20 possible parameters to control using the buttons and knobs, so this week's task was to work out which 20 features would make it into the final design, and write any necessary code to implement those features. I'm now almost certain that the 20 controllable parameters will be:
chance (likelihood of random drum hits being added)
zoom (whether short notes are affected by the randomness, or just long ones)
midpoint (the average velocity of the random hits)
range (the range of random velocities generated)
pitch (the playback speed of the sample - can now also play samples in reverse!)
bit crush (crunchy digital distortion)
crop (trims the samples for a staccato effect)
glitch (deliberately overloads the processor for weird noises)
slop (random quantize - moves a hit forwards or back by a random amount of time)
swing (transitions between straight and swing/shuffle rhythm)
delay mix (how many echoes, basically)
beat (choose from a selection of preset beats)
tempo (can also be set by tapping a button)
drift (gradually alters various parameters over time automatically)
drop (choose which samples to mute)
drone mod (how much to multiply the drum audio by the drone audio)
drone mix (how much raw drone to include in the mix)
It was a process of trial and error to reach this list of features. Some ideas (such as switching between different sets of samples) were ruled out because there wasn't enough storage or memory. Other ideas took a while to get right - I was really keen to have the ability to play samples in reverse, but I had to clone the Mozzi library and edit some of its code to enable this. I also had to clone and edit the ArduinoTapTempo library to make it do what I wanted. I'm aiming to make pull requests for the features I added to these libraries once I'm done with DrumKid.
As well as adding these 20 controllable parameters, I added a number of other features, such as the ability to save and load patches from the ATmega's EEPROM. I also spent quite a while optimising the code, and working out how to store as little as possible in the ATmega's (tiny) RAM. As things stand, the program storage space is at 93%, while the dynamic memory is 87% full from global variables alone (enough to trigger a warning in the IDE, but I've done plenty of checks to make sure it's fine).
So, overall, the technical side of things is good, but more importantly, DrumKid is sounding good! I recorded an audio demo today to try and show off most of its functions. Have a listen here:
So far, almost all my build logs for this project have been about technical challenges, design choices, etc - there has been very little about the most interesting aspect of this drum machine: the way that randomness creates a beat. Now that I'm happy with the basic design and am well into the coding section of the project, this seems like a good time to explain the algorithm (if that's the right word?) behind DrumKid.
DrumKid starts off as a pretty regular drum machine. It begins with a basic 16-step drum pattern, e.g. "kick hat hat hat snare hat hat kick kick hat kick hat snare hat hat hat" (it can play multiple sounds at once, but that's much harder to write in a sentence!). This basic pattern is then modified using random numbers in the following way:
Imagine that for each type of drum (kick, snare, hat, etc), and for each step in the sequence, you roll a dice. If you roll a six, a drum hit is added to the sequence. So, as well as the original pattern, about a sixth of the steps (for each type of drum) that would have been empty now have drum hits. These dice rolls will be different every time, creating an unpredictable beat.
If we want the beat to be more unpredictable, we could lower the threshold of when we add an extra hit - say, when we roll a six or a five. This threshold effectively controls how much randomness we allow into the beat, and is controlled by a knob on the drum machine (obviously with a much bigger range than the one to six of a dice!). Turning the knob to zero will mean that only the original pattern is played, while turning it up to maximum will mean that every drum is triggered on every step. This parameter is called chance.
This is an interesting start, but it sounds much nicer when we also vary the volume/velocity of each drum hit. Let's imagine that every time the first dice has determined that there will be an extra hit, we will also roll a second dice to determine the velocity, with a roll of one creating a very quiet hit, and six creating a very loud hit. This will sound interesting, but a little bit wild - we want a way to tame this randomness.
We can define a minimum and maximum value for these random velocities, so that, for instance, all of the extra hits are between 30% and 50% volume. This allows the original pattern to remain discernible, while adding a sort of sub-groove to the beat. Alternatively, you could put the minimum at 10% and the maximum at 90%, creating a much busier feel. After a bit of experimenting, it turns out that the most intuitive, live-performance-friendly way to control these parameters is not with "min velocity" and "max velocity" knobs, but with one knob to determine the midpoint the random velocities, and one knob to control the range. This means you can create a drum fill simply by turning up the midpoint knob.
Manipulating these three knobs, chance, midpoint, and range, gives a lot of expressive control over a drumbeat, and these will be the main default controls on DrumKid. By pressing different buttons, it will be possible to switch the knobs to other functions, including audio effects like pitch shift, bit-crush, etc, and there may be other more obscure randomness-based parameters (perhaps an inverse of the process described here, which removes hits rather than adding them), but these three controls are the heart and soul of DrumKid, and provide its signature sound.
Coding is going well, so hopefully there will be an audio/video demo soon!
So, the previous prototype looked cool but a routing error meant that it was completely non-functional. Unperturbed, I rerouted the design in KiCAD, fixed a couple of other errors I'd noticed, and ordered a new run of five PCB's, which arrived last week. I soldered everything in place, plugged in the battery pack, and... disappointment. The LEDs were flickering dimly, and a drumbeat was barely discernible through white noise in the headphones. I was frustrated, and busy with other work, so I put the barely-functional prototype to one side for a few days.
Yesterday, with a free afternoon ahead of me, I waded back into the problem. My first thought was that the batteries weren't powerful enough, perhaps due to some bad soldering that was causing the circuit to leak power somehow, but I tried a few different power sources and the results were the same. I tried a simpler Arduino sketch, and managed to get the LEDs working at full brightness, which led(!) me to realise that I'd done something stupid in the original sketch. I corrected my original mistake and moved onto the audio problem.
The audio was noisy, inconsistent, and had an annoying high-frequency buzz. Cunningly, I had included breakout pins in the PCB design, which meant I was able to easily intercept the raw, low-voltage audio output before the amplifier chip (LM386) and have a listen. I fed it through what should have been an identical amplifier circuit on the breadboard prototype, and the sound was much nicer, albeit not perfect, so I painstakingly double-checked whether my KiCAD schematic accurately reflected my breadboard. It did not! I had forgotten to ground pin 4 of the LM386. I briefly thought "oh no, I guess I'm ordering another PCB" before realising that this mistake could be fixed by soldering a small wire from pin 2 to pin 4. Obviously not a long-term solution, but fine for a prototype.
Suddenly there was progress. The volume control went from near-silent to super-loud, with no white noise, but there was still a high-frequency buzz. I showed the almost-working drum machine to my always-supportive partner, secretly hoping she might not even notice the buzz, but she pulled a face and said it sounded horrible. This problem turned out to be super-easy to fix, though - I just added a single decoupling capacitor (I had left optional holes for several on the PCB layout), and everything was perfect!
And not only was the PCB working, but a very generous Twitter-friend had laser-cut the two parts I needed to complete the prototype, and sent them to me in the post. This means that I'm now at a very exciting stage:
The PCB works, with only one tiny extra wire needed to account for a minor error in the design
The laser-cut parts look and feel great, and I'm happy with the overall aesthetics of the drum machine
The Arduino sketch is producing nice, clean audio via the Mozzi library
The PCB now matches the breadboard design pretty much exactly, which means I can work on the code using an Arduino and a breadboard, safe in the knowledge that it will work on the PCB once I'm happy with the code
I've now got a couple of weeks to focus on the code before the Hackaday Prize deadline, making sure the drum machine is intuitive, fun, and (most importantly) musically interesting.
Happy with recent progress! After deciding to go for a more simple, bare-bones design, I designed a new PCB which ran off 3 AA batteries instead of 2, eliminating the need for voltage regulation. I also made the decision for the top surface of the PCB to be the actual front of the instrument, eliminating the need for a traditional case. Long story short, the PCB arrived and this is approximately what it looks like when assembled, with a few caveats to be discussed further down:
You can see that the design consists of a top and bottom layer, separated by standoffs, as well as an extra "palm rest" piece on the top layer, to cover ugly/sensitive electronics. The main circuitry is on the underside of the top PCB - the "palm rest" piece just hides the solder. There are now six buttons and four knobs on top to control the instrument, plus a volume knob. I'm really pleased with the look and feel of the instrument, but there are a number of ways in which the final version will differ from this mock-up:
The potentiometers will be slightly shorter and knurled for better ergonomics
The standoffs and machine screws will be metal for better durability
The battery holder, which is mounted on the underside of the PCB, will be secured in place with machine screws and dome nuts, for better aesthetics than the current temporary nut
In this photo, the top "palm rest" cover is 3D printed, while the bottom, protective layer of the case is actually just a spare, unpopulated PCB - both these pieces will likely end up as laser-cut plywood or acrylic
There is also one other key way in which this prototype can be improved: it doesn't actually work! I'm embarrassed to say that I was rushing to finish the PCB design before heading to Glastonbury music festival with some friends, and ended making a silly mistake which rendered the entire board unusable. I am very keen for this design to be "hackable", so I have added breakout connections for all the main Arduino pins (5V, ground, 14 digital pins, 6 analogue pins), but I was struggling slightly for space and, as far as I can tell from reviewing the KiCAD files, I must have attempted to move the breakout pins halfway through routing the board. In doing so, I created a short circuit which I only noticed when testing an assembled board. Here's what I did:
All I had to do was click the "run DRC test" button, and this mistake would have been glaringly obvious, but by this point it was midnight and my mind was focused on packing for the festival. Never mind! It was a good lesson, and there were a couple of other minor issues with the board which I noticed anyway (mounting holes in the wrong place, poor layout choices, etc), so I've created a minor revision of the board and ordered another small run of 5 PCBs from China. Fingers crossed! In the meantime I can keep working on the code/firmware using my breadboard/Arduino circuit.
I've hit a bit of a slump with this project so I'm writing a log to try and clarify my thoughts.
I like to think that I'm not the only maker whose shelves are littered with half-finished projects. Initial ideas are exciting, and that excitement often propels me as far as an initial proof-of-concept build, but then the grind of iterating the design kicks in and that often causes me to give up. "DrumKid" has already surpassed the vast majority of my previous projects, in that I've created several breadboard versions, a stripboard version, and two PCB versions, as well as a 3D-printed case. This is something to be proud of, and yet, paying-the-bills work has pushed DrumKid development off my immediate list of priorities, and the Hackaday Prize deadline is steadily moving closer. What to do?
At the start of this project, I promised myself I would take the simplest route where possible. Getting bogged down with power management, amplification, and case design has taken me away from the super-simple design I was imagining. It's time to be brutal and come up with a simple, bare-bones product. My mentoring session gave me some really good tips about how to simplify the circuit design, and now I think I have a good plan for simplifying the case design - by not building one.
A friend bought me a Pocket Operator drum machine for Christmas. This instrument is made by Teenage Engineering, who seem to specialise in stripped-down design. The Pocket Operator is simply a single PCB, with buttons, knobs, and a display on the front, and batteries on the back. All the other components appear to be hidden under the display.
If I can design DrumKid in a similar way, I think that would solve a lot of my problems. Since I'm using fairly chunky through-hole components, I might need to use two PCBs (separated by stand-offs), one for the interactive components (buttons, knobs, LEDs) and one for the "other stuff". I might also need some sort of covering to prevent fingers touching sensitive circuitry.
I like the aesthetic of the Pocket Operator, too - it's simple and utilitarian, but playful at the same time. I'm going to do a few sketches and see how practical it is to make a DrumKid prototype in a similar style.
I had a really useful mentoring session with Mitch Altman, Majenta Strongheart and two other Hackaday Prize entrants on Thursday. It was really interesting to see how the other entrants approached their projects, and I learnt a lot from talking to Mitch about the development process.
Coincidentally, Mitch has previously built an Arduino-based synth with a lot of similarities to my project. I looked at his schematics before the session and noticed a few things:
Both our projects used an Atmega328 to generate audio
Both projects used an LM386 to amplify the audio
While my project uses a relatively expensive chip to boost the voltage of 2 AAA batteries, Mitch's synth runs directly from 3 AA batteries
This comparison was really interesting and useful - it told me that my approach to the circuit was fairly uncontroversial, but it also suggested that I could do away with the most problematic element of my design, the expensive and noise-producing voltage boost chip. I hadn't previously realised that the Atmega328 could run happily on less than 5V (forum posts had suggested otherwise), so it was very gratifying to hear Mitch confirm that it works fine on 4.5V. Straight after the mentoring session, I hooked my breadboard circuit up to three AAA batteries and was excited to realise that it worked fine, with barely any noise.
A few other things I took away from the mentoring session:
My problems with making mistakes during PCB design are normal, and it's an accepted part of the development process to just hack the incorrect design and then incorporate the fix into the next version
It might be worth investigating Seeed Studio in future for board assembly (in case me hand-soldering the boards becomes a bottleneck when producing larger quantities)
CNC routing could be an option for the case if laser-cutting isn't suitable
Overall, really happy that I was able to take part in this mentoring group - it helped me with both big-picture thinking and with the specifics of my project.
I feel like I have a handle on the noise issues now. Part of the issue was the PWM noise (Mozzi generates audio via pulse width modulation rather than a "proper" digital-to-analogue converter). The Mozzi website gives a useful low-pass filter circuit for filtering out this noise, but I found that it wasn't sufficient once I started amplifying the signal. Although the signal is only just within my range of hearing, I could tell from recording the signal into my computer that there was a lot of high-frequency oscillation that I wanted to get rid of.
I played around with different resistor and capacitor values, but found that in order to filter out enough of the noise, I was also having to filter out the higher frequencies of the drums, leaving an unwanted muffled sound. I searched the web for "make steeper low-pass filter", and suddenly felt like I was back at university again. I came across this great explanation of passive low-pass filters, which had a really useful section on building a second-order filter. This is basically a chain of filters, and gives a steeper "roll-off", cutting out more of the unwanted frequencies (about 15kHz and above) and keeping more of the frequencies that actually contain drum sounds. I played around with a few different components (why are ceramic capacitors so hard to read?) and found a sweet spot, meaning I was ready for my next PCB...
There are a few key differences from the first version:
LM386 amplifier for louder headphone signal (friends told me the last version was too quiet)
Different button layout after testing the first design
Three control knobs instead of one after testing the first design
Different type of button - the previous ones were hard to source and impossible to find with an RoHS certification, which is worth thinking about before I start selling DrumKid
Bigger on/off switch for better ergonomics
Horizontal thumbwheel volume control for better aesthetics
Mounting holes because I forgot them last time
Better power management - decoupling capacitors for the Atmega328
Arduino and power pin breakouts for better hackability
I'm still learning about board layout, and should probably get some professional feedback at some point, but for now I've got my fingers crossed that this will be a good improvement on the previous PCB. Now I've got about three weeks before the boards turn up - I could have shelled out the extra money for fast shipping, but I need some time to work on the code anyway, so I'm happy to wait.
Next steps: more work on the code, 3D-print a new case, try DrumKid with my band.
After yesterday's rant about not knowing what to do next, I decided to invest some time in making a new stripboard prototype. I was worried that the current design (batteries to voltage boost IC to Atmega328 to LM386) was just fundamentally too noisy, yet I couldn't think of a way to omit any of those elements without going all the way back to the drawing board. With this worrying thought in my head, I decided to convert my latest breadboard circuit into a stripboard circuit, in the hope that I would be able to build something with a clean enough audio output to give me some hope for the PCB version. It was a half-logical, half-desperate step, but (after several tense hours) it just about worked.
Before adding the decoupling capacitors, the noise was still horrible, but I tried adding a few different values to both sets of power/ground pins on the Atmega328 and gradually the noise became almost acceptable. Perhaps "acceptable" is a bit strong, but given that the stripboard circuit doesn't have a proper ground plane, I'm happy enough to now recreate this as a PCB, with slots for numerous decoupling capacitors.
Apologies that the last couple of posts have been a bit dull - I'm trying to be disciplined and sort out the fundamental issues like power supply, audio volume, and noise, before I keep working on the fun features.
I'm reaching a tricky point in the development process. Skills-wise, I'm someone with a fairly good grasp of coding, but only a patchy (if gradually improving) grasp of electronics. This means that, while I'm pretty capable of solving weird software problems, things like grounding issues or noisy power supplies send me into a cold sweat.
I've never really had to worry about problems like this before this project, because I could always avoid them. My previous musical instrument builds were one-offs, and I could choose a platform that didn't require me to do much "real" electronics. For instance, a lot of my recent instruments have used a Teensy 3.X (£20+) with a Teensy audio adaptor (£13), which instantly gives lovely clean audio and plenty of processing power. I also power most of my projects with a USB power supply rather than batteries, which simplifies things.
DrumKid, though, is my first attempt at a real-world "product", and developing it is a very different process. I've used a £2 Atmega328 chip to try and keep costs down, but doing so is causing me all sorts of problems that I wouldn't hit with a Teensy. I can't just put £33 of extra components in there, though, because I'll then have to put the price up by that amount. Then again, with the better components, it's probably a better instrument and probably worth more, so maybe that's okay. And by using a Teensy instead of an Atmega328, I would probably save myself a bunch of time and money on the development process.
The problem is, I have no idea how to do the calculations that would tell me whether my current strategy of trying to be as cheap as possible is the right one. I've also sunk a lot of time into this design, and I don't want to change tack, which I know is bad logic.
Anyway, my current problem is this: DrumKid works nicely when using a proper Arduino and a nice clean 5V power supply for testing, although the audio is a little quiet. I can boost the audio with an LM386 amplifier, but then it becomes really important to have a clean power supply. The finished product will be powered by batteries, run through a boost converter to get to 5V, and it's quite hard (but possible) to get that power supply clean enough for good audio. Basically, everything should work fine together, but when I try all the elements together on a breadboard, I get horrendous, unacceptable amounts of noise. Now, I know that a solderless breadboard is probably not the best way to test a fairly sensitive circuit like this, but I don't know what else to try. Is it worth spending time making a stripboard version? Do I have to resort to doing another iteration of the PCB, knowing that it probably won't be the final one, and might not even work?
I think I'm starting to see the difference between being a "hacker" and a "designer"...
Spent a good day working on the project today, and made a few decisions about the design. While looking back at the initial, web-based version of this drum machine, I remembered that the most pleasing thing about the interface was changing multiple parameters at once, by touching the different sliders on the touchscreen. This was previously something I had decided to sacrifice for this physical version, in favour of having one big potentiometer whose function could be changed by pressing different combinations of buttons.
Today I decided to experiment on the breadboard with three potentiometers, and only five buttons instead of seven, and it definitely felt nicer, so I'm going to carry on with that layout for now - I think it will look just as good (if not better) when translated into a new case design, and will only raise the component cost by £1 or so (although I've said that about a few components recently, so it's probably time to do another cost check soon).
I've also spent quite a bit of time on the code today, implementing a system which loads two copies of each audio sample, allowing them to overlap with each other. Before I added this feature, a loud bass drum followed immediately by a very quiet one would cause an annoying "click" sound as its signal was suddenly attenuated by the quieter sample which replaced it.
This system is working nicely, but it is a bit more processor-intensive and has consequently caused me to get rid of the resonant filter effect. Analogue filters are really cool, but this was a fairly weedy-sounding digital filter, and I don't think it's any great loss.
To show where I've got to so far, I recorded a sample of how DrumKid sounds in its current state. The following recording starts off "clean", with no additional bit-crush effect, although it's still pretty crunchy (a feature not a bug!). I begin by adjusting the "hyperactivity" parameter to modulate how many extra hits are added to the basic beat. Then I start to increase the bit crush effect while also modulating the pitch of the samples. The only post-processing I added to the recording was a low-pass filter, because I could still hear a faint high signal (Mozzi's carrier signal?) which I haven't successfully filtered out on the breadboard yet.
The simplest way to get a version of DrumKid working (apart from buying one when it's released!) is to build the breadboard circuit using an Arduino. The components are mainly pretty standard: you'll need a breadboard, jumper wires, an Arduino Uno, tactile buttons, LEDs, 10k potentiometers (linear), an LM386 amplifier chip, and a selection of capacitors and resistors. You'll also need some sort of breadboard-compatible headphone socket - I used a 3.5mm socket with screw terminals which is designed for prototyping like this.
I've squeezed everything onto a single breadboard with small buttons and tightly spaced potentiometers, but you might want to consider sprawling over two breadboards, which would allow you to use bigger buttons, making for a more ergonomic playing experience. Using a second breadboard might also give you space to use a breadboard-friendly Arduino variant, keeping the whole project a bit neater, although I haven't tested this.
Build breadboard circuit
Build the breadboard circuit shown below. Refer to the schematic for capacitor values. There are six push buttons which use the Arduino's internal pull-up resistors, five LEDs with current-limiting resistors, and four potentiometers connected to the Arduino's analog inputs. All these parts of the circuit are fairly standard, and found in lots of basic Arduino examples.
The more complex part of the circuit is found on the right of the breadboard - this takes the audio output from pin 9 of the Arduino and filters it, before amplifying it. The raw audio output is a PWM output which has quite a lot of unwanted noise (the carrier signal), so I've added a 2nd-order RC filter to clean it up. In doing so, I've removed quite a lot of the higher frequencies, which I'm happy with because of the lo-fi sound I'm aiming for, but if you want to keep more of the high frequencies (at the expense of a noisier signal), you can try different resistor and capacitor values. The LM386 part of the circuit then amplifies the signal. There are many ways to wire an LM386, so feel free to use a different circuit for this if you'd prefer.
If you just want to play around with DrumKid and aren't too worried about audio quality, you can just connect your headphone socket straight to pin 9 and ground, and omit the the LM386 circuit, filter circuit, and volume control.
Upload Arduino code
Download the DrumKid repository from https://github.com/mattybrad/drumkid and use the Arduino IDE (software) to open the Arduino sketch found at drumkid/arduino/drumkid/drumkid.ino
The code relies on several external libraries, so you will either need to install them using the Arduino library manager or from a zip file. Any libraries not available through the library manager will be noted in the code.
Make sure that the DEBUGGING constant is set to "false", and BREADBOARD is set to "true", then upload the sketch to the Arduino. If all goes well, you should see all five LEDs flash rapidly, after which you can play your breadboard drum machine.