Arduino Touchscreen X-Y MIDI Controller

I have a list of other projects I’d like to use my cheap touchscreen MIDI controller for.  For details see the original discussion here: Arduino Touchscreen MIDI Controller.

In this project I turn it into an “X-Y” controller – essentially a two-dimensional potentiometer.  Moving in the Y direction changes one value and moving in the X direction changes another.

But there are a number of other options I’ve also included:

  • X can be set up to play discrete notes too (represented by the lines).
  • X can also be used as pitch-bend when playing.

Warning! I strongly recommend using old or second hand equipment for your experiments.  I am not responsible for any damage to expensive instruments!

These are the key Arduino tutorials for the main concepts used in this project:

If you are new to Arduino, see the Getting Started pages.

Parts list

The Circuit

This is using the same setup as the Arduino Touchscreen MIDI Controller.  Nothing has changed hardware wise.

IMG_5388

The Code

The basic operation is that the code has to set up a useful display – I’m using series of lines as a reference; detect a touch; and on touch do various things depending on if the touch is static or your finger is moving (and in which direction – the X or Y direction).

IMG_6270

There are several options in the code, all configured using statements at the top of the code.

#define MIDI_CHANNEL 1
#define Y_MIDI_CC 74
//#define X_MIDI_CC 1
#define MIDI_PITCH_BEND

MIDI_CHANNEL is hopefully self-explanatory.  The MIDI CC values to use for each direction are set by the Y_MIDI_CC and X_MIDI_CC values.  Both are optional – if one is commented out, then that axis is not used as a MIDI CC controller.  If MIDI_PITCH_BEND is defined then the X direction will work as a pitch bend controller once touched.  It will bend relative to the original touched position until you take your finger off.

There is an option to include several notes to play as well.  This is setup in an array of MIDI note values at the top.

#define NUM_NOTES 8
uint8_t notes [NUM_NOTES] = {60, 62, 64, 65, 67, 69, 71, 72};
//#define NUM_NOTES 13
//uint8_t notes [NUM_NOTES] = {60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72};

Here are two examples – if the top one is used, we get a standard major scale.  If the bottom one is used, we get a single octave chromatic scale.

The main logic is as follows:

IF touch detected THEN:
work out an equivalent X and Y "potentiometer" value
IF we're moving THEN calculate a pitch bend value (if required)
IF a new touch THEN calculate a MIDI note value (if required)

Act on the touch information to generate MIDI messages:
NoteOn/NoteOff on touch/release if required
MIDI CC messages for the X and Y "potentiometer" values if required
MIDI pitch bend message for the X direction if required

There are several helper routines to support this:

  • x2note – translates a touch X coordinate into a MIDI note value.
  • xy2val – translates a touch X or Y coordinate into an equivalent “potentiometer” value – i.e. 0 to 1023 as if it was used with analogRead.
  • x2pb – translates a touch X coordinate into a pitch bend value in the range -8192 to 8192 with zero sitting at the point of the original touch.

I’d like to have some kind of visual indication of where the touch is happening – as you might expect with one of those neat tablet MIDI apps you can get – so there are some hooks in there to support that, but I’ve not implemented anything like that at present.

One thing to note about MIDI pitch bend messages and the Arduino MIDI library.  MIDI pitch bend messages have the following format:

MIDI Pitch Bend Message = 0xEn, lsb, msb
n = MIDI channel in 0 to F hex format
lsb = least significant 7 bits of a 14-bit value
msb = most significant 7 bits of a 14-bit value

Where the 14-bit value goes from 0 to 16383.  However it should be noted that the mid-point (8192) means “no bend”.  This means values less than 8192 bend downwards and values above 8192 bend upwards.

The MIDI library hides all that and uses an “int” value that can take the range -8192 to 8192 which means that 0 represents “no bend”.  The code uses the MIDI library values throughout and lets the MIDI library do the translation to the MIDI message as required.

In my example I’ve configured the code as follows:

  • Use a set of 8 notes a major scale, C4 to C5.
  • Use the Y-axis to control MIDI CC message 74 which is often used as the filter cut-off value in a synthesizer that supports it.
  • Use the X-axis for pitch bend

Find it on GitHub here.

Closing Thoughts

In the video I’m using it to control my Shruthi and with the right sound, being able to change the filter “on the fly” like that is quite fun.

The main limitation here though is that the touchscreen will only register one touch, so as a note controller it is monophonic.  But that doesn’t matter in X-Y controller mode.

The original thought came from seeing some of those tablet sound making apps you can get (one of my favourites is Jorden Rudess’ MorphWiz): the comment that kicked it all off came from @EmmaLovelace on Twitter in reference to EtherPad.  A cheap Arduino touchscreen will never come anywhere near the touch interface of apps like these on a tablet, but that might be possible using a more sophisticated setup – maybe a HDMI touch screen on a Raspberry Pi for example.  That would be fun to try at some point.

Another similar thing to try would be to hook up an old laptop’s touchpad.  For a simple 2-D interface, I don’t really need a graphical display. I’ve also seen it done with a cheap Nintendo DS replacement touchscreen.  But for that to work, I’d need some kind of MIDI merge facility, so that it could be used with a keyboard controller.  That could be built in to the Arduino’s MIDI connections, or via a separate hardware unit.

But seeing as I do have a graphics display it would be nice to have something a little more visually appealing!

Kevin

IMG_6271

Leave a comment