Contents

UMIDI

UMIDI

A couple of years ago, I made a module for my eurorack that allowed me to use my Korg ES2 sampler to trigger drum modules. The idea was that it could have a TRS MIDI input and gate outputs. The module has been incredibly useful, but I want more! The Teensys are not cheap, and this project used a Teensy 2.0++ so I thought why not use an STM32 Blue Pill instead and do it at a fraction of the cost.

I decided to port the project only to discover that the Arduino MIDI library doesn’t include support for other boards. Weird, right? I don’t know, maybe I didn’t look far enough but I only needed a few things ported so I decided to write my own using what was available from the Arduino framework. And it would be a good learning experience too. Anyway, I found this post with an example that was a really great starting point, and I decided to add a few more things that would allow me to port the code better. The result is a simple (though missing a ton of functionality) library that I can drop/replace with the Arduino MIDI library but works with my BluePill board.

What is UMIDI?

The UMIDI library is a simple Arduino library for handling MIDI messages from gear via the RX and TX pins of a microcontroller which is supported by the Arduino framework. It is meant to be called in the same way to make it easy to port projects from Arduino or Teensy platforms over to the STM 32 boards.

As of the time of its release, the library now supports sending and receiving MIDI note on, note off, control change, and program change messages. It is also capable of receiving MIDI clock ticks, start, stop, and continue. I have not yet added sending clock events however as I only implemented what I needed for my other project.

How Does UMIDI Work?

It works through callbacks, basically every loop it checks to see if there is a new MIDI message, then processes the data and handles calling the appropriate message function. It is intended to work in the same way as the Arduino MIDI library. The difference is that I can pass which pins I want it to use then create the serial MIDI port from it. Of course, this implies that you are using a set of pins that supports RX and TX.

How do I use it?

Download or clone the repo into your project’s /lib folder. Once it is in a path that PlatformIO can use, simply call it into your file using ‘#include UMIDI.h’ as simple as that.

Here is an example of how to use this library to receive NOTE and CC events, a few more examples can be found in the examples folder in the repo.

#include <Arduino.h>
#include <UMIDI.h>

// Create an instance of the UMIDI class
UMIDI midi(PA3, PA2);

// Callback function for handling Note On messages
void handleNoteOn(byte channel, byte pitch, byte velocity) {
  Serial.print("Note On - Channel: ");
  Serial.print(channel);
  Serial.print(", Pitch: ");
  Serial.print(pitch);
  Serial.print(", Velocity: ");
  Serial.println(velocity);
}

// Callback function for handling Note Off messages
void handleNoteOff(byte channel, byte pitch, byte velocity) {
  Serial.print("Note Off - Channel: ");
  Serial.print(channel);
  Serial.print(", Pitch: ");
  Serial.print(pitch);
  Serial.print(", Velocity: ");
  Serial.println(velocity);
}

// Callback function for handling Control Change messages
void handleControlChange(byte channel, byte controller, byte value) {
  Serial.print("Control Change - Channel: ");
  Serial.print(channel);
  Serial.print(", Controller: ");
  Serial.print(controller);
  Serial.print(", Value: ");
  Serial.println(value);
}

// Callback function for handling Program Change messages
void handleProgramChange(byte channel, byte program) {
  Serial.print("Program Change - Channel: ");
  Serial.print(channel);
  Serial.print(", Program: ");
  Serial.println(program);
}

void setup() {
  // Initialize serial communication
  Serial.begin(9600);

  // Initialize the UMIDI library
  midi.begin();

  // Set callback functions for handling MIDI messages
  midi.setHandleNoteOn(handleNoteOn);
  midi.setHandleNoteOff(handleNoteOff);
  midi.setHandleControlChange(handleControlChange);
  midi.setHandleProgramChange(handleProgramChange);
}

void loop() {
  // Check for incoming MIDI messages
  midi.read();
}

Final thoughts

This library is far from complete. But I tried to make this as easy to expand on as possible. I will likely be contributing more as I need more features for my projects, but I encourage others to contribute if they use it and find themselves expanding it too. That’s all for now. I hope you find this useful!

Cheers!