Sending MIDI Messages

Introduction

If you completed any of the buzzer projects, you will know by now that there is much fun to be had in making the Arduino create noises. The only issue you might have had is with the quality of the sound. Since MIDI is a serial protocol and the Arduino can generate messages on the serial port, we can use an Arduino to send MIDI signals to a PC and have the PC play the noises using a MIDI synthesizer.

You Will Need

  • 1 x 220 Ohm Resistor
  • 1 x MIDI Jack
  • Jumper Wires
  • USB MIDI Adapter

I used a MIDI jack with pins for mounting on PCBs and soldered it, a resistor and some headers to a small piece of stripboard. Some people solder the wires and resistor directly to the pins - also a nice solution.

Making The Circuit

Arduino Circuit

Connect the MIDI in cable of the USB adapter to the MIDI connector and plug in the USB cable.

Programming The Arduino

In order to hear the notes, you will need to install some software to your PC. I used Virtual Midi Piano Keyboard to view/hear the MIDI playing. Once installed, you will need to make sure that you set up the software to receive MIDI input. With the USB adapter connected and drivers installed (automatic usually), go to the Edit menu and choose MIDI Connections. Complete as shown below,

VMPK MIDI settings

I also changed the base octave setting in the main window to 2. The code will then play all of the notes you can see on the screen with all other settings at their default values.

VMPK MIDI settings

At this point, it is best to close VMPK. In fact, always close VMPK when you are uploading a sketch to the Arduino or pull out the jumper you have in pin 1. VMPK receives some strange messages if you don't and you will miss what is really happening.

The following code plays all of the notes you can see on the screen in order and repeats the sequence when done.

void setup() {
  // Set MIDI baud rate:
  Serial.begin(31250);
}

void loop() {

  for (int note = 0x18; note < 0x53; note ++) {
    //Note on channel 1 (0x90), some note value (note), middle velocity (0x45):
    noteOn(0x90, note, 0x45);
    delay(300);
    //Note on channel 1 (0x90), some note value (note), silent velocity (0x00):
    noteOn(0x90, note, 0x00);   
    delay(100);
  }

}

//  plays a MIDI note.  Doesn't check to see that
//  cmd is greater than 127, or that data values are  less than 127:
void noteOn(int cmd, int pitch, int velocity) {
  Serial.write(cmd);
  Serial.write(pitch);
  Serial.write(velocity);
}

The key part of the sketch is the noteOn procedure and the key parameter is the one labelled pitch. These values are expressed in hexadecimal in this sketch - most references seem to use hex. The value is from 0 - 127 (a 7 bit value) with each number representing a note.

MIDI Note Table

Musical NoteHex Value
C(-1)00
C#(-1)01
D(-1)02
D#(-1)03
E(-1)04
F(-1)05
F#(-1)06
G(-1)07
G#(-1)08
A(-1)09
A#(-1)0A
B(-1)0B
C00C
C#00D
D00E
D#00F
E010
F011
F#012
G013
G#014
A015
A#016
B017
C118
C#119
D11A
D#11B
E11C
F11D
F#11E
G11F
G#120
A121
A#122
B123
C224
C#225
D226
D#227
E228
F229
F#22A
G22B
G#22C
A22D
A#22E
B22F
C330
C#331
D332
D#333
E334
F335
F#336
G337
G#338
A339
A#33A
B33B
C43C
C#43D
D43E
D#43F
E440
F441
F#442
G443
G#444
A445
A#446
B447
C548
C#549
D54A
D#54B
E54C
F54D
F#54E
G54F
G#550
A551
A#552
B553
C654
C#655
D656
D#657
E658
F659
F#65A
G65B
G#65C
A65D
A#65E
B65F
C660
C#761
D762
D#763
E764
F765
F#766
G767
G#768
A769
A#76A
B76B
C86C
C#86D
D86E
D#86F
E870
F871
F#872
G873
G#874
A875
A#876
B877
C978
C#979
D97A
D#97B
E97C
F97D
F#97E
G97F

Challenges

Mess around with the code a little. Send a few notes and make a tune of some sort. With some sensible use of your favourite web search engine, you could find out a little more about MIDI commands and do a little more, ilke vary the instrument being played.

Clearly, the ability to create the sounds themselves is a sufficient basis for all sorts of projects. Use this setup to get your head around what is possible before considering where some more components and adaptations to the sketch will lead.

Most USB MIDI adapters have two MIDI cables, one labelled IN and one labelled OUT. This means that you can connect the output lead to a MIDI device that accepts MIDI IN and use that to play your tune.