
The Arduino can make music in many different ways. You can search the internet and find a lot of MIDI schematics and code, as well as a few ways to have the Arduino act as a sound source, emitting its own musical notes.
I went ultra-simple on the hardware. I'm using an Arduino Uno R3 clone that set me back a whopping $7.00. In line with the Junkbox Junkie philosophy, the parts for the circuit cost me around... well, nothing. Zero. Zilch. Nada.
Arduino prototype shields are relatively inexpensive, but since I had a total of 3 components and a wire, I really didn't want to use an entire shield. So I made what I'll call an 'Arduino Bridge'. It's a piece of perfboard I had – yes – in my junkbox. It is wide enough to bridge between the power socket side and the digital out socket side. Two 220Ω resistors, five pins and a female MIDI jack which isn't a MIDI jack, but is a MIDI jack, and the hardware was complete.
So, about this MIDI jack thing. Little known fact: the older IBM clone XT and AT systems used a keyboard with a huge coiled wire thing that plugged into a jack on the main computer. This jack, which isn't a MIDI jack, is a MIDI jack. It's a 5-pin DIN style, exactly the same thing as a real female MIDI jack. So, again with the Junkbox Junkie thing, I desoldered the keyboard jack from a defunct motherboard and used it as my MIDI jack.
The schematic is simple. Here, I feel compelled to mention SAFETY. If you know how to solder and all the relevant safe practices, great. If you don't please consult with someone who does. Just be safe. This project isn't worth pursuing if you damage yourself. Safety glasses and care wielding a 350° soldering iron are in order.
The largest problem is probably making sure to look at the REAR of the MIDI (formerly keyboard) jack while connecting the resistors. I also used a total of five pins to connect to the Arduino. On the power (+5, GND) side, I added a pin to sort of align the bridge when connecting it. On the digital port side, I used pins for digital 11 and 12, again to help guide the plugging in of the board. Pin 11 is the MIDI send signal. Pin 12 would be the receive side of things, if we were sending MIDI back into the Arduino. Which we aren't.
So, that leaves the software. This first code attempt will be pretty lean. Don't expect major symphonic works of art just yet. There are a few 'must haves' in order to even get a MIDI command message sent out of the Arduino. SoftwareSerial is part of the standard libraries included when you download the IDE. We will be using that for the MIDI communication at 31,250 baud. To talk back to the PC, mostly to capture debug messages on the serial monitor, we'll be using the standard Serial object, connected by default to digital pins 0 and 1. We can use 9600 baud for now, but I reserve the right to chuck that up to 115,200 in future applications.
Next time: Some "random" thoughts on how to start generating music.
I went ultra-simple on the hardware. I'm using an Arduino Uno R3 clone that set me back a whopping $7.00. In line with the Junkbox Junkie philosophy, the parts for the circuit cost me around... well, nothing. Zero. Zilch. Nada.
Arduino prototype shields are relatively inexpensive, but since I had a total of 3 components and a wire, I really didn't want to use an entire shield. So I made what I'll call an 'Arduino Bridge'. It's a piece of perfboard I had – yes – in my junkbox. It is wide enough to bridge between the power socket side and the digital out socket side. Two 220Ω resistors, five pins and a female MIDI jack which isn't a MIDI jack, but is a MIDI jack, and the hardware was complete.
So, about this MIDI jack thing. Little known fact: the older IBM clone XT and AT systems used a keyboard with a huge coiled wire thing that plugged into a jack on the main computer. This jack, which isn't a MIDI jack, is a MIDI jack. It's a 5-pin DIN style, exactly the same thing as a real female MIDI jack. So, again with the Junkbox Junkie thing, I desoldered the keyboard jack from a defunct motherboard and used it as my MIDI jack.
The schematic is simple. Here, I feel compelled to mention SAFETY. If you know how to solder and all the relevant safe practices, great. If you don't please consult with someone who does. Just be safe. This project isn't worth pursuing if you damage yourself. Safety glasses and care wielding a 350° soldering iron are in order.
The largest problem is probably making sure to look at the REAR of the MIDI (formerly keyboard) jack while connecting the resistors. I also used a total of five pins to connect to the Arduino. On the power (+5, GND) side, I added a pin to sort of align the bridge when connecting it. On the digital port side, I used pins for digital 11 and 12, again to help guide the plugging in of the board. Pin 11 is the MIDI send signal. Pin 12 would be the receive side of things, if we were sending MIDI back into the Arduino. Which we aren't.
So, that leaves the software. This first code attempt will be pretty lean. Don't expect major symphonic works of art just yet. There are a few 'must haves' in order to even get a MIDI command message sent out of the Arduino. SoftwareSerial is part of the standard libraries included when you download the IDE. We will be using that for the MIDI communication at 31,250 baud. To talk back to the PC, mostly to capture debug messages on the serial monitor, we'll be using the standard Serial object, connected by default to digital pins 0 and 1. We can use 9600 baud for now, but I reserve the right to chuck that up to 115,200 in future applications.
Next time: Some "random" thoughts on how to start generating music.
Test Program for the Arty Bridge:
/*
+-------------------------------------------------+
| Arty The Aleatoric Arduino: test_MIDI |
| Part I of the Arty series |
| Perambulations in the Field |
| of Artifical Music Generation |
| Brought to you by "Junkbox Junkie, the Musical" |
+-------------------------------------------------+
Copyright © 2015 by Bill L. Behrendt
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdarg.h>
#include <stdio.h>
#include <SoftwareSerial.h>
//software serial port pins for MIDI
#define MIDI_OUT 11
#define MIDI_IN 12 //unused
//MIDI command messages
#define CMD_NOTE_ON 0x90 //channel 1
#define CMD_NOTE_OFF 0x80 //channel 1
//global variables
SoftwareSerial MIDI(MIDI_IN, MIDI_OUT); // RX, TX
void flashWorkLED(char start) {
if (start == 1) {
digitalWrite(LED_BUILTIN, HIGH);
delay(250);
digitalWrite(LED_BUILTIN, LOW);
delay(250);
}
for (char tm = 0; tm < 5; tm++) {
digitalWrite(LED_BUILTIN, HIGH);
delay(125);
digitalWrite(LED_BUILTIN, LOW);
delay(75);
}
}
void sendMIDI(unsigned char cmd, unsigned char data1, unsigned char data2)
{
MIDI.write(cmd); //note on or note off
MIDI.write(data1); //MIDI note 0-127
MIDI.write(data2); //velocity (loudness) of note
}
void audioBootTest(void) {
sendMIDI(CMD_NOTE_ON, 36, 64);
sendMIDI(CMD_NOTE_ON, 60, 64);
sendMIDI(CMD_NOTE_ON, 64, 64);
sendMIDI(CMD_NOTE_ON, 67, 64);
sendMIDI(CMD_NOTE_ON, 72, 64);
flashWorkLED(1);
delay(1000);
flashWorkLED(0);
sendMIDI(CMD_NOTE_OFF, 36, 64);
sendMIDI(CMD_NOTE_OFF, 60, 64);
sendMIDI(CMD_NOTE_OFF, 64, 64);
sendMIDI(CMD_NOTE_OFF, 67, 64);
sendMIDI(CMD_NOTE_OFF, 72, 64);
}
void allNotesOff(void) {
//turns off all notes on all MIDI channels
for (int anoff = 0; anoff < 16; anoff++) {
sendMIDI(0xB0 + anoff, 0x7B, 0x00);
}
}
void setup() {
Serial.begin(9600); // for looking at debug things
MIDI.begin(31250); // our software serial MIDI connection
//turn all notes off, all channels then emit a chord
allNotesOff();
flashWorkLED(1);
audioBootTest();
}
void loop() {
// send each MIDI note, one at a time
for (int x = 0; x < 128; x++)
{
sendMIDI(CMD_NOTE_ON, x, 64);
Serial.println(x);
delay(150);
sendMIDI(CMD_NOTE_OFF, x, 64);
}
flashWorkLED(0);
}
/*
+-------------------------------------------------+
| Arty The Aleatoric Arduino: test_MIDI |
| Part I of the Arty series |
| Perambulations in the Field |
| of Artifical Music Generation |
| Brought to you by "Junkbox Junkie, the Musical" |
+-------------------------------------------------+
Copyright © 2015 by Bill L. Behrendt
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdarg.h>
#include <stdio.h>
#include <SoftwareSerial.h>
//software serial port pins for MIDI
#define MIDI_OUT 11
#define MIDI_IN 12 //unused
//MIDI command messages
#define CMD_NOTE_ON 0x90 //channel 1
#define CMD_NOTE_OFF 0x80 //channel 1
//global variables
SoftwareSerial MIDI(MIDI_IN, MIDI_OUT); // RX, TX
void flashWorkLED(char start) {
if (start == 1) {
digitalWrite(LED_BUILTIN, HIGH);
delay(250);
digitalWrite(LED_BUILTIN, LOW);
delay(250);
}
for (char tm = 0; tm < 5; tm++) {
digitalWrite(LED_BUILTIN, HIGH);
delay(125);
digitalWrite(LED_BUILTIN, LOW);
delay(75);
}
}
void sendMIDI(unsigned char cmd, unsigned char data1, unsigned char data2)
{
MIDI.write(cmd); //note on or note off
MIDI.write(data1); //MIDI note 0-127
MIDI.write(data2); //velocity (loudness) of note
}
void audioBootTest(void) {
sendMIDI(CMD_NOTE_ON, 36, 64);
sendMIDI(CMD_NOTE_ON, 60, 64);
sendMIDI(CMD_NOTE_ON, 64, 64);
sendMIDI(CMD_NOTE_ON, 67, 64);
sendMIDI(CMD_NOTE_ON, 72, 64);
flashWorkLED(1);
delay(1000);
flashWorkLED(0);
sendMIDI(CMD_NOTE_OFF, 36, 64);
sendMIDI(CMD_NOTE_OFF, 60, 64);
sendMIDI(CMD_NOTE_OFF, 64, 64);
sendMIDI(CMD_NOTE_OFF, 67, 64);
sendMIDI(CMD_NOTE_OFF, 72, 64);
}
void allNotesOff(void) {
//turns off all notes on all MIDI channels
for (int anoff = 0; anoff < 16; anoff++) {
sendMIDI(0xB0 + anoff, 0x7B, 0x00);
}
}
void setup() {
Serial.begin(9600); // for looking at debug things
MIDI.begin(31250); // our software serial MIDI connection
//turn all notes off, all channels then emit a chord
allNotesOff();
flashWorkLED(1);
audioBootTest();
}
void loop() {
// send each MIDI note, one at a time
for (int x = 0; x < 128; x++)
{
sendMIDI(CMD_NOTE_ON, x, 64);
Serial.println(x);
delay(150);
sendMIDI(CMD_NOTE_OFF, x, 64);
}
flashWorkLED(0);
}
Copyright © 2015 by Bill L. Behrendt