Background:
I am trying to build a set of drums pads, driven by piezo sensors and messages sent via midi to my Mac. I have studied numerous different examples of people doing just this, and their tutorials look stupidly easy but I seem to be missing something because I’m having difficulties.
My setup:
I have an Uno, and for this post I have removed the piezo sensor from the mix to focus on the midi message entirely since that is where I am having problems. From the Uno, I have wired a 5-pin midi female port (using only the three pins required) and run this to a Midiplus Tbox 2x2 (midi to USB hardware) that is plugged into my Mac via USB. I tried using the Hairless app people recommended online, but this caused even more problems. I also wanted a control in the mix so I had something to test against, and was able to hook up my ancient Roland Dr660 drum machine via midi to the same Tbox hardware and test it’s output compared to the Uno. On my Mac I have installed the MIDI Monitor application that people online have suggested for midi debugging. The app prints out all of the midi message information it hears including channel, note, velocity, etc. The wiring diagram for my setup is at the bottom of this post.
The code:
I’ve pared back the code I’m using to be bare-bones to demonstrate the source of my issues. The code is below, commented with what I believe should be doing. The basic idea of this is in the loop:
- Set an initial counter, and in each loop read an individual value from a predefined list (called ‘PadNote’) of midi note values based on the counter.
- Once I have the midi note, I send the message to an external function (called MIDI_TX) which logs all of the values I sent and sends the message using ‘Serial.write’ for the message, note, and velocity. I wait a half second and then send the midi off message the same way, using velocity of 0.
- Increment the count and wait 2 seconds.
#define midichannel 1;
byte status1;
int ct = 0;
int pinAssignments[6] = {
'A0','A1','A2','A3','A4','A5'
};
const byte txPin = 1;
byte PadNote[6] = {
57,58,59,60,61,62
};
void setup() {
pinMode(txPin, OUTPUT);
Serial.begin(115200);
}
void loop() {
// stop after 6 iterations
if (ct == 6){
exit(0);
}
// debug print out Midi note expecting to send
Serial.println("");
char buffer[30];
sprintf(buffer, "Midi note to send: %d", PadNote[ct]);
Serial.println(buffer);
// send message, Midi note, and velocity
MIDI_TX(144,PadNote[ct],100);
// wait just half a sec' here
delay(500);
// send Midi off
MIDI_TX(144,PadNote[ct],0);
// increment my count and wait for 2 seconds
ct++;
delay(2000);
}
void MIDI_TX(byte MESSAGE, byte PITCH, byte VELOCITY)
{
// debug print out all of the values being sent
char buffer[60];
sprintf(buffer, "status: %d, PITCH: %d, VELOCITY: %d", status1, PITCH, VELOCITY);
Serial.println(buffer);
// send the Midi message
status1 = MESSAGE + midichannel;
Serial.write(status1);
Serial.write(PITCH);
Serial.write(VELOCITY);
}
The questions:
- One piece of the code that I haven’t wrapped my brain around is what is the actual message being sent via midi? All the examples I’ve seen show sending three ‘Serial.write’ commands, the first value being the one I don’t understand, the second being the midi note itself, and the third being the velocity. A lot of the examples I’ve seen use 144 for the first value, but I don’t know what this corresponds to. Other people online have said I can’t send above 127 so I’ve tried using 127 instead of 144 and I get the same results. It’s my understanding that I can’t send above 127 for the note itself, being that midi is 0-127. So what is the 144 here (and why does it show as 145 in the logs)?
- When I hook my Roland drum machine to the midi USB converter and hit a pad, I see a single midi on and a single midi off message in the MIDI Monitor app. The note is the exact value of the note I have programmed the drum machine to send. When I hook the Uno to the midi USB converter and run the loop, I see multiple midi on messages for each loop iteration and the notes sent don’t match the midi note I log to the Arduino Serial Monitor in my loop. Sometimes the messages don’t get sent at all. Note the timestamps of six iterations of my loop below:
Serial Monitor
13:48:49.838 -> Midi note to send: 57
13:48:49.838 -> status: 0, PITCH: 57, VELOCITY: 100
13:48:49.838 -> ⸮9dstatus: 145, PITCH: 57, VELOCITY: 0
13:48:52.338 -> Midi note to send: 58
13:48:52.338 -> status: 145, PITCH: 58, VELOCITY: 100
13:48:52.338 -> ⸮:dstatus: 145, PITCH: 58, VELOCITY: 0
13:48:54.830 -> Midi note to send: 59
13:48:54.867 -> status: 145, PITCH: 59, VELOCITY: 100
13:48:54.867 -> ⸮;dstatus: 145, PITCH: 59, VELOCITY: 0
13:48:57.343 -> Midi note to send: 60
13:48:57.343 -> status: 145, PITCH: 60, VELOCITY: 100
13:48:57.343 -> ⸮<dstatus: 145, PITCH: 60, VELOCITY: 0
13:48:59.854 -> Midi note to send: 61
13:48:59.854 -> status: 145, PITCH: 61, VELOCITY: 100
13:48:59.854 -> ⸮=dstatus: 145, PITCH: 61, VELOCITY: 0
13:49:02.337 -> Midi note to send: 62
13:49:02.371 -> status: 145, PITCH: 62, VELOCITY: 100
13:49:02.371 -> ⸮>dstatus: 145, PITCH: 62, VELOCITY: 0
MIDI Monitor
Timestamp Source Action Channel Note Velocity
13:48:52.450 From Midi In 1 Note On 2 24 2
13:48:52.451 From Midi In 1 Note On 2 16 80
13:48:52.452 From Midi In 1 Note On 2 0 16
13:48:52.452 From Midi In 1 Note On 2 66 16
13:48:52.453 From Midi In 1 Note On 2 6 38
13:48:52.454 From Midi In 1 Note On 2 8 48
13:48:52.455 From Midi In 1 Note On 2 48 67
13:48:52.455 From Midi In 1 Note On 2 0 72
13:48:52.456 From Midi In 1 Note Off 2 2 0
13:48:52.953 From Midi In 1 Note On 2 0 88
13:48:52.953 From Midi In 1 Note Off 2 1 99
13:48:52.954 From Midi In 1 Note Off 2 38 67
13:48:52.955 From Midi In 1 Note Off 2 0 71
13:48:54.953 From Midi In 1 Note Off 2 97 2
13:48:54.954 From Midi In 1 Note Off 2 80 80
13:48:54.955 From Midi In 1 Note Off 2 0 16
13:48:54.955 From Midi In 1 Note Off 2 36 0
13:48:57.456 From Midi In 1 Note On 2 24 2
13:48:57.457 From Midi In 1 Note On 2 80 80
13:48:57.457 From Midi In 1 Note On 2 0 80
13:48:57.458 From Midi In 1 Note On 2 67 16
Bottom line:
I’ve never worked with Arduino before so this is my first project, but I’m a software engineer by trade so the code makes sense. I’ve removed all of the variables that I can think of to focus on the issues themselves, but can’t see why the Uno is sending multiple wrong notes (midi on) and no midi off messages. The problem with debugging this is that everything in the Arduino realm seems to be working (code and debug message) but it’s after it leaves Arduino sphere that things get weird. I’m hoping someone has some idea where my setup could be going wrong?
