Mark Hughes
Published

MIDI Drum Robot

A central hub that takes an incoming midi note message and sends out a corresponding 12V signal to one of ten connected solenoids.

IntermediateShowcase (no instructions)Over 1 day239
MIDI Drum Robot

Things used in this project

Hardware components

Arduino Leonardo
Arduino Leonardo
×1
Linear Solenoid, 12 VDC
Linear Solenoid, 12 VDC
various solenoids were used in the final project depending on how hard each drum element would need to be hit, for example the kick drum utilises a larger more powerful solenoid than the other drums.
×10
Relay 12V 10A
×10
barrel jack connector
×10
momentary switch
×1
Power Supply 12V
×1
Hook Up Wire Kit, 22 AWG
Hook Up Wire Kit, 22 AWG
×1

Software apps and online services

Arduino IDE
Arduino IDE

Hand tools and fabrication machines

Soldering iron (generic)
Soldering iron (generic)
Mastech MS8217 Autorange Digital Multimeter
Digilent Mastech MS8217 Autorange Digital Multimeter
Router
used for cutting and shaping plywood enclosure.
Laser cutter (generic)
Laser cutter (generic)
used for cutting and etching front perspex panel.
Multitool, Screwdriver
Multitool, Screwdriver

Story

Read more

Custom parts and enclosures

Front Perspex Panel

a laser cut and engraved front panel for the enclosure

Schematics

Schematic Midi Drum

a schematic showing how to wire the power supply, on/off switch, reset button, and 5 relays with flyback diodes to the outputs of an arduino leonardo.

Code

MIDI Drum Code

Arduino
// an arduino code, compatible with arduino boards with midi over usb capability, there are 10 outputs that will be triggered by individual midi notes, the midi notes correspond to individual drum kit pieces as standard in midi drum programming, extra trigger notes have been added for alternative drum sounds and a test note that corresponds to a C major scale, easily played using the white keys on a standard midi keyboard.
#include <MIDIUSB.h>

// these are the arduino pins that the solenoids are hooked up to
enum drumPins {kickPin = 0, snarePin = 1, hhPin = 2, crashPin = 3, openhhPin = 4, ridePin = 5, floortomPin = 6, racktomPin = 7, cowbellPin = 8, sidestickPin = 9};

// these are the midi notes that each solenoid triggers on, as well as an alternate for each
enum midiNotes {kickMidi = 36, snareMidi = 38, hhMidi = 42, crashMidi = 49, openhhMidi = 46, rideMidi = 51, floortomMidi = 41, racktomMidi = 48, cowbellMidi = 56, sidestickMidi = 37};
enum midiNoteAlts {kickMidiAlt = 35, hhMidiAlt = 44, snareMidiAlt = 40, rideMidiAlt = 59, floortomMidiAlt = 43, racktomMidiAlt = 50};
enum midiNoteTest {testMidiC = 60, testMidiD = 62, testMidiE = 64, testMidiF = 65, testMidiG = 67, testMidiA = 69, testMidiB = 71, testMidiC2 = 72, testMidiD2 = 74, testMidiE2 = 76};

void setup() {
  // the serial port is just used as a monitor for debugging
  // it is not needed for midi
  Serial.begin(115200);

  // setup pins 0-9 as outputs
  for(int i=0; i<=9; i++) {
    pinMode(i, OUTPUT);
  }
}
 
void loop() {
  //listen for new MIDI messages
  midiEventPacket_t rx = MidiUSB.read();
  processMidi(rx);
}

void processMidi(midiEventPacket_t rx) {
    switch (rx.header) {
    case 0x0:
      // do nothing
      break;

    // note on
    case 0x9:
      handleNoteOn(rx.byte1 & 0xF, rx.byte2, rx.byte3);
      break;
    
      // note off
      case 0x8:
        handleNoteOn(rx.byte1 & 0xF, rx.byte2, 0);
      break;

    // control change
    case 11:
        Serial.print("CC: ");
        Serial.print(rx.byte2);
        Serial.print(":");
        Serial.print(rx.byte3);
        Serial.print("\n");
      break;

    default:
      Serial.println(rx.header);
      break;
  }
}

void handleNoteOn(byte channel, byte pitch, byte velocity) {
  // it is possible to use the actual midi velocity here, just be sure to
  // double to value because midi is 0-127
  // and then change digitalWrite to analogWrite
  if(velocity > 0) {
    velocity = HIGH;
  }

  switch (pitch) {
    case kickMidi:
    case kickMidiAlt:
    case testMidiC:
      Serial.print("Kick: ");
      digitalWrite(kickPin, velocity);
      break;
    case snareMidi:
    case snareMidiAlt:
    case testMidiD:
      Serial.print("Snare: ");
      digitalWrite(snarePin, velocity);
      break;
    case hhMidi:
    case hhMidiAlt:
    case testMidiE:
      Serial.print("HH: ");
      digitalWrite(hhPin, velocity);
      break;
    case crashMidi:
    case testMidiF:
      Serial.print("Crash: ");
      digitalWrite(crashPin, velocity);
      break;
    case openhhMidi:
    case testMidiG:
      Serial.print("Open hat: ");
      digitalWrite(openhhPin, velocity);
      break;
    case rideMidi:
    case rideMidiAlt:
    case testMidiA:
      Serial.print("Ride: ");
      digitalWrite(ridePin, velocity);
      break;
    case floortomMidi:
    case floortomMidiAlt:
    case testMidiB:
      Serial.print("floortom: ");
      digitalWrite(floortomPin, velocity);
      break;  
    case racktomMidi:
    case racktomMidiAlt:
    case testMidiC2:
      Serial.print("RackTom: ");
      digitalWrite(racktomPin, velocity);
      break;  
    case cowbellMidi:
    case testMidiD2:
      Serial.print("Cowbell: ");
      digitalWrite(cowbellPin, velocity);
      break;  
    case sidestickMidi:
    case testMidiE2:
      Serial.print("Sidestick: ");
      digitalWrite(sidestickPin, velocity);
      break;  
    default:
      // print the midi note value, handy for adding new notes
      Serial.print("Note(");
      Serial.print(pitch);
      Serial.print("): ");
      break;
  }

  if(velocity == 0) {
    Serial.println("off");
  } else {
    Serial.println("on");
  }
}

Credits

Mark Hughes
3 projects • 0 followers
Contact

Comments

Please log in or sign up to comment.