Arduinos, MIDI and real apps
Since it’s really been a while since I posted here, I’m going to publish my research on getting an Arduino based interface to talk directly to something else via MIDI. This project could easily be expanded to more complex solutions (i.e. not just two momentary switches), could easily use OSC, channel MIDI data across a network, have a more complex user interface. The point with this stage in the project was to get a framework to build new projects from.
When I first started working with Ruby and Cocoa, the RubyCocoa project was pretty elementary, but many leaps and bounds have been made. Thanks go out to bleything and and the RubyCocoa team without whose wonderful work this would not be possible.
Making an interface from scratch with the Arduino at its core
Equipment needed:
- arduino (diecimila or equivalent)
- wire + wire cutters
- breadboard
- selection of resistors (10k preferable)
- switches (any sort, I used momentary)
- computer – mac, linux or pc (mac preferable)
- box of some sort – optional
- soldering iron – only necessary for finishing the project
# Wire a switch – one side to ground and the other to digital input 6. Use the breadboard.
# Put a resistor between the side of the switch connected to ground and +5v.
This is called a pullup resistor and makes the current default to ‘on’ or +5v when the switch is closed. When the switch is open, the voltage remains at 0v.
If you want additional switches, follow the two steps above making sure you use a new resistor each time.
Difficult bit: find a nice box and glue the whole lot into it and plug in a usb cable.
Getting your computer prepared to talk to the Arduino
If you are comfortable with using the terminal, and want a one-step install for the various packages required for this tutorial, try:
MacPorts
To install: go to the MacPorts website and install using the installer there.
Check everything is working by firing up a terminal and typing
port version
which should return
Version: 1.710
Preparing Ruby
All the below are necessary before continuing
Installing (upgrading) Ruby
Ruby is already included in MacOSX, but for compatibility reasons, it’s best to upgrade. If you’re happy with your installation, just continue as is until you come up against any errors. Please note the Ruby included with 10.4 is very old, and possibly broken.
Fire up a terminal (if it isn’t already open from above) and type
sudo port upgrade ruby
Rubygems — required to use the below libraries
Fire up a terminal (if it isn’t already open from above) and type
sudo port install rb-rubygems
MIDIator — Ruby MIDI library
MIDIator allows us to use Ruby to easily create MIDI messages in a simple and comprehensible fashion
Fire up a terminal (if it isn’t already open from above) and type
sudo gem install midiator
Serialport — Ruby Serial Port library
This is installed by default as part of Ruby, but best to upgrade:
sudo gem upgrade ruby-serialport
Easy! Just sit back and watch incomprehensible lines of text scroll by.
Arduino code
The Arduino itself requires code to run. This tells the Arduino what to do with incoming and outgoing data. The language is called Wiring.
Make sure you have the Arduino programming environment installed (from http://arduino.cc)
Use the following code:
To explain, the first block initialises the pins we will use.
The setup() method initialises the pins and serial connection and tells us that they are sending data in to the Arduino.
The loop() method reads the pins every cycle, stores the data in variables and decides what to do with it. In this case, it sends a different value to the computer if the pin is up or down. The swi variable checks if it’s already been sent, and prevents doubling the ‘note on’ value. i.e. it can’t send a note off before it’s sent a note on and vice versa.
/*
sends serial data over usb to be converted by ruby to MIDI..
*/
int inPin1 = 6; // choose the input pin (for a pushbutton) int inPin2 = 7; int val1 = 0; // variable for reading the pin status int val2 = 0; boolean swi1 = false; boolean swi2 = false;
void setup() {
Serial.begin(9600);
pinMode(inPin1, INPUT); // declare pushbutton as input
}
void loop(){
val1 = digitalRead(inPin1); // read input val1ue
val2 = digitalRead(inPin2);
if (val1 == HIGH && swi1 == false) { // check if the input is HIGH (button released)
swi1 = true;
Serial.println(89, DEC);
delay(100);
}
if (val1 == LOW && swi1 == true){ // check if the input is low and it's just been high
swi1 = false;
Serial.println(90, DEC);
delay(100);
}
if (val2 == HIGH && swi2 == false) { // check if the input is HIGH (button released)
swi2 = true;
Serial.println(91, DEC);
delay(100);
}
if (val2 == LOW && swi2 == true){ // check if the input is low and it's just been high
swi2 = false;
Serial.println(92, DEC);
delay(100);
}
}
Building a simple communication script in Ruby
Download the RubyMIDI.zip file and look in the lib folder at usbchecker.rb. This checks to see if the Arduino is present. In short, OSX creates a list of all the USB devices on your computer at /dev/. This script checks for one in the correct syntax for an Arduino, and passes it back to our main program.
Look in the main folder at BasicMIDI.rb. This contains all the information to communicate with the Arduino and change it to MIDI data. The require functions at the top load in the libraries we installed earlier – rubygems, midiator, serialport and the file we’ve just looked at, usbchecker.rb. The first paragraph runs the usbchecker.rb and passes the identity of the Arduino back and initialises it (turns it on and starts communicating with it).
The next paragraph creates a MIDI device with Midiator and tells it to send all MIDI data to CoreMIDI on OSX, also known as the IAC Driver (Load up Audio MIDI setup and have a look).
The whole of the next section is a bit boring, and merely consists in grabbing data from the serial port and converting it into a meaningful format rather than the incomprehensible rubbish that comes across normally. sp.getc.chr grabs a character (getc) from the serial port (sp), and converts it into a real character (chr). The next loop puts it into a string.
Then, if it has something, it decides which one it’s received from the Arduino (see above that we’re sending different numbers according to what’s happening) and sends either a midi note on (midi.note_on(89, 1, 100)) or note off (midi.note_off(89, 1, 0)).
The other parts are failsafes for if it receives a line-end or newline character – the Arduino sends these after each transmission as part of the Serial.println() method.
Magic, that’s all the code explained
We can run this script by opening a terminal, typing ruby and dragging and dropping the BasicMIDI.rb file into the window, then hitting return. It will fail if there isn’t an Arduino present.
Integrating your Ruby script into a fully fledged native MacOSX application
First, go and download Xcode from http://developer.apple.com and install it. This will take a while.
You’ll notice there’s another folder called RubyCocoaUSBApp which contains lots of files and folders and a file ending .xcodeproj which has our Xcode project in it. Open this, and Xcode will open the project. You’ll notice the lib folder is still there, and that AppController.rb has the same code as BasicMIDI.rb above. It’s not necessary to know the structure of the rest of the folders, just that there’s lots of necessary stuff in there that it’s unwise to touch. Just modify the AppController.rb with your code and link it into the MainMenu.nib using Interface Builder – I won’t explain here because it’ll take ages, unless people need me to? Easy peasy.
Next step: Build and Run (Command-R).
This should launch our fully fledged application, which runs when we click on the button. It will display ‘Ready’ when connected and sending MIDI.
Simply connect any MIDI client to the built-in IAC Driver on OSX and away we go.
Oh, and before I forget, here’s the fully fledged application in case you’re having problems compiling using Xcode.

