MIDI Drum Module
By Don Carveth, Botgoodies, Oct. 2004
Rev. 1 Nov. 2004 – Added LCD text descriptions for drum tones, drum sets and MIDI and fixed some data entry bugs. Changed the LCD format to one page per data entry type for a total of 4 pages.
ATMEGA16, c-code using GCC 3.4 WinAVR, schematic, code.
As a hobbyist musician who often plays a MIDI keyboard and used to play the drums a MIDI drum project seemed a good idea. It turned out that getting from a whack on a small speaker to a bass tone from my MIDI sound card was really quite simple. I wired up a board with two MIDI drum channels, an ATMEGA16 microcontroller, a 2x16 line LCD display and 6 key keyboard, sent the signal to a PC sound card and was able to use my feet to play drums accompanying my piano. I added a feature to the board that allowed me to send controller signals to the card as my keyboard is quite old and can issue only limited requests. Using the LCD/keypad I could change the drum set used and the individual drum tones for each drum channel. Upgrading to an 8 channel drum machine controller and creating the electronic end of a full set of electronic drums would be quite simple. Most of the work would involve the mechanical end, an area that I did not delve into too far.
MIDI is an asynchronous serial interface. The baud rate is 31.25 Kbaud (+/- 1%). There is 1 start bit, 8 data bits, and 1 stop bit (ie, 10 bits total), for a period of 320 microseconds per serial byte. 31250 is conveniently divisible by 1 MHz and therefore 8 MHz so it can be set precisely using UART dividers.
The MIDI circuit is current loop, 5 mA. Logic 0 is current ON. One output drives one (and only one) input. To avoid grounding loops and subsequent data errors, the input is opto-isolated. It requires less than 5 mA to turn on. The Sharp PC-900 and HP 6N138 optoisolators are satisfactory devices. Rise and fall time for the optoisolator should be less than 2 microseconds.
The standard connector used for MIDI is a 5 pin DIN. Separate jacks (and cable runs) are used for input and output, clearly marked on a given device (ie, the MIDI IN and OUT are two separate DIN female panel mount jacks). 50 feet is the recommended maximum cable length. Cables are shielded twisted pair, with the shield connecting pin 2 at both ends. The pair is pins 4 and 5. Pins 1 and 3 are not used, and should be left unconnected.
The standard schematic is:
An alternate schematic based on using the joystick port of a PC sound card is:
MIDI commands are quite simple consisting typically of an 8 bit command followed by 0, 1 or 2 data bytes. A good summary of the commands is located at http://www.borg.com/~jglatt/tech/midispec.htm. The MIDI GS tone table defines tone sets and drum notes.
Drum Module - Hardware
The drum module detects “hits” and sends appropriate MIDI signals using the selected drum type and volume. Hits are detected by small speakers (or microphones, whatever you have that’s handy). Tapping the speaker sends a low level analog wave to the input of an LM358 op amp. The op amp V-- is connected to ground so it cuts off the negative part of the cycle and amplifies the positive signal to a maximum of about 3.5 V. The signal is connected to the AVR’s ADC0 input. The ADC reference voltage is set at 3.5 V using a resistor bridge. Accuracy is not as important as range.
The ATMEGA16 uC fuses are set to enable the internal 8MHz clock. It’s possible that this may not always be accurate enough (MIDI baud rate within 1%) and an external crystal may be required. Worked fine on mine. I also have a regular 19.2K Baud RS-232 interface to Hyperterminal that I use for troubleshooting. Setting the “TESTING” macro in midi.h to 1 sets this mode. The ATMEGA16 is overkill – I suspect this could all be accomplished on an ATMEGA8 with minor changes – except for the text descriptions which push flash memory use from 4K to above 10K.
The LCD uses a 4 bit standard interface and is explained in file LCD.c. The keyboard consists of up/down, left/right, send and times 10 keys and is explained in kb2.c. The x10 shift key is handled separately from the main keyboard routines.
The MIDI interface needs some explanation. My intent was to connect my MIDI piano keyboard into this module then through into the sound module. The output to the sound module would normally consist of the UART connected directly to the DIN connector jack. In my case I connected the MIDI keyboard in an “OR” configuration using the 74HC00 so that signals from either the drum module or the MIDI keyboard would go the sound module. Since my drum board is isolated from ground I decided I could get by without an optical interface (this proved to be correct). I was afraid that I might have problems when the two signals collided and that proved to be true and occurred more often than was acceptable. The module was still usable by using the keyboard built in sound module mixed with the output from the PC sound card. I included a switch on the keyboard input signal to block it when operating the drums. I could still use the module as an extended tone setting module if I didn’t use the drums. This allowed me to access some previously unavailable sounds from my Roland Sound Canvas sound card.
At this point the drum sensor consists of a small speaker fastened face down to a piece of wood set on the floor. I wear shoes and tap my foot on the back of the speaker. This works well enough that I may not bother to upgrade. If I did so a simple spring return foot pedal with a hard rubber striker would be ideal.
Drum Module - Software
The AVR program in written in c and compiled using GCC3.4, WinAVR version. There are several separate modules for keyboard, LCD display and standard functions.
After initializing the uC and variables the program enters an infinite loop where it monitors the ADC inputs for signals exceeding the drum sensor trigger levels and monitors the keyboard. If a drum signal is sensed then the amplitude of the signal is determined by monitoring the signal until the amplitude begins to drop then latching the peak value. At this point a MIDI signal is issued containing the drum (note) number and the volume. A 20 ms deadband timer is started to ensure the note is not retriggered.
The keyboard status is monitored every scan (kb_keyflag). If non-zero then the keyboard processing routine is entered. The keyboard is a six key design - up, down, left, right, enter (middle) and X10. The location of the LCD cursor is monitored (LCD_pos) and a different process entered for each different data entry location. I created a separate entry page for each of Drum Set, Drum #1 tone, Drum #2 tone and general MIDI . At each location the following keyboard actions can be taken:
Up - Increase value
Down - Decrease value
Left - Move to data entry location at left. If at left moves to previous page.
Right- Move to data entry location at right. If at right moves to next page.
Enter- Send MIDI controller signal based on info on active line
X10 - Increases up/down from 1 to 10 per keystroke
Drum Set – Select a drum set and push the enter key to issue command.
Drum Tone – One page for each of drums 1 and 2. Select the tone and push enter. Note that only standard set text values are shown. Print out a copy of GS_Table Drum Sets.xls to use as a reference and set tones by number.
General MIDI - "C" refers to channel, "B" to bank, "T" to tone. Set each value then push enter to send a MIDI controller command using the entered parameters. Note that only bank 1 text descriptions are shown. Print out a copy of GS-Table OtherBanks.xls to use as a reference and set tones by number.
EEPROM - every time a new command is issued all of the current values are stored in EEPROM. On powering up the last used values are restored. To return to factory defaults, hold down the enter key on power up or reset.
LCD Display - There are 4 separate data entry screens - Drum set, drum#1 tone, drum#2 tone and general MIDI. The cursor goes to the data entry location on the first line. The second line displays the text description.
If you have any questions about the article, please contact the author at firstname.lastname@example.org.