Filtering MIDI Pitch Bend Messages Using Arduino

Jake Spracher
4 min readOct 1, 2023

The Pitch Bend Dilemma

While I mostly write software and consult for startups, I also produce music as Prophisee. Recently, my MIDI piano keyboard started having a major problem: the pitch bend wheel potentiometer was malfunctioning, effectively rendering the device useless by adding awful “warbling” to every recording. The internal design was very unfriendly to DIY repair, and support was useless (thanks private-equity-owned M-Audio!). Instead of replacing the entire keyboard, I decided to employ a highly over-engineered solution. The plan? Filter out all MIDI pitch bend messages using a $28 Arduino.

A midi piano keyboard
The culprit

Setting the Stage

To effectively filter the messages, I configured my setup as follows:

  • MIDI Output from Keyboard: A standard MIDI cable was used to carry the MIDI signals from the keyboard to the Arduino.
  • Arduino Uno: I used the Uno for the filtering process. To interface with the MIDI signals, I added a MIDI Shield to the Arduino. This shield provides the necessary hardware to read and send MIDI messages.
  • Computer: Post filtering, the Arduino sends the MIDI messages to the computer through its USB connection like any typical MIDI instrument.
The Arduino UNO with the midi shield attached on top and USB and MIDI cables connected.
The contraption

The MIDI Library

To read, process, and send MIDI messages on the Arduino, I utilized the Arduino MIDI Library. It provides a set of tools to work with MIDI data easily, making our task much more straightforward.

Transforming Arduino into a MIDI Device

One challenge was ensuring the computer recognized the Arduino as a MIDI instrument. By default, the Arduino Uno is seen as a virtual serial port over USB. To get around this, we needed to update the firmware of the Arduino’s USB interface chip. This process required the use of a specific firmware called ‘mocoLUFA’.

However, the main branch of mocoLUFA had some compiler errors on build. Luckily, there was an open pull request with the necessary fixes. I built the firmware using that branch and detail the process below.

Device Firmware Update (DFU) Mode

To upload the new firmware to the Arduino, we had to put the Arduino into DFU mode. Here’s how:

  1. Locate the 6-pin ICSP header on the Arduino Uno.
  2. Short the pins closest to the USB connection (GND and RST).
  3. Reset the Arduino.
  4. Release the short. If successful, the Arduino would enter DFU mode, making it ready to accept new firmware.
Circled in red: two pins closest to the USB input end of the board on the 6 pin pad.
Short these. I had to try a few times.

Building and Loading the Firmware

Using the dfu-programmer tool, which can be installed via homebrew on macOS, I then built and flashed mocoLUFA firmware onto the Arduino.

### Install the firmware programmer and AVR compiler ###
$ brew install dfu-programmer
$ brew tap osx-cross/avr
$ brew install avr-gcc
### Build the firmware ###
$ curl -O <http://www.fourwalledcubicle.com/files/LUFA/LUFA-100807.zip>
$ unzip LUFA-100807.zip
$ git clone <https://github.com/kmontag/mocolufa.git>
$ cd mocolufa
$ git checkout const-errors
$ make clean; make
### Confirm DFU###
$ system_profiler SPUSBDataType
...
Product ID: 0x2fef
Vendor ID: 0x03eb (Atmel Corporation)
Version: 0.00
...
### Flash the firmware ###
$ dfu-programmer atmega16u2 erase
$ dfu-programmer atmega16u2 flash dualMoco.hex
Checking memory from 0x0 to 0x157F... Empty.
0% 100% Programming 0x1580 bytes...
[>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>] Success
0% 100% Reading 0x3000 bytes...
[>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>] Success
Validating... Success
0x1580 bytes written into 0x3000 bytes memory (44.79%).

To program the Arduino microcontroller with the new mocoLufa firmware loaded, you must short another set of pins on reboot to put it back into serial mode:

Circled in yellow, two left pins in the bottom row of three relative to the top when usb input is at left.
Short these

The Code: Filtering the Pitch Bend

With the hardware set and the firmware in place, the final step was the Arduino code. Utilizing the MIDI library, I filtered out the pitch bend messages while letting all other MIDI data pass through unaffected. Here’s the code:

#include <MIDI.h>

MIDI_CREATE_DEFAULT_INSTANCE();

void setup() {
MIDI.begin(MIDI_CHANNEL_OMNI);
MIDI.turnThruOff();
}

void loop() {
if (MIDI.read()) {
byte cmd = MIDI.getType();
switch (cmd) {
case midi::NoteOn:
case midi::NoteOff:
case midi::ControlChange:
MIDI.send(MIDI.getType(), MIDI.getData1(), MIDI.getData2(), MIDI.getChannel());
break;
}
}
}

With this in place, the MIDI output from the Arduino had no pitch bend messages, and my keyboard sounded as good as new, sans the pitch bend.

Conclusion

With some quick hacking, we successfully filtered out unwanted MIDI messages from our keyboard output. This DIY solution saved me the headache of using a per-track software filter in Ableton or even replacing the keyboard and was pretty fun.

Shout out to Kevin for this awesome blog that has some more details if your setup is different from mine:

https://diyelectromusic.wordpress.com/2022/03/22/arduino-and-usb-midi/

--

--