STM32 based MIDI controller

If you do orchestral programming, you know that MIDI faders are absolutely essential to achieve a sound that wouldn’t be passed of as “MIDI-like”. What happens when you really, really want a MIDI controller with a bunch of faders, but don’t feel like spending *that much* money on one?

Well, you build one.

In this series of posts, I will present my take on the DIY MIDI controller, which has 4 faders, 4 rotary encoders, and a 4×4 key matrix, all of which are fully programmable via an onboard LCD. Instead of designing a custom PCB for this project, which, in hindsight, would have greatly simplified its development, especially when it came to writing the firmware, I chose to use whatever I had on hand, which meant:

  • Generic Blue Pill (STM32F103C8T6), which did NOT have nearly enough IO pins
  • 2 MCP23017 I2C IO Expanders: one driving an LCD and the other driving an LED Matrix
  • 2 CD4051 Multiplexers interfacing the 5 rotary encoders

Turns out, not getting a microcontroller that has enough IO pins is really just asking for trouble, as the firmware for this thing could only be described as an abomination. Too many things running concurrently, all having rather strict timing requirements. I will present to you the many challenges I faced trying to get everything to work correctly together while still maintaining the responsiveness of the user interface and inputs, and how I eventually solved all of them.


But first, an overview of what’s to come

The hardware is pretty routine stuff: various components connected to a microcontroller dev board in (mostly) the way you’d expect. There are a few interesting bits which arised as a result of me using all those IO expanders though, and I will cover them one by one as the series progresses.

But here is a quick overview:

  • User Interface
    • 4 faders for individually assignable MIDI CC control
    • 4 pushable rotary encoders to trigger notes and do additional MIDI CC control. All individually assignable, and each accompanied by an LED whose intensity corresponds to the value of the currently assigned CC channel.
    • 4×4 key matrix with Gateron Yellow keyswitches, accompanied by
    • 4×4 bi-color LED matrix to indicate the position of all the C keys
    • 16×2 character LCD for menu and status display
    • 1 pushable rotary encoder to navigate through the menu
  • Electronics
    • Microcontroller: STM32F103C8T6 (sorely lacks IO)
    • Faders are connected directly to analog input pins
    • Rotary encoder pushbuttons and the key matrix are also directly connected to digital IO
    • The 4 LED’s are also connected directly, and their brightness is varied using bit angle modulation
    • 2 CD4051 multiplexers, breaking out 2 pins on the micro to the 10 required for the 5 rotary encoders
    • 2 MCP23017 I2C IO Expanders
      • One drives the LCD. Well, sort of. I initially had the LCD completely driven by it, but turns out that all the I2C commands needed to set the control pins just got in the way, so in its current state this MCP23017 essentially drives the 8-bit data bus only.
      • The other drives the LCD Matrix. This one is driven by DMA, so its essentially fully autonomous. I’m really excited to share how I pulled it off, as it involved some *ahem* pretty unorthodox (according to ST’s reference manual anyways) ways of driving the micro’s I2C peripheral.
    • 24LC128 EEPROM to store parameters between on-off cycles
    • Serial over the micro’s USB peripheral to handle the MIDI protocol
    • Power delivery is handled by a generic 3.3v LDO
  • 3D printed case, keycaps, and fader knobs

Instead of a large schematic with everything on it, I think a better approach would be to break it up into sections: a series of posts each containing the schematic of one particular aspect of the hardware, along with a breakdown of the code required to drive it and chronicles of the many hours I spent banging my head on the table trying to fix issues that cropped up. Then, I’ll cap it off with a summary of how it all comes together, and address the various improvements that I think could be implemented.

Here we go!

Leave a Comment

Your email address will not be published. Required fields are marked *