Digitally Recordable, User-Modifiable Sound Emitting Tool
You can build a customizable electronic drum kit with a microcontroller, force sensing resistors, simple bottles, and some basic electronic components. The system presented here detects strikes on four separate drums and plays back different samples for each drum.
Have you ever wanted a way to play the drums quietly at home also without spending hundreds (or even thousands) of dollars on an electronic kit? Now you can with a system similar to the Digitally Recordable, User-Modifiable Sound Emitting Tool (DRUMSET), which I designed and built with my Cornell University lab partners, Nick Teo and Ian Vermeulen. In this article, I’ll detail the design, which features an Atmel ATmega1284p microcontroller and a custom PCB board designed by Cornell University professor Bruce Land (see Photo 1). You can use a different microcontroller and board to design a similar system, but be advised that your mileage may vary.
The electronic system plays a high-quality drum sample with every strike of a constructed drum. It detects strikes on four separate drums and plays back different samples for each drum. A user can select between multiple preprogrammed drum kits using a user interface controlled by pushbuttons and a 2 × 16 LCD. This enables the user to assign drum samples to any of the four drums. Thus, a user can create a custom drum kit using the user interface and record a sample with the system’s microphone and assign it to a drum (see Figure 1).
At the heart of the system is an ATmega1284p microcontroller (see Figure 2). To detect drum hits, the force from a drum hit is directed through a modified 2-liter soda bottle (which directs force down to a single point) down to a Tekscan Flexiforce A201 force-sensing resistor, which is then connected to the ADC input on the microcontroller. This now-digital pulse is then debounced in software and processed as either a valid drum hit or noise. If the pulse is a valid hit, the system plays a preprogrammed drum sample corresponding to the drum that was hit and the current state of the system through an external DAC circuit, which is in turn connected to speakers. The user interface provides the user with an easy way to program the drums and is controlled by seven pushbuttons.
Each drum is constructed from a Flexiforce force-sensing resistor, a 2-liter soda bottle, an oatmeal can, and some tape (see Photo 2). The middle section of each bottle is removed, leaving only the semispherical top of the bottle and the bottom of the bottle. These two sections are then taped together and suspended inside the oatmeal can housing. The oatmeal can is cut so that the bottom is open and the can is slightly taller than the modified soda bottle. The soda pop bottle is then suspended inside this housing, where the bottom of the bottle is taped to the inside of the lid, leaving the cap barely touching the surface on which the system is resting. Attached to the bottle cap is then the sensing area of the Flexiforce force-sensing resistor, which is in turn wired to the ATmega1284p microcontroller’s ADC port (see Photo 3). The reason this drum setup is so elaborate is because the Flexiforce sensor has a very small sensing area (approximately 9.5 mm in diameter), which is not nearly enough to create a drum. In order to create a drum of usable size, we direct force down from the larger sensing area of the lid of an oatmeal can down to the size of a bottle cap using the soda bottle. The bottle is suspended inside the can so that the sensor does not need to deal with the actual weight of the soda pop bottle; instead, the weight of the bottle is felt by the oatmeal can housing and the sensor only detects when the bottle is compressed by a drum impact on the lid of the can.
This setup was used for three drums. For the kick drum, we simply placed a force sensor between two pieces of cardboard, which was then stomped on to register impacts. This much simpler setup worked well for the kick drum because of the simple stomping action that delivers a large amount of force over a large area.
Because these force sensors are really just resistors that change resistance based on how much force is applied to them, we needed to add a voltage source to actually measure how much force was being applied. We used the microcontroller’s VCC voltage source (5 V) and a 1-MΩ resistor to create a voltage divider circuit, which we then wired to the ADC input of the ATmega1284p. This resistance value was determined using the Force vs. Resistance graph from Tekscan for the FlexiForce sensor (see Figure 3).
In connecting the drums to ADC inputs on the microcontroller, we discovered that the input from one ADC channel caused other channels to experience noise. In order to account for and remove this noise, we added a 1-nF capacitor between the drum and the ADC input, which cleaned up the signal quite well and allowed the system to get better precision when recognizing actual drum hits (see Figure 4).
All four of the ADC inputs corresponding to drums were polled every millisecond. If the input was under an experimentally derived threshold value of 190 out of 255, that ADC input was registered to have a hit. In addition, each ADC input is debounced in software such that a single hit is not registered as multiple hits. This was done using a standard debouncing finite state machine. We did, however, discover that debouncing was a tricky issue to deal with, given that the drums we constructed were not incredibly robust and were slightly different from one another in terms of sensitivity. We needed to make sure that if the drum continued to move after a sharp impact, we didn’t detect additional hits. Simultaneously, we wanted to make sure that quick, successive hits to the drum, such as those in a drum roll, were each detected as valid. In running various experiments, we derived a state transition of 4 ms for the debounce state machine. Given that we have four drums in the system, we run the debounce code every millisecond and cycle through each drum, meeting the 4-ms timing perfectly for all four drums.
MICROPHONE: AUDIO INPUT
For recording custom samples into the system, we used a microphone wired to a Maxim Integrated MAX281 low-pass filter and an LF353 op-amp amplifier circuit. This recording subsystem is then wired to one of the ADC inputs on the ATmega1284p microcontroller.
In order to record the samples, we used an interrupt service routine (ISR) clocked at 22 kHz. This same routine was also used to generate sound output, as we found that both input and output must be at the same clock frequency in order to maintain correct-sounding audio output. We used a simple Boolean flag (recordFlag), which, when set high, turns the ISR into an audio-input ISR, while at all other times it serves as an audio-output output. Unfortunately, due to the ATmega1284p’s limited EEPROM, we were only able to save up to four audio samples, each of a length of about 0.17 s. This was, however, enough to map a sample to each drum in the system.
When getting audio input, we ran into a speed limitation with the ADC, which allowed us to only sample the input at one-third of the 22-kHz ISR clock speed. While the ADC could theoretically run at 22 kHz, we had trouble getting it to work at that frequency, which forced us to perform this workaround. To improve sound quality, we performed some interpolation between samples to make the audio less choppy, and we also added ramping up and ramping down to each sample to remove any clicking at the beginning and end of each sample playback. We also added functionality to ensure that the microphone detects some sound before beginning to record a sample. Finally, we added a red LED to the system that turns on whenever the record flag is set, which gives a visual cue that the system is ready to record.
In order to output sound from the system, we used an external Digital-to-Analog converter, namely an Analog Devices AD7303 8-bit DAC with an SPI interface. Our professor provided us with an SPI example for the ATmega1284p, which we used as a large basis for our own code to get serial communication working with the DAC. We sent samples at 22 kHz from the system to the 8-bit DAC, which was then connected directly to speakers for audio output.
The samples we used were stored either in program memory (PROGMEM) or EEPROM in the microcontroller. For those samples that we stored in PROGMEM, we needed to write code that used Atmel’s pgmspace C library in order to read data, byte by byte. This area was what we used for storing preprogrammed samples, as we found that there was much more program memory space available than EEPROM. In addition, we recognized that we would never have to modify the preprogrammed samples, which allowed us to store them in a static place in memory. We did, however, use EEPROM to store samples that were recorded using the microphone audio input. For clocking the output, we used an interrupt-triggered routine clocked at 22 kHz to output samples to the DAC. Because our PWM register overflows after 256, we divided each sample by four to theoretically allow for four samples to be played simultaneously. This did, however, result in softer audio output for single samples, but this was easily remedied by turning up the external speakers a bit.
The user interface for this system consists of seven pushbuttons and a 2 × 16 LCD. The buttons provide navigation controls (previous, next, enter), mode selection (Kit Selection mode, Custom Programming mode, Record mode), and a play sample button that allows the user to audition a custom sample in custom programming mode before programming it to a drum (see Photo 4). The screen’s top line displays the current mode and the bottom line scrolls between options for a given mode.
For Kit mode, the bottom line of the LCD scrolls through the four preprogrammed kits (Acoustic, Electronic, Misc, and Smoke on Water). When the Enter button is pressed, the user interface provides a confirmation message affirming that the kit has been changed. For Program mode, the bottom line of the LCD scrolls through all of the available samples. Once a sample is selected, the user interface tells the user to select the drum they’d like to program with the given sample, which they can do by simply striking the drum (or stomping in the case of the kick drum).
The latencies between the hits of drums and when the sounds played were well within acceptable ranges. Figure 5 illustrates the latency between hitting the drum head and the sound playing through the speaker. As shown in the screen capture, the latency from the hit to the sound starting to play is well below 10 ms, which is the delay that is perceptible to humans. Channel 2, the waveform on the bottom, is the signal to the ADC pin connected to the drum. Channel 1, the waveform on the top, is the signal to the speaker.
The system is also robust enough that it is able to pick up drum rolls, which are very fast drum hits in one smooth motion. In Figure 6, we see three very clear peaks, and each of those peaks is registered as a hit. The recording through the mic required two different pieces, signal filtering from the mic to the ADC port and then saving the input to the ADC pin to EEPROM.
Figure 7 shows the input of through the mic versus the input on the ADC pin. The raw input is channel 1 and the filtered output is channel 2. The channels are AC coupled to remove the DC offset. We see that the raw signal is very clearly amplified and filtered correctly. Most of the noise that is filtered out by the circuit is very high frequency and difficult to resolve on the scope trace, but removing it through the low pass filter is necessary to produce cleaner recordings.
Because we are using a 22-kHz playback, we needed to be able to record samples at 22 kHz. This proved to be a bit difficult due to the fact that the ADC on the ATmega1284p could only really sample at around 8 kHz. To resolve this issue, we turned to interpolation. Figure 8 shows how well the interpolation works in our system. The general shape of the signal is replicated through our interpolation. Some of the higher frequencies in the beginning could not be replicated because of the slower sampling rate and the fact that they were cut off by the ramp-up function.
There are occasionally accuracy issues with the force sensors, where some drum hits are not registered. This is due to the fact that our drums were not built very precisely or with the highest quality materials, but this could easily be remedied by higher quality parts, more precise drum construction, and perhaps better tuning for each drum. For the most part, however, the drums that were built were responsive to hits and very usable, especially the kick pedal and one of the drums that ended up serving as the snare in the kit. Of course, the system will not sound as good as an actual drum set, but the samples used are of very high quality and serve to make the system quite good for practicing and casual playing. In addition, recordings are only taken at approximately 7.3 kHz and then upsampled to 22 kHz using interpolation, so they aren’t as high quality as the preprogrammed samples. However, even with all of these limitations, the system works really well! Check out the video in the links for a demonstration of the functionality.
The results met most of our expectations. (You can view our project video at https://.youtube.com/watch?v=UDDq8T6gyiw.) When we first began working on this project, we wanted to construct the system such that the relative force of the impact to the drum would determine the volume of the audio output for the given sample. However, as we built up the project, it became clear that this was an unrealistic goal. This is due in part because of the way that force is transferred to the force sensor and also because of the way that the drums are constructed. Areas of the drum that are directly connected to the soda bottle would transfer almost all the force to the sensor while other areas might not transfer as much. Also each drum is constructed differently and the force to each sensor would not be consistent.
If we were to do this project again, we might try harder to create drums consistently so that we would be able to add varying volume to drum hits. It might also be good to use a 10-bit DAC instead of the 8-bit DAC that is currently in the project. This would increase the resolution of the sound coming out of the speakers and allow us to take advantage of the 10-bit ADC resolution.
R. Alur, Drum Kit Video, https://.youtube.com/watch?v=UDDq8T6gyiw.
R. Alur, Drum Kit Project Files, http://people.ece.cornell.edu/land/courses/ece4760/FinalProjects/f2014/iyv2_gt224_ra469/.
B. Land, SPI Example Using AD7303 DAC from Analog Devices, http://people.ece.cornell.edu/land/courses/ece4760/SPI/DACspiGCC644.c.
Analog Devices | www.analog.com
Microchip Technology (formerly Atmel) | www.microchip.com
MAX281 Low-pass filter
Maxim Integrated | www.maximintegrated.com
Tekscan | www.tekscan.com
PUBLISHED IN CIRCUIT CELLAR MAGAZINE • MAY 2016 #310 – Get a PDF of the issue