Convert Rockband Controller to MIDI Drums


88,796

583

56

www.youtube.com/EvanKale91 === www.facebook.com/EvanKale91 === www.twitter.com/EvanKale91 === ww...

Hey! Today I'm going to show you how to convert a Rock band or Guitar Hero drum controller into a real MIDI drum set that can interface with digital audio workstations like Ableton Live, FL Studio, Pro Tools, etc.

Or you can simply use it to play DTXMania (DrumMania)!

Teacher Notes

Teachers! Did you use this instructable in your classroom?
Add a Teacher Note to share how you incorporated it into your lesson.

Step 1: Watch the Video!

Click here to view on YouTube

Check out this video to see the drum set working as a MIDI controller!

It is also recommended if you'd like to know the inner workings of the Arduino code, and want a more detailed explanation of the circuit.

If you'd like to just get it done, then read on!

Step 2: What You'll Need

We're going to need an Arduino.
I chose to use the Arduino UNO because I only needed 6 analog inputs but if you have more than 6 piezo sensors, then you can go with the Arduino Mega which has 16 analog inputs.

We'll also need:

  • 1 proto board
  • 1MΩ resistor for every drumpad
  • 1 220Ω for the MIDI port
  • 1 MIDI port
  • Male pin headers

Where to buy

Soldering gear:

Test gear:

Step 3: What I'll Be Using

I'll be using the Guitar Hero World Tour controller for this Instructable.

It's got 3 drum pads, 2 cymbal pads, and a pedal. On the back panel, there's even 2 stereo 3.5mm audio jacks - one of which connects the bass pedal and the other we can save for any further modifications to the drumset.

Also, this set comes with a MIDI input port. Which is perfect, because we'll just save a MIDI jack and rewire this port internally and turn it into a MIDI output port.

Step 4: Open Up the Controller

After you take out the screws on the back and unhook the controller dock, we can lift the back plate, and access the piezos.

You can see that the piezos are plugged in directly to the mainboard. The other board on the top just holds the back panel, and all the inputs of the back panel are plugged into the main board directly as well.

We'll just unscrew the main board, and replace it with our Arduino.

Step 5: Create a Shield for the Arduino

The first image here explains how our piezos need to be hooked up to the Arduino.

Then we'll have make a shield for the Arduino where we can plug in the piezos from the drum set into.

The second image is the schematic of the shield on a protoboard.

First we add some pin headers on the board to match the pins of the arduino, so that we can snap the proto board on top like a shield.

Then we'll take our resistors and connect it to a common ground.

Then we take our pin headers, break them into twos, and solder one end of each of the these to the other end of the resistors. Then we connect the other pins of the headers to ground as well. Now we can just plug our piezos directly to these pin headers.

We'll also add one more pin header for the MIDI port, as drawn in the schematic.

Step 6: Back Panel Modification (Guitar Hero Controller Only)

This step is for Guitar Hero World Tour controllers only -

Since we're reusing the MIDI port on the back panel of this controller,

We'll need to make a slight modification to the back panel board. By adding a jumper between the two pins pictured above, we can ground the middle pin of the MIDI port which would otherwise be missing for a MIDI output port. We can then plug the last four pins of the cable ribbon directly into our proto board.

Step 7: Install the Arduino Code

Download the full Arduino source code here:

https://github.com/evankale/ArduinoMidiDrums

If you're using the Guitar Hero World Tour controller, the default code will work out of the box.

Otherwise, you'll need to make adjustments to the definitions at the top of the code as you see fit to your drum set.

If you'd like a detailed explanation of how the program works, then check the the video from step 1!

Step 8: Snap It in and Close It Up!

Snap our new shield onto the Arduino, then plug in all the piezos into the pin headers.

I also added some hot glue to the solder joints to prevent it from breaking off in the future from all the drum hits.

Then make sure the wires are secured by taping them down with scotch tape, and close up the unit!

Step 9: Give It a Test!

Fire up a digital audio workstation like FL Studio and give it a go.

That's all there is to it!

If you liked this instructable, then perhaps you'll like some of my other projects!

You can check them out at my YouTube Channel.

Later!

4 People Made This Project!

Recommendations

  • Made with Math Contest

    Made with Math Contest
  • Multi-Discipline Contest

    Multi-Discipline Contest
  • Robotics Contest

    Robotics Contest

56 Discussions

0
None
MusaM14

2 years ago

hello everyone. y managed to make the conversion from a rockband drum set, but 1 problem i have is that i cant figure out how to add digital inputs for the pedal and eventually a cymball chocker. so i would appreciate any help taht you can provide.

and also thank you for the tutorial and the code

2 replies
0
None
joshuaj3180MusaM14

Reply 4 months ago

#include "Arduino.h"
#include "EButton.h"
/*
* Copyright (c) 2015 Evan Kale
* Email: EvanKale91@gmail.com
* Website: www.ISeeDeadPixel.com
* www.evankale.blogspot.ca
*
* This file is part of ArduinoMidiDrums.
*
* ArduinoMidiDrums is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/&gt;.
*/

//Piezo defines
#define PIEZOS 7
#define SNARE_THRESHOLD 30 //anything < TRIGGER_THRESHOLD is treated as 0
#define LTOM_THRESHOLD 30
#define RTOM_THRESHOLD 30
#define LCYM_THRESHOLD 30
#define RCYM_THRESHOLD 30
#define MCYM_THRESHOLD 30
#define KICK_THRESHOLD 30

#define START_SLOT 0 //first analog slot of piezos

//MIDI note defines for each trigger
#define SNARE_NOTE 70
#define LTOM_NOTE 71
#define RTOM_NOTE 72
#define LCYM_NOTE 73
#define RCYM_NOTE 74
#define MCYM_NOTE 76
#define KICK_NOTE 75

//MIDI defines
#define NOTE_ON_CMD 0x90
#define NOTE_OFF_CMD 0x80
#define MAX_MIDI_VELOCITY 127

//MIDI baud rate
#define SERIAL_RATE 115200

//Program defines
//ALL TIME MEASURED IN MILLISECONDS
#define SIGNAL_BUFFER_SIZE 100
#define PEAK_BUFFER_SIZE 30
#define MAX_TIME_BETWEEN_PEAKS 20
#define MIN_TIME_BETWEEN_NOTES 50



//map that holds the mux slots of the piezos
unsigned short slotMap[PIEZOS];

//map that holds the respective note to each piezo
unsigned short noteMap[PIEZOS];

//map that holds the respective threshold to each piezo
unsigned short thresholdMap[PIEZOS];

//Ring buffers to store analog signal and peaks
short currentSignalIndex[PIEZOS];
short currentPeakIndex[PIEZOS];
unsigned short signalBuffer[PIEZOS][SIGNAL_BUFFER_SIZE];
unsigned short peakBuffer[PIEZOS][PEAK_BUFFER_SIZE];

boolean noteReady[PIEZOS];
unsigned short noteReadyVelocity[PIEZOS];
boolean isLastPeakZeroed[PIEZOS];

unsigned long lastPeakTime[PIEZOS];
unsigned long lastNoteTime[PIEZOS];

const int buttonPin = 10; // the pin that the Foot Pedal is attached to
int buttonPushCounter = 0; // counter for the number of button presses
int buttonState = 0; // current state of the button
int lastButtonState = 0; // previous state of the button

const int buttonPin3 = 12; // the pin that the Foot Pedal is attached to
int buttonPushCounter3 = 0; // counter for the number of button presses
int buttonState3 = 0; // current state of the button
int lastButtonState3 = 0; // previous state of the button

void setup()
{

// initialize the Foot Pedal pin as a input:
pinMode(buttonPin, INPUT);
pinMode(buttonPin3, INPUT);

Serial.begin(SERIAL_RATE);

//initialize globals
for(short i=0; i<PIEZOS; ++i)
{
currentSignalIndex[i] = 0;
currentPeakIndex[i] = 0;
memset(signalBuffer[i],0,sizeof(signalBuffer[i]));
memset(peakBuffer[i],0,sizeof(peakBuffer[i]));
noteReady[i] = false;
noteReadyVelocity[i] = 0;
isLastPeakZeroed[i] = true;
lastPeakTime[i] = 0;
lastNoteTime[i] = 0;
slotMap[i] = START_SLOT + i;
}

thresholdMap[0] = KICK_THRESHOLD;
thresholdMap[1] = RTOM_THRESHOLD;
thresholdMap[2] = RCYM_THRESHOLD;
thresholdMap[3] = LCYM_THRESHOLD;
thresholdMap[4] = SNARE_THRESHOLD;
thresholdMap[5] = LTOM_THRESHOLD;
thresholdMap[6] = MCYM_THRESHOLD;

noteMap[0] = KICK_NOTE;
noteMap[1] = RTOM_NOTE;
noteMap[2] = RCYM_NOTE;
noteMap[3] = LCYM_NOTE;
noteMap[4] = SNARE_NOTE;
noteMap[5] = LTOM_NOTE;
noteMap[6] = MCYM_NOTE;

}

void loop()
{

// read the pushbutton input pin:
buttonState = digitalRead(buttonPin);
buttonState3 = digitalRead(buttonPin3);

// compare the buttonState to its previous state
if (buttonState != lastButtonState) {
// if the state has changed, increment the counter
if (buttonState == HIGH) {
// if the current state is HIGH then the button went from off to on:
midiNoteOn(50, 127);

} else {
// if the current state is LOW then the button went from on to off:
midiNoteOff(50, 127);
}
// Delay a little bit to avoid bouncing
delay(30);
}
// save the current state as the last state, for next time through the loop
lastButtonState = buttonState;

// compare the buttonState to its previous state
if (buttonState3 != lastButtonState3) {
// if the state has changed, increment the counter
if (buttonState3 == HIGH) {
// if the current state is HIGH then the button went from off to on:
midiNoteOn(60, 127);

} else {
// if the current state is LOW then the button went from on to off:
midiNoteOff(60, 127);
}
// Delay a little bit to avoid bouncing
delay(30);
}
// save the current state as the last state, for next time through the loop
lastButtonState3 = buttonState3;


unsigned long currentTime = millis();

for(short i=0; i<PIEZOS; ++i)
{
//get a new signal from analog read
unsigned short newSignal = analogRead(slotMap[i]);
signalBuffer[i][currentSignalIndex[i]] = newSignal;

//if new signal is 0
if(newSignal < thresholdMap[i])
{
if(!isLastPeakZeroed[i] && (currentTime - lastPeakTime[i]) > MAX_TIME_BETWEEN_PEAKS)
{
recordNewPeak(i,0);
}
else
{
//get previous signal
short prevSignalIndex = currentSignalIndex[i]-1;
if(prevSignalIndex < 0) prevSignalIndex = SIGNAL_BUFFER_SIZE-1;
unsigned short prevSignal = signalBuffer[i][prevSignalIndex];

unsigned short newPeak = 0;

//find the wave peak if previous signal was not 0 by going
//through previous signal values until another 0 is reached
while(prevSignal >= thresholdMap[i])
{
if(signalBuffer[i][prevSignalIndex] > newPeak)
{
newPeak = signalBuffer[i][prevSignalIndex];
}

//decrement previous signal index, and get previous signal
prevSignalIndex--;
if(prevSignalIndex < 0) prevSignalIndex = SIGNAL_BUFFER_SIZE-1;
prevSignal = signalBuffer[i][prevSignalIndex];
}

if(newPeak > 0)
{
recordNewPeak(i, newPeak);
}
}

}

currentSignalIndex[i]++;
if(currentSignalIndex[i] == SIGNAL_BUFFER_SIZE) currentSignalIndex[i] = 0;
}


}


void recordNewPeak(short slot, short newPeak)
{
isLastPeakZeroed[slot] = (newPeak == 0);

unsigned long currentTime = millis();
lastPeakTime[slot] = currentTime;

//new peak recorded (newPeak)
peakBuffer[slot][currentPeakIndex[slot]] = newPeak;

//1 of 3 cases can happen:
// 1) note ready - if new peak >= previous peak
// 2) note fire - if new peak < previous peak and previous peak was a note ready
// 3) no note - if new peak < previous peak and previous peak was NOT note ready

//get previous peak
short prevPeakIndex = currentPeakIndex[slot]-1;
if(prevPeakIndex < 0) prevPeakIndex = PEAK_BUFFER_SIZE-1;
unsigned short prevPeak = peakBuffer[slot][prevPeakIndex];

if(newPeak > prevPeak && (currentTime - lastNoteTime[slot])>MIN_TIME_BETWEEN_NOTES)
{
noteReady[slot] = true;
if(newPeak > noteReadyVelocity[slot])
noteReadyVelocity[slot] = newPeak;
}
else if(newPeak < prevPeak && noteReady[slot])
{
noteFire(noteMap[slot], noteReadyVelocity[slot]);
noteReady[slot] = false;
noteReadyVelocity[slot] = 0;
lastNoteTime[slot] = currentTime;
}

currentPeakIndex[slot]++;
if(currentPeakIndex[slot] == PEAK_BUFFER_SIZE) currentPeakIndex[slot] = 0;
}

void noteFire(unsigned short note, unsigned short velocity)
{
if(velocity > MAX_MIDI_VELOCITY)
velocity = MAX_MIDI_VELOCITY;

midiNoteOn(note, velocity);
midiNoteOff(note, velocity);
}

void midiNoteOn(byte note, byte midiVelocity)
{
Serial.write(NOTE_ON_CMD);
Serial.write(note);
Serial.write(midiVelocity);
}

void midiNoteOff(byte note, byte midiVelocity)
{
Serial.write(NOTE_OFF_CMD);
Serial.write(note);
Serial.write(midiVelocity);
}

0
None
JustinM305MusaM14

Reply 10 months ago

Digital inputs? Or extra analog inputs? If you need more analog inputs then you need the Arduino MEGA.

0
None
joshuaj3180

5 months ago

I found out how to use the rock band cymbals too. all you have to do is add 3 volts at the tip and the other 2 wires for the piezos sensor.


RBC.jpg
0
None
BBQ Bee

Question 6 months ago

hi, one question:

if you have even more than 16 piezo sensors (arduino mega is not enought), are multiplexer the way to go? are they suitable for this, or are there other solutions?

thanks

0
None
JustinM305mishkad

Answer 10 months ago

Totally, I bought those, but I suggest you to find other channels that have build this pads in ways that give a better feeling and a better response to the touch.

0
None
JustinM305AndrewM437

Reply 10 months ago

Not really, refer to answers above for answer xD

0
None
toateot

2 years ago

For the Guitar Hero set...

Does the MIDI message travel through the Uno USB?

Or does the MIDI message still travel through the MIDI port? If this is the case then I will need a MIDI to USB converter cable for a computer connection?

2 replies
1
None
5ki11Zztoateot

Reply 1 year ago

i dont know if this question is still up to date, but for future people having the same qestion: you will need an extra midi to usb cable, the ardunio cable will be used just for power, not midi ^^

0
None
JustinM3055ki11Zz

Reply 10 months ago

Yes, you need a MIDI - MIDI (I am using this method) so the DAW or drum software you are using can read the velocity of the notes. The USB connection to the Arduino is just for uploading the code and powering. In addition, the MIDI - USB needs extra software to make it work, while the MIDI - MIDI needs a audio interface or MIDI interface.

0
None
Jovo1995

1 year ago

Could someone please help me build the pcb? I’m not firmilular with using pcb. Only ever used breadboard. I have everything working (need to sort the thresholds of each pad out. Because some hits don’t read and some lag way after) I just need to get it on pcb and add a midi port as the rockband set doesn’t have one. Thank you.

1 reply
0
None
JustinM305HarshanaH

Reply 10 months ago

Add 2 more 1M resistors and follow the same schematic as the other resistors. You will need Arduino MEGA since you will be using 2 extra analoge inputs.

0
None
РомаС4

2 years ago

Help me guys (
I've done everything. Everything works. But there are always some extra sounds

1 reply
0
None
JustinM305РомаС4

Reply 10 months ago

Sensitivity issues probably, that is a common issue with DIY pads, but if you are using the rock band/GH controller then check the code part.

0
None
Maarkaus

2 years ago

So I have been given a set of these drums, and I happen to have an Arduino mega.

I would very much like to do this, but have 2 questions first.

1. How do you connect this to the computer? Directly with USB to USB from the Arduino? or with the midi port and a USB adapter? If its by adapter can someone recommend one? I dont want to fry a USB port.

Second, how is it powered? By Wall wart or USB? I suspect Wall wart, but its not covered here.

I will look around the internets to see if I can find the answer. If I do I will post, but so far no success.

If anyone knows, please help! thank you