Midi out sending incorrect note values or not sending messages at all

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?

You appear to be using Serial for both debug messages and MIDI messages. Of course, your MIDI device is going to be confused by the debug messages and Serial Monitor will have trouble displaying the binary MIDI messages.

Well that makes perfect sense, now that you say it

144 (0x90) is the basic command for NoteOn. Then you should add on (MIDI channel number-1). So 145 is a NoteOn on MIDI Ch 2. Bytes 2 and 3 are the ones that can only be 0-127.

And are you sure MIDIPlus TBox will accept commands at 115200 baud instead of the MIDI specified 31250?

Steve

Thanks @johnwasser. I wrote a longer reply above and most of it didn't get posted. I'll try removing the debug Serial statements and see if that helps.

Since Serial is the recommended method of debugging, is there another console to write to or another way to log debug statements that won't collide with midi (have to ask, but I'm guessing there isn't)?

You can always move the MIDI output to a SoftwareSerial port on different pins. Then you can run that at the correct MIDI speed. That's probably what most people do.

Steve

slipstick:
144 (0x90) is the basic command for NoteOn. Then you should add on (MIDI channel number-1). So 145 is a NoteOn on MIDI Ch 2. Bytes 2 and 3 are the ones that can only be 0-127.

And are you sure MIDIPlus TBox will accept commands at 115200 baud instead of the MIDI specified 31250?

Steve

Ah, thank you for that explanation! I saw other examples that used 0x90 instead of 144 and didn't understand that either, so this is good info.
And no, I'm not sure about the baud rate (still don't have a grasp on that piece of the puzzle either). I can try switching to the midi specified rate as you mentioned. That's another good thing for me to check.

These have been great suggestions, and I'm getting closer after removing the extra debug statements and setting the baud rate to the midi recommended rate. I'm now getting very different strange behaviour.

#define midichannel 1;
byte status1;
int ct = 0;
const byte txPin = 1;

void setup() {
  pinMode(txPin, OUTPUT);
  Serial.begin(31250);
}

void loop() {
  // stop after 6 iterations
  if (ct == 6){
    exit(0);
  }

  // send message, Midi note, and velocity
  MIDI_TX(144,65,100);

  // wait just half a sec' here
  delay(500);

  // send Midi off
  MIDI_TX(144,65,0);

  // increment my count and wait for 2 seconds
  ct++;
  delay(2000);
}

void MIDI_TX(byte MESSAGE, byte PITCH, byte VELOCITY) 
{
  // send the Midi message
  status1 = MESSAGE + midichannel;
  Serial.write(status1);
  Serial.write(PITCH);
  Serial.write(VELOCITY);
}

Now I only get 3 midi messages per loop but the channel is wrong (sending on 9 instead of expected 2) and the note is wrong. I hard-coded the midi note to 65 and I get the following results, but if I hard-code it to 60-62 or 64 I get no results. If I use 63 I get "invalid" messages (see bottom of logs below).

Timestamp	Source		Action		Channel	Note	Velocity
15:32:32.157	From Midi In 1	Note Off	9	0	76
15:32:32.158	From Midi In 1	Note Off	9	95	19
15:32:32.658	From Midi In 1	Note Off	9	55	95

15:32:34.658	From Midi In 1	Note Off	9	0	55
15:32:34.659	From Midi In 1	Note Off	9	95	19
15:32:35.159	From Midi In 1	Note Off	9	55	95

15:32:37.159	From Midi In 1	Note Off	9	0	55
15:32:37.160	From Midi In 1	Note Off	9	95	19
15:32:37.660	From Midi In 1	Note Off	9	55	95

15:32:39.660	From Midi In 1	Note Off	9	0	55
15:32:39.661	From Midi In 1	Note Off	9	95	19
15:32:40.161	From Midi In 1	Note Off	9	55	95

15:32:42.161	From Midi In 1	Note Off	9	0	55
15:32:42.162	From Midi In 1	Note Off	9	95	19
15:32:42.662	From Midi In 1	Note Off	9	55	95

15:32:44.662	From Midi In 1	Note Off	9	0	55
15:32:44.663	From Midi In 1	Note Off	9	95	19
15:32:45.163	From Midi In 1	Note Off	9	55	95

// logger when using '64'
15:43:22.936	From Midi In 1	Invalid			1 bytes
15:43:25.437	From Midi In 1	Invalid			1 bytes
15:43:27.938	From Midi In 1	Invalid			1 bytes
15:43:30.439	From Midi In 1	Invalid			1 bytes
15:43:32.940	From Midi In 1	Invalid			1 bytes
15:43:35.441	From Midi In 1	Invalid			1 bytes

I should only be sending two midi messages per loop- a half second apart- and one should be on and one should be off. The other confusing thing about this is that all the "note off" messages show velocity of non-zero which doesn't make sense.

That log seems to bear no connection to the code you have posted. Wrong status and channel and both note and velocity are all over the place and are never the values you have in the program. Are you sure that really is the code that you have loaded?

It's worth checking the MIDI output connections/resistor values carefully though I imagine you have already done that. What program is producing the log?

As I said before I'd move the MIDI connection to a SoftwareSerial connection on e.g. pins 2&3 so you still have Serial available for debug messages. Then you can see exactly what you're sending. But it is starting to seem possible that it's external equipment that is messing things up

Steve

It's worth checking the MIDI output connections/resistor values carefully

Very true. Although it wasn't the ultimate root cause of my issue, I was using 220k ohm instead of 220 ohm resistors.

it is starting to seem possible that it's external equipment that is messing things up

Also very true. Once I identified the resistor issue and found that I was receiving incorrect messages on incorrect channels at the precise moment I should have, I replaced my spliced female midi cable that I had been using with a 5 pin female midi jack (it just came in the mail- I couldn't test this before) and everything is working as expected.
Thanks for all the help with this!