Arduino Polyphonic Microtonal Midi Converter

Introduction: Arduino Polyphonic Microtonal Midi Converter

Greatly improved version here!


I wanted to play microtonal scales with my MIDI keyboards, so I made this arduino based device that reads in MIDI notes and sends out corresponding microtonal pitches using MIDI notes and pitchbend values. I wrote the code for n-TET microntonal scales, i.e., equally spaced whole number of notes per octave, but I think it could be easily adapted using a pair of lookup tables to map to any scale.

I relied heavily on this Send and Receive MIDI with Arduino instructable. I recommend becoming familiar with it.

Teacher Notes

Teachers! Did you use this instructable in your classroom?
Add a Teacher Note to share how you incorporated it into your lesson.

Step 1: Acquire Parts and Assemble

I only used two parts.

  • I used the Arduino compatible SparkFun RedBoard. I'm new to Arduino, so I'd love to hear if you have another favorite compatible board.
  • And I used a LinkSprite MIDI Shield. Instead of the shield, if you're feeling industrious, you could build the MIDI in and out ports using the instructable I linked to above.

Step 2: Code

The arduino code is attached below as a text file.

These values should be customized.

#define pitchbendRange 2 // the pitchbend range in semitones
#define octaveSteps 10 // the number of steps in an octave
#define middleNote 60 // tune to this MIDI note - 60 is middle C (0-127)
#define numVoices 16 // use this many MIDI channels (1-16)

I used the above values in the video demo. It shows a Propellerhead Reason rack with 16 piano modules assigned to the 16 MIDI channels. I played two octaves of a 10 TET scale on a keyboard beginning with the D key below middle C and ending on the Bb key above middle C.

You can see that each channel and module are stepped thru as I play each successive note. The reason for doing this is that pitchbend is a channel-wide setting. When playing polyphonically, if every note were sent to a single MIDI channel, then the new pitchbend setting would alter the tuning of previously played but still sounding notes. So I have it cycle through 16 channels so that 16 notes can be played at a time each with their own pitchbend values. If you set numVoices to 1 it works fine with a monosynth.

Stepping thru the main loop, the arduino reads in 3 bytes--one MIDI note ON or OFF at a time. Then it calculates the MIDI note and pitchbend value to send out. Instead of calculating these values dynamically, as I mentioned above I think a pair of lookup tables could be implemented where you precalculate the values to map to. This would allow mapping to any scale.

Next the arduino checks if the command is a note ON and, if so, sends out the mapped note and pitchbend values and increments to the next MIDI channel. If the command is a note OFF, the arduino finds the MIDI channel where that note is ON and turns it OFF.



Update: I made the code (v1.1 attached) more efficient by checking whether the command is a note ON or note OFF prior to doing any calculation.

Also, I did more research using MIDI-OX and the Yamaha CP-33 manual around the second problem in my notes below (step 3) and found that a steady stream of (hex) F8 and (hex) FE MIDI realtime messages are the culprit. I tried to write some code to recognize them quickly and move on like below, but it seemed the arduino could not keep up. I was able to get a note thru the arduino only every few seconds or so.

do {
  command =;
} while (command == 248 || command == 254);

Step 3: Notes

I encountered some problems.

Problem 1: Right after I update the code on the arduino it spits a bunch of junk out of the serial port. I'm guessing this is just the serial port initializing, but it can cause whatever synth is on the receiving end to go into an unexpected state. Nothing bad has happened to my synths, but just be aware.

Problem 2: I tried using a Yamaha CP-33 stage piano as a MIDI controller, but it does not work. The CP-33 manual does not say how to disable MIDI timing messages, and it sends a steady stream of these messages that I suspect jam up the serial port buffer on the arduino. My other MIDI keyboard does not send timing messages and works great.

Be the First to Share


    • Backyard Contest

      Backyard Contest
    • Silly Hats Speed Challenge

      Silly Hats Speed Challenge
    • Finish It Already Speed Challenge

      Finish It Already Speed Challenge

    2 Discussions


    4 years ago on Introduction

    This looks like a really fun project! Thanks for sharing and welcome to the community!