Accessible MIDI Controller for Kids

I’m always bad at music. Neither do I have a background in music. Sure I was playing piano and guitar when I was a kid, but it was because my mom made me to. Since then, I’ve never played it anymore. So, making a MIDI controller was very challenging to me. In this blog, my objective is to make a simple MIDI controller that can teach kids with low vision or blindness to familiarize music. I was more focus on how to make it more accessible for these kids rather than making complex music.

 

Goal

How might we make a musical instrument that is accessible and can teach kids with low vision or blindness to learn music.

 

Ideas

I was inspired by Soundscape, a midi controlled musical interactive surface. Kale Joines, who designed it, had a brilliant idea to make the users immerse in the sound as they interact with it. The 3D surface which looks like a terrain makes the users explore on the surface and sound.

Soundscape by Kale Joines

The Soundscape gave me the idea of using touch in the tactile sense to play music. Since the goal is to make an accessible musical instrument for kids who have low vision or blindness, there are some factors that are important to be considered.

  • Texture: For people without vision, they rely more on tactile sense. In this project, I wanted to make the texture rather soft to get the sense of feeling safe. For children, if the products have solid texture, they might think of harmness.
  • Surface: Playing music for people with low vision or blindness is challenging. It’s not that they can’t because music is more audio than visual, but it takes longer for them to memorize the place of the notes. If the surface isn’t flat, I think it would be helpful for them to memorize it.
  • Elevation: Most of musical instrument differentiate the notes based on its place. The higher the pitches, the further the place for instance. But it’s harder for people with low vision or blindness. I thought adding elevation on the instrument would give clearer and more intuitive interaction for the users.
  • Keep it simple: Never be too complex. It’s the key to design things for kids. If kids can’t figure out how to use things, they will get bored after some time. In this project, my idea is to place the notes only in a X axis. That way it’s easier for them to memorize notes.

 

Sketch

Interaction

With this accessible music instrument, the user can produce music by pushing the notes, sort of like a mental model when someone playing a piano. Also, they can make a pitch bend by shaking the notes. There’s also a volume control which user can turn up and down to increase or decrease the volume.

I’m using an exactly piano mental model in this project. Since piano is a very popular instrument, users might know how does piano work. But, since the user target is kids with low vision or blindness, there’s possibility that they don’t know what piano is. That way, I’m making it as simple as possible, with just note buttons which can produce sound when it’s being pressed.

Design

Development

Tools

  • Arduino UNO
  • Switch Button
  • 10K Ohm Resistor
  • 440 Ohm Resistor
  • Tilt Ball Sensor
  • Tilt Mercury Sensor
  • Potentiometer 10K
  • Breadboards
  • Wires

 

Materials

  • Plywood
  • Sheet Foam
  • Ball High-density Foam
  • Stick Wood

 

Wiring

Here’s what it looks like in real life:

And here’s the clearer image of the wiring:

Code

To be honest, I looked into Tom’s code here, and made some changes to match my MIDI controller. I wanted the notes to be specific: C, D, E, F, and G. And I added volume using potentiometer.

#include <SoftwareSerial.h>

int keys[] = {9, 10, 11, 12, 13};   // five pins for pushbuttons (keys)
int lastKeyState[] = {0, 0, 0, 0, 0}; // previous state of the keys
int keyCount = 5;             // number of keys
int baseNote = 48;            // C4, used as the base note

//software serial
SoftwareSerial midiSerial(2, 3); // digital pins that we'll use for soft serial RX & TX

void setup() {

  //  Set MIDI baud rate:
  Serial.begin(9600);

  midiSerial.begin(31250);

  for (int k = 0; k < keyCount; k++) { // iterate over the keys
    pinMode(keys[k], INPUT);           // make each an input
  }

}

void loop() {
  int currentKeyState[] = {0, 0, 0, 0, 0}; // holds the current state of all keys
  int velocityNote = 1023 - analogRead(A0); // read value for volume from potentiometer
  int volumeNote = map(velocityNote, 0, 1023, 0, 127); // map value to 127
  for (int k = 0; k < keyCount; k++) {         // iterate over the keys
    currentKeyState[k] = digitalRead(keys[k]); // read each key

    if (currentKeyState[k] != lastKeyState[k]) {// if a key has changed
      int thisNote;
      if (k == 0) {
        thisNote = k + baseNote; // C note
      } else if (k == 1) {
        thisNote = k + baseNote + 1; // D note
      } else if (k == 2 || k == 3) { 
        thisNote = k + baseNote + 2; // E and F note
      } else {
        thisNote = k + baseNote + 3; // G note
      }

      int thisCommand = 0;
      if (currentKeyState[k] == HIGH ) {        // if key is pressed
        thisCommand = 0x90;                     // command is noteOn
        Serial.print(" on: ");
      } else {                                  // if key is released
        thisCommand = 0x80;                     // command is noteOff
        Serial.print("off: ");
      }

      midiCommand(thisCommand, thisNote, volumeNote);  // play or stop the note
      Serial.println(thisNote, HEX);            // print note
      lastKeyState[k] = currentKeyState[k];     // save key state for next time
    }

    // read a 10-bit analog input and convert it to
    // 2 7-bit bytes, to send as the least significant byte (lsb)
    // and most significant byte (msb) of a pitch bend message:
    int pitchBendSensorC = digitalRead(4);          // read digital input
    int pitchBendSensorD = digitalRead(5);          // read digital input
    int pitchBendSensorE = digitalRead(6);          // read digital input
    int pitchBendSensorF = digitalRead(7);          // read digital input
    int pitchBendSensorG = digitalRead(8);          // read digital input

    if (pitchBendSensorC == 0 ) {                   // if it's == 0
      byte msb = highByte(pitchBendSensorC << 1);   // get the high bits
      byte lsb = lowByte(pitchBendSensorC);         // get the low 8 bits
      bitWrite(lsb, 7, 0);                         // clear the top bit
      midiCommand(0xE0, lsb, msb);                 // send the pitch bend message
    }
    if (pitchBendSensorD == 0 ) {                   // if it's == 10
      byte msb = highByte(pitchBendSensorD << 1);   // get the high bits
      byte lsb = lowByte(pitchBendSensorD);         // get the low 8 bits
      bitWrite(lsb, 7, 0);                         // clear the top bit
      midiCommand(0xE0, lsb, msb);                 // send the pitch bend message
    }
    if (pitchBendSensorE == 0 ) {                   // if it's == 10
      byte msb = highByte(pitchBendSensorE << 1);   // get the high bits
      byte lsb = lowByte(pitchBendSensorE);         // get the low 8 bits
      bitWrite(lsb, 7, 0);                         // clear the top bit
      midiCommand(0xE0, lsb, msb);                 // send the pitch bend message
    }
    if (pitchBendSensorF == 0 ) {                   // if it's == 10
      byte msb = highByte(pitchBendSensorF << 1);   // get the high bits
      byte lsb = lowByte(pitchBendSensorF);         // get the low 8 bits
      bitWrite(lsb, 7, 0);                         // clear the top bit
      midiCommand(0xE0, lsb, msb);                 // send the pitch bend message
    }
    if (pitchBendSensorG == 0 ) {                   // if it's == 10
      byte msb = highByte(pitchBendSensorG << 1);   // get the high bits
      byte lsb = lowByte(pitchBendSensorG);         // get the low 8 bits
      bitWrite(lsb, 7, 0);                         // clear the top bit
      midiCommand(0xE0, lsb, msb);                 // send the pitch bend message
    }
  }
}
//  plays a MIDI note.  Doesn't check to see that
//  cmd is greater than 127, or that data values are  less than 127:
void midiCommand(byte cmd, byte data1, byte  data2) {
  midiSerial.write(cmd);
  midiSerial.write(data1);
  midiSerial.write(data2);

  //prints the values in the serial monitor so we can see what note we're playing
  Serial.print("cmd: ");
  Serial.print(cmd);
  Serial.print(", data1: ");
  Serial.print(data1);
  Serial.print(", data2: ");
  Serial.println(data2);
}

Enclosure

It’s actually more challenging to build the enclosure than coding the program. Since I had to think what materials best for this MIDI controller, regarding the goal of this project. Also, how to make it sturdy, since this is for kids.

Making of Enclosure

 

Final Product

Making an Accessible Music Instrument from Vidia Anindhita on Vimeo.

 

The Takeaways

By doing this project, I learned a lot about MIDI. How does it works, what exactly MIDI is, and how to put it into code. There are a lot of elements in MIDI which we can control to produce different kind of interesting music. And beyond that, I learned that making accessible product is not easy at all. There are many things to be considered, from how people with disability would interact with the product, what usually they do if they’re facing similar things, what kind of materials should we choose, etc.

 

Leave a Reply

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