Arduino Drum Machine

Hello,
I am working on building a very large drum machine. I would like to have 16 pads that are lit with one color all of the time, but change to another color when they are struck. I also need each pad to send a MIDI signal when they are hit. I am going to use piezos as sensors because they are cheap and seem to work quite well. I have started by hooking up one piezo sensor and a midi out port to the Arduino using the schematic I found here: http://todbot.com/blog/wp-content/uploads/2006/10/arduino_midi_schematic.png .

I have managed to get an LED to flash when the piezo is hit, but I am having trouble getting a MIDI signal. I used the program "MIDI Monitor" on my mac to read what MIDI data was coming in, and it kept saying that the commands were "invalid".

Here is the code that I am using:

int ledPin = 13   ;    // Led connected to digital pin 13
int piezo1 = 0   ;     // Piezo 1 connected to analog 0
byte val = 0     ;     // variable to store the value read from the sensor pin
int statePin = 0; // variable used to store the last LED status , to toglle the light
byte THRESHOLD = 100;  // threshold value to decide when the detected sound is a knock or not

void setup()  
{
 pinMode(ledPin, OUTPUT); // declare the ledPin  as OUTPUT
 Serial.begin(31250);  // set MIDI baud rate  
}  

void loop(){
 // deal with first piezo
  val = analogRead(piezo1)/4;  
  if (val >= THRESHOLD) {  
   noteOn (144 , 10, 100);
    digitalWrite(ledPin, HIGH);
    delay(1);
    digitalWrite(ledPin, LOW);
  }  
}


// plays a MIDInote doesn't check to see that cmd is greater  than 127 or that data values are less than 127
void noteOn(char cmd, char data1,char data2) {
  Serial.print(cmd, BYTE);
  Serial.print(data1, BYTE);
   Serial.print(data2, BYTE);
}

I got this code from another forum thread (http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1197975890)

What I am wondering is how I can fix my MIDI issue, how I can make it so that the pads are one color until they are hit, in which case they will turn another color and back again, and how I can hook up 16 pads to the 6 inputs on the Arduino. I know that I will need to use a multiplexer for the inputs, and probably one for the outputs too (I need to use 32 separate LEDs). I would like to use something like a 74HC4051, as they are readily available at my local electronics store.

Thank you very much for your help.

I'd suggest using the MIDI library, it's much easier to use.

As to the invalid message problem, does the program actually listen for serial messages? Because MIDI over USB is a totally different protocol (because it has to obey usb protocol) than sending MIDI directly thru a virtual serial port. There's a serial-to-MIDI converter application available on the intarwebs, just do a google search.

As to hardware, are you looking into having velocity sensitivity? If not, then the piezos could be wired as digital sensors, and have a trimmer pot to adjust the sensitivity.

sciguy:
I'd suggest using the MIDI library, it's much easier to use.

As to the invalid message problem, does the program actually listen for serial messages? Because MIDI over USB is a totally different protocol (because it has to obey usb protocol) than sending MIDI directly thru a virtual serial port. There's a serial-to-MIDI converter application available on the intarwebs, just do a google search.

As to hardware, are you looking into having velocity sensitivity? If not, then the piezos could be wired as digital sensors, and have a trimmer pot to adjust the sensitivity.

Thanks for the quick reply, I am using a usb to MIDI cable to connect it to my computer. I don't really care about having the pads velocity sensitive, but I am not sure how I would wire them to the Arduino as digital sensors. I am relatively new to Arduino, and am hoping that this project will help me learn more about the Arduino. Do you happen to know where I might find some sample code to use the MIDI library?

Thanks again for your help

When you install the MIDI library you will also get some examples (found in the File menu Examples submenu in the Arduino SDK), like you get for most libraries you install.

But if the only MIDI you need is to send note on, you can do without the MIDI library. Or if you just want some understanding of how things work it could be a good idea to fix your code before changing to the library.

I don't have time to test (I mean, I have to leave some fun for you!) but something like this should fix your note on function:

void noteOn(byte channel, byte key, byte velocity) {
  Serial.print(0x90 & channel, BYTE);
  Serial.print(key, BYTE);
   Serial.print(velocity, BYTE);
}

And if you thought 10 was the MIDI channel to use for drums, you need to change that to 9. Channels are numbered 1 to 16, but go from 0 to 15 in the protocol.

pellen:
When you install the MIDI library you will also get some examples (found in the File menu Examples submenu in the Arduino SDK), like you get for most libraries you install.

But if the only MIDI you need is to send note on, you can do without the MIDI library. Or if you just want some understanding of how things work it could be a good idea to fix your code before changing to the library.

I don't have time to test (I mean, I have to leave some fun for you!) but something like this should fix your note on function:

void noteOn(byte channel, byte key, byte velocity) {

Serial.print(0x90 & channel, BYTE);
  Serial.print(key, BYTE);
  Serial.print(velocity, BYTE);
}




And if you thought 10 was the MIDI channel to use for drums, you need to change that to 9. Channels are numbered 1 to 16, but go from 0 to 15 in the protocol.

Thanks for all the help,
I tried your new code, but I am still getting "invalid" MIDI signals. Here is my code again:

int ledPin = 13   ;    // Led connected to digital pin 13
int piezo1 = 0   ;     // Piezo 1 connected to analog 0
byte val = 0     ;     // variable to store the value read from the sensor pin
int statePin = 0; // variable used to store the last LED status , to toglle the light
byte THRESHOLD = 60;  // threshold value to decide when the detected sound is a knock or not

void setup()  
{
 pinMode(ledPin, OUTPUT); // declare the ledPin  as OUTPUT
 Serial.begin(31250);  // set MIDI baud rate  
}  

void loop(){
 // deal with first piezo
  val = analogRead(piezo1)/4;  
  if (val >= THRESHOLD) {  
   noteOn (9 , 144, 100);
    digitalWrite(ledPin, HIGH);
    delay(1);
    digitalWrite(ledPin, LOW);
  }  
}


// plays a MIDInote doesn't check to see that cmd is greater  than 127 or that data values are less than 127
void noteOn(byte channel, byte key, byte velocity) {
  Serial.print(0x90 & channel, BYTE);
  Serial.print(key, BYTE);
   Serial.print(velocity, BYTE);
}

Thanks again for the help.

midi data go from 0 to 127. 144 is too high.

pellen:
midi data go from 0 to 127. 144 is too high.

Thanks, but it is still sending "invalid" signals...

Works for me. Tested it with a MIDI out port and USB MIDI interface (running Renoise on the computer to see/hear that notes are triggered properly).

I rewrote the loop slightly rather than connecting some kind of analog input:

void loop(){  
   noteOn (9 , 40, 100);
   digitalWrite(ledPin, HIGH);
   delay(200);
   digitalWrite(ledPin, LOW);
   delay(200);
   noteOn (9 , 40, 0);
}

Setting up MIDI out on a breadboard was on my TODO list anyway and I was really curious how it could not work.

I had several problems with this crappy USB MIDI interface though. Seems like I have to reconnect it now and then for it to respond. Might be connected somehow to the times when I accidentally upload a new sketch with TX still being connected to MIDI out.