Sending MIDI signals using Arduino

Hello,
i have a few questions for you.

I want to create a MIDI controller with buttons, pots and sliders. (i know that there're many topics about this!)
But it's the first time I try to do something like this and I really want to understand what I'm doing... I don't want to copy and paste codes from the net.

just to understand everything better, i'll now use only one button. as soon as it gets hit, a signal is sent to my computer (I'm using a Mac).
it is then handled by Serial to Midi converter (http://spikenzielabs.com/SpikenzieLabs/Serial_MIDI.html) and then something happens (i'll map that button to a specific action,such as Play/Pause, in Traktor).

I've set up 2 midi ports using the IAC driver.

I understand that if the button is pressed, a noteOn signal is sent.
it is made up of 3 elements:
a status byte and two data bytes (pitch and velocity).

so a noteOn method should be like this:

noteOn(byte statusbyte, byte pitch, byte velocity){
Serial.print(statusbyte);
Serial.print(pitch);
Serial.print(velocity);
}

as soon as the button isn't pressed anymore, a noteOff signal is sent.
that is like a noteOn signal but velocity is set to 0.

void noteOff(byte statusbyte,byte pitch){
  Serial.print(statusbyte);
  Serial.print(pitch);
  Serial.print(0);
}

what values should i set for each byte sent?
i know that a status byte has 3 parts (8 bits in total)

  • most significant byte (1)
  • message type (note off = 000, note on=001 ...)
  • channel (from 0 to 15)

i don't know the values for pitch and velocity (<is it the volume?)

i set baud rate at 57600. but Serial to midi converter doesn't seem to be working because there's a red light at the bottom.

thanks for your help

Read the part of the Serial MIDI page that says "A little bit about MIDI".

Playing a single A4 note at medium volume for 1/10th of a second would look like this:

const byte noteOffCommand = 0;
const byte noteOnCommand = 1;

byte channel = 0;  // Channel 1  (0-15 selects channel 1-16)

byte pitchByte = 69;  // A4 = Middle A = 440 Hz (Piano keyboard runs from 21/A0 to 108/C8)
byte velocityByte = 64;  // Medium Velocity/Volume (value from 0 to 127)

Serial.print(0x80 + (noteOnCommand << 4) + channel, BYTE);
Serial.print(pitchByte, BYTE);
Serial.print(velocityByte, BYTE);

delay(100); // Note duration

Serial.print(0x80 + (noteOffCommand << 4) + channel, BYTE);
Serial.print(pitchByte, BYTE);
Serial.print(velocityByte, BYTE);
Serial.print(pitchByte, BYTE);

Note if you are using arduino 1.0 this will have to be:-

Serial.write(byte(pitchByte));

what values should i set for each byte sent?
i know that a status byte has 3 parts (8 bits in total)

  • most significant byte (1)
  • message type (note off = 000, note on=001 ...)
  • channel (from 0 to 15)

The first two part are normally combined into 1, it is easier to use hex notation, so a note on would be 0x90 and a note off 0x80
then simply add the channel number to this, to get the status byte to send.
In software there are channels 0 to 15 which correspond to the MIDI channels 1 to 16

i don't know the values for pitch and velocity (<is it the volume?)

Pitch is the MIDI note number between 0 and 127 - with 60 corresponding to middle C. Each increment up or down is a semitone shift.
Velocity is like volume and again has to be between 0 and 127

Thank you guys :slight_smile: