Midi - USB adapter issues

Basically, I have followed the Youtube tutorial provided by the channel Notes and Volts about a MIDI in circuit, but I would prefer writing my own code for handling the midi information.

I have figured most of the code and I decided to use the MIDIUSB arduino library available on the library manager. The part on where I'm getting stuck is actually sending the midi message to external programs or VSTs. By simply printing the information on the serial monitor, everything seems to be working alright, but whenever I actually try to place the noteOn or noteOff functions in the place where the printing was happening I am experiencing some weird bugs, such as having to press notes 8 times and after then i actually recieve the signals of the notes pressed.

Here is the code:

#include "MIDIUSB.h"

int byte1;         // 1st byte is command or "status" byte
int byte2;
int byte3;          // 2nd byte is program change number
int theBytes[3];

void noteOn(byte channel, byte pitch, byte velocity) {
  midiEventPacket_t noteOn = {0x09, 0x90 | channel, pitch, velocity};
  MidiUSB.sendMIDI(noteOn);
}

void noteOff(byte channel, byte pitch, byte velocity) {
  midiEventPacket_t noteOff = {0x08, 0x80 | channel, pitch, velocity};
  MidiUSB.sendMIDI(noteOff);
}

void setup() {
  Serial1.begin(31250);
}

void controlChange(byte channel, byte control, byte value) {
  midiEventPacket_t event = {0x0B, 0xB0 | channel, control, value};
  MidiUSB.sendMIDI(event);
}

void loop() {
  if (Serial1.available() >= 3) {
   for (int i=0; i<3; i++) {
   theBytes[i] = Serial1.read();
   }

   byte1 = theBytes[0];
   byte2 = theBytes[1];
   byte3 = theBytes[2];

   Serial.print(byte1);
   Serial.print(", ");
   Serial.print(byte2);
   Serial.print(", ");
   Serial.println(byte3);
  }
}
   

And here is an example of code that is not working and I can't really figure out why:

#include "MIDIUSB.h"

int byte1;         // 1st byte is command or "status" byte
int byte2;
int byte3;          // 2nd byte is program change number
int theBytes[3];

void noteOn(byte channel, byte pitch, byte velocity) {
  midiEventPacket_t noteOn = {0x09, 0x90 | channel, pitch, velocity};
  MidiUSB.sendMIDI(noteOn);
}

void noteOff(byte channel, byte pitch, byte velocity) {
  midiEventPacket_t noteOff = {0x08, 0x80 | channel, pitch, velocity};
  MidiUSB.sendMIDI(noteOff);
}

void setup() {
  Serial1.begin(31250);
}

void controlChange(byte channel, byte control, byte value) {
  midiEventPacket_t event = {0x0B, 0xB0 | channel, control, value};
  MidiUSB.sendMIDI(event);
}

void loop() {
  if (Serial1.available() >= 3) {
   for (int i=0; i<3; i++) {
   theBytes[i] = Serial1.read();
   }

   byte1 = theBytes[0];
   byte2 = theBytes[1];
   byte3 = theBytes[2];

    if(byte3 > 0){
      noteOn(0, byte2, byte3);
      } else if(byte3 == 0){
      noteOff(0, byte2, byte3);
      }
  }
}
   

This code cannot parse MIDI correctly. It is susceptible to framing errors and does not handle running status.

I'd recommend using a library with a well-tested MIDI parser, e.g. Control Surface: MIDI Tutorial.

If you want to implement the parser yourself, check the state machine described in the MIDI specification on midi.org. In particular, check the most significant bit to tell data bytes from status bytes, and use a thirdByte flag to know where you are in the current message.

If you need some inspiration and/or test cases, see Control Surface: SerialMIDI_Parser.cpp Source File and https://github.com/tttapa/Control-Surface/blob/main/test/MIDI_Parsers/tests-MIDI_Parsers.cpp.

Thanks, Pieter! This is definitely a better approach at parsing the MIDI data properly, but I am still getting stuck at actually sending the data in to a program such as FL Studio. By using the MIDIUSB library I still have the problem of nothing being sent unless I press a key several times, only by then the program will play something. I think I should also mention that I have a very old MIDI-only keyboard and am using an Arduino Pro Micro

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.