Rack Mount MIDI Meters

Eight small colour screens display MIDI data, in a 1U rack format

Public Chat
Similar projects worth following
Eight 240x240 pixel colour screens are mounted on a custom carrier board, and controlled by a Teensy 4.0 microcontroller. A custom MIDI DIN input module provides MIDI 1.0 data to the Teensy. Power is provided to the system via a USB-B connector.

The firmware was developed with Arduino. The background image was licensed from a stock photo site, the PNG image converted into a hex data array, and then that PNG data interpreted by an Arduino library. Another Arduino library was adapted for driving the displays.

MIDI Control Change messages are interpreted into needle angle. The needle is drawn over the PNG image, a simple one-pixel wide line without anti-aliasing. The MIDI channel and controller numbers are hard-wired on the first version of the firmware. It is about as simple a meter implementation as possible.

The front panel holes were cut with a waterjet.

The idea for this project came from a brainstorming session with my friend Jerry. We were trying to come up with a good application for circular TFT LCD displays. Meters of course came to mind, there was a time when they were usually circular. Then it occurred to me that these displays were small enough to fit into the very limited vertical space of a 1U rack box. And with these one could create a meter array like on old mixing consoles. 

Console meters are normally rectangular, and the same idea would have worked with rectangular screens...but whatever. How the mind works, nobody knows.

So we ordered some of the displays, and got to work on a board for mounting them. Jerry helped me to create the board in Kicad. I have been an Eagle user, soon to change over to Kicad. The dimensions were too big for my free Eagle license, and my paid-for Eagle license disappeared when that software changed ownership.

The board is largely just a means of mounting the screens. It has a few connectors on it, and a 74HC138 which enables the MCU to select a display, but requiring fewer signal lines. The MCU outputs the number of the display (0-7) then proceeds as it would normally if talking to only one display. 

I chose the Teensy 4.0 because for its high throughput, as I imagined driving multiple displays might require that in the worst case. With this simple meter, its just line drawing, and line erasing, which most likely could be done with a less capable chip.

The Teensy is mounted on a breakout board that I created earlier. Its part of a set of boards I made for prototyping rack mount systems. Its mostly just an MCU socket broken out to some connectors. The serial ports interface at 5 volts, because that was what MIDI and DMX needed. So its got some level shifters on it. I also had the SPI port brought out at 3.3V on a 2x3 header with same pinout as the Atmel ICSP (Arduino programming port). That is used for writing the displays, though I messed up the pinout on one of the boards, and so used Dupont jumper wires to connect, rather than a ribbon cable as intended.

The Arduino code utilizes the PNG decoding library from Larry Bank. Also it uses code from The needle drawing and GC9A01 driver were adapted from his code.


The main project file. All the application logic is contained here.

ino - 17.74 kB - 05/27/2022 at 19:32



Just a empty array at the moment. Its meant to be a PNG file, turned into a C array. I will provide an image ASAP.

h - 55.00 bytes - 05/27/2022 at 19:31



The display driver.

cpp - 10.06 kB - 05/27/2022 at 19:31


  • 8 × 1.28" Round TFT LCD Display Module, 240x240, GC9A01
  • 1 × Teensy 4.0
  • 1 × Hammond 1U 19" Rack Box
  • 1 × DIN MIDI receiver module
  • 1 × 74HC138 decoder IC

  • First Project Code Release

    Tom Dowad05/27/2022 at 19:47 0 comments

    This is missing the image, I'm creating a new one so I can provide that without copyright issues. But the image file is there so you can see the form. Or make your own. Get a 240x240 PNG @ 16 bits-per-pixel. Use your favourite language to convert the file into a C array. I haven't yet found the code I used for that...I'll share it when I find it or rewrite it.

    I put the display driver in a separate file, because the .INO was getting a bit big, and so the display driver as a component could more easily be swapped. 

    The form of the MIDI receiver -> value -> display is in place. So its easy to follow the design pattern and create new views.

    The needle physics has been moved over from the test code into the Arduino project. Because the sampling rate differed from the test code, the constants were different. The algorithm is, I believe, identical. The result of needle physics is that the needle will not instantaneously pop from one position to another without moving through the space between, and when it arrives at its destination, it tends to overshoot then bounce back. Also it will tend to bounce off the hard stops at each end.  

    Any questions, let me know. I will improve the commenting as needed.

  • Pitch Wheel Message Intepreter

    Tom Dowad05/19/2022 at 02:50 0 comments

    The meter box has so far been only a set of VUs, but my intention is to interpret a range of MIDI message types into different displays. A few days ago I got the pitch wheel message display working, though it has no PNG background image yet.

    The pitch wheel message carries 14-bit value, that is interpreted as positive or negative. Typically the full scale positive and negative values will result in a pitch change up or down one octave.

    This is quite straightforward to convert into a display, using the same needle as with the VUs. A few parameters in the needle line drawing function needed to be changed to get the needle to move in a way appropriate to the task.

    There was one surprise. I had just bought the keyboard controller through craigslist, and was not familiar with its operation. At first I was thrown by the MIDI activity, so I used my protocol analyser to have a look. It turned out this device uses MIDI's running status. With running status, the device sends the pitch wheel command once, then any number of the 14-bit values after that, as long as no other MIDI messages needing to share the cable. So running status was coded into the message interpreter.

  • Simulating Needle Physics

    Tom Dowad05/17/2022 at 20:35 0 comments

    There was some interest in the skeuomorph aspect of this project. That is, new tech simulating old. So I reckoned I might as well follow that thread. I got some new PNG images on order, inspired by vintage meters. And I reckoned I might as well get the needles moving in a way that is more realistic, ie simulating physics.

    Maker [sjm4306] did it in this project:

    I had a look at the code for that project. While I'm sure its quite accurate, I couldn't get my head around the PI method used. But I did pick up something from this implementation: that physics only required a few lines of code.

    I didn't really understand how one of these meters worked either. So I went to Youtube, what else? This video was helpful:

    I knew about the spring and the magnet, but I was surprised to learn about the damper, and how it was implemented. I could see the hard stops on each end. I had certainly "pinned" one of these needles in my day, but never seen the inner mechanics of it.

    I was just about to jump into writing C code, then realized it might not be as easy as imagined. I often write code in Xojo, a VB-like language, for testing algorithms. Its fast, inputting values is easy, and it has a good debugger. VB is, like most languages, similar to C.  And it was only a half-dozen lines of code.

    Here is the code I settled on:

    It is not the definitive physics simulation, but I am happy enough with the results.

    Here is the simulation running:

    Sorry its just a screen capture and no voice over. I will do time.

    The PULL setting is meant to simulate the amount of force applied by the spring (to the left) and the magnet (to the right). As it is increased, the needle moves faster. If set to 0.0 the needle won’t move at all.

    The DAMPING setting is meant to simulate the damper, which is a drag on the needle movement and slows it down. In the code its as a multiplier on the velocity. If set to 1.0, the needle will oscillate, forever apparently. If set to 0.0, the needle will not move.

    The VALUE setting only changes on mouse button release, not when dragging the slider. You’ll see when it changes as there is a numeric field up top.

    Toward the end of the video I move the slider to minimum and maximum positions. Look for the needle bouncing off of the hard stops on either end.

    I’ll get this algorithm into the rack unit shortly.

  • Some Video

    Tom Dowad05/14/2022 at 05:18 0 comments

    I just made a short phone video to show the meters in operation:

    In order to get a MIDI data stream to demonstrate the workability of 8 meters running simultaneously over one MIDI DIN cable (31250 baud), I programmed another MCU to generate it. That MCU generated sine waves, with a range of 0-127, then as each wave value would change, it output the value in a Control Change message. 

    My math on this is that all 8 displays could be updated about every 8 milliseconds. Given that a video frame rate of 30 frames-per-second (33 ms/frame) is generally adequate for smooth animation,  32 channels could be transmitted on one MIDI 1.0 cable. That would saturate the MIDI stream. 

View all 4 project logs

Enjoy this project?



andriy.malyshenko wrote 05/27/2022 at 10:05 point

Hi Tom, those gauges look neat. Any chance you'd share the final code? I'd like to reuse it in ESP32-audio projects

  Are you sure? yes | no

Tom Dowad wrote 05/27/2022 at 13:06 point

Sure will. I wanted to clean it up a bit. That is mostly done, and I've integrated the physics algorithm. I'll have one more go at it and put it up later today.

  Are you sure? yes | no

andriy.malyshenko wrote 05/27/2022 at 18:59 point

No worries, I'm willing to wait. Although don't hold up due to the code quality, any code is appreciated:)

  Are you sure? yes | no

Tom Dowad wrote 05/27/2022 at 17:26 point

I'm going to have to swap out the bitmap. I'm creating a new one. Not sure when that will be ready.

  Are you sure? yes | no

Tom Dowad wrote 05/27/2022 at 19:27 point

I can't see how to upload to the Files section.

  Are you sure? yes | no

Tom Dowad wrote 05/27/2022 at 19:34 point

Ok got it. The three files should be in one folder called midi_dashboard

  Are you sure? yes | no

Similar Projects

Does this project spark your interest?

Become a member to follow this project and never miss any updates