Introduction: Black Box Midi Controller

The Black Box is a midi controller created with an Arduino Leonardo, using some rotary switches assembled in a matrix to produce certain note values.

Step 1: Gather Materials

To build the Black Box, you will need the following:

Tools

  • Soldering iron - used to make many connections, important for assembling the switch matrix.
  • Screwdriver - for opening and closing the project enclosure.
  • Power drill and drill bit (closest possible to 10 mm) - for drilling the hole for the tempo mode toggle switch.
  • 3-D printer - for printing knobs, and the lid to the project box.
  • Pliers - for all pinching and or bending type tasks involved.

Materials

  • Solder
  • Appropriate filament for your 3-D printer
  • Project enclosure
  • Rotary Switches x 16
  • 10k Potentiometer
  • Toggle Switch
  • Jumper Wires
  • PCB or Breadboard
  • Arduino Leonardo
  • Micro USB to USB cable
  • Nail Polish x 5 colors
  • 120 ohm resistor x 4

Step 2: Assembling the Switch Matrix

The first step in assembling the Black Box is to assemble the switch matrix that constitutes most of the human interface.

The idea behind this is that there are four columns and four rows of switches. The arduino can send power to any individual column, and read which switches are closed by checking the rows. There is a better solution to this problem than the one that I imagined here, but this is the one that I used when I constructed the device initially.

Simply solder some of the jumper wire to each of the switches, so that the switches are connected together as shown.

Step 3: Printing the Lid

The next step is to print the new lid for the project enclosure.

Attached are the files that I used to print my lid, my print bed was not quite large enough to print it in one piece, so I sliced it in half.

Step 4: Print and Paint the Knobs

Next up is to print the 17 knobs to go onto the various actuators that will be poking out of the box.

Attached are the files that I used for my knobs.

After they're done printing, I placed a drop of nail polish of a few different colors to be able to tell them apart when they are installed on the actuators.

Step 5: Assemble the Lid

Now it is time to assemble the lid. The columns are arranged along the length of the box, and the rows along the other direction. The 10k potentiometer goes into the bottom right corner. You can use the pliers to tighten the nut down on top of the box, just make sure that the switches are in the right order going both vertically and horizontally, otherwise the device will not function quite right.

Step 6: Prepare the Lower Project Enclosure

The lower project enclosure needs a hole drilled in one of the sides for the toggle switch that will control tempo mode on the device. The placement of this hole does not need to be exact, just be sure to leave enough room for the lid and for the switch that will be installed there to be able to fit. I highly recommend placing the hole on the top of the box, as there is a much lower chance of the switch making any accidental connections. Once the hole is made, install the toggle switch on the side, being sure to tighten it down like the rest of the components that exit the box.

Step 7: Assemble the Secondary Board

The secondary board is to connect the rows to external pull-down resistors, and to make input from the matrix more manageable.

Solder the components into place if you are using a pcb, or just build the circuit if you are using a bread board.

Step 8: Wire Up the Arduino

The time has come to wire up the arduino.

The first thing to wire is the secondary board. Wire the positive and negative power rails to ground, and 5 volts respectively. then wire the outputs from rows one through four to pins eight through eleven on the arduino. Then connect the inputs to the secondary board to their respective rows.

Connect the inputs for the matrix to pins two through five on the arduino, for columns one through four respectively.

Then connect the toggle switch, one side of the switch to ground, and the other to pin 12 on the arduino.

After that, hook up the potentiometer to 5 volts, ground, and the middle pin to analog pin 0.

Finally, connect the arduino to the USB cable, and you can close the box up. If nothing goes wrong, you shouldn't have to open it again.

Step 9: Modify the Arduino Hardware Libraries

In order to provide the MIDI over USB functionality that this device uses, a modification must be made to the arduino hardware libraries. Follow the instructions on this page to make the necessary modifications to the libraries, then move on to the next step.

Step 10: Upload a Sketch to the Arduino

The device is physically complete, all that remains is to load the code onto it.below is a copy of the code, from start to finish, that I used when I built my Black Box. The arduino sketch is also provided as an attachment.

<p>#define rowOne 0 // Defines the midi note played by the first row.<br>#define rowTwo 1 // Defines the midi note played by the second row.
#define rowThree 2 // Defines the midi note played by the third row.
#define rowFour 3 // Defines the midi note played by the fourth row.
#define columnOne 2 // Defines the pin connected to the first column.
#define columnTwo 3 // Defines the pin connected to the first column.
#define columnThree 4 // Defines the pin connected to the first column.
#define columnFour 5 // Defines the pin connected to the first column.
int delayTime; // Holds the number of milliseconds the program waits between columns.</p><p>byte noteOne;
byte noteTwo;
byte noteThree;
byte noteFour;</p><p>// Sets the pin modes for all of the inputs and outputs of the arduino</p><p>void setup() {
  pinMode(7, INPUT);
  pinMode(8, INPUT);
  pinMode(9, INPUT);
  pinMode(10, INPUT);
  pinMode(11, INPUT);
  pinMode(12, INPUT);
  digitalWrite(12, HIGH);
  pinMode(columnOne, OUTPUT);
  pinMode(columnTwo, OUTPUT);
  pinMode(columnThree, OUTPUT);
  pinMode(columnFour, OUTPUT);
}</p><p>void loop() {
  setDelay();
  flashColumn(columnOne);
  flashColumn(columnTwo);
  flashColumn(columnThree);
  flashColumn(columnFour);
  if(digitalRead(12) == 0){
    playTimingNotes();
  } else {
    playNormalNotes();
    delay(delayTime);
  }
  noteOne = 0;
  noteTwo = 0;
  noteThree = 0;
  noteFour = 0;
}</p><p>// First parameter is the event type (0x09 = note on, 0x08 = note off).
// Second parameter is note-on/note-off, combined with the channel.
// Channel can be anything between 0-15. Typically reported to the user as 1-16.
// Third parameter is the note number (48 = middle C).
// Fourth parameter is the velocity (64 = normal, 127 = fastest).</p><p>void noteOn(byte channel, byte pitch, byte velocity) {
  MIDIEvent noteOn = {0x09, 0x90 | channel, pitch, velocity};
  MIDIUSB.write(noteOn);
}</p><p>void noteOff(byte channel, byte pitch, byte velocity) {
  MIDIEvent noteOff = {0x08, 0x80 | channel, pitch, velocity};
  MIDIUSB.write(noteOff);
}</p><p>// Combines note on and note off information into one method</p><p>void playNote(byte channel, byte pitch, byte velocity){
  noteOn(channel, pitch, velocity);
  MIDIUSB.flush();
  noteOff(channel, pitch, velocity);
  MIDIUSB.flush();
}</p><p>// Powers a column of the matrix, then reads out which switches are closed 
// then sets the column back down to low</p><p>void flashColumn(byte column){
 digitalWrite(column, HIGH);
 readColumn(column);
 digitalWrite(column, LOW);
}</p><p>// Reads each row, then plays the respective notes if the switches are closed</p><p>void readColumn(int column){
  int noteNumber = 100;
  if(digitalRead(8) == 1){
    noteNumber = rowOne + (column-1)*12;
  } else if(digitalRead(9) == 1){
    noteNumber = rowTwo + (column-1)*12;
  } else if(digitalRead(10) == 1){
    noteNumber = rowThree + (column-1)*12;
  } else if(digitalRead(11) == 1){
    noteNumber = rowFour + (column-1)*12;
  }
  if(column == 2){
    noteOne = noteNumber;
  } else if(column == 3){
    noteTwo = noteNumber;
  } else if(column == 4){
    noteThree = noteNumber;
  } else if(column == 5){
    noteFour = noteNumber;
  }
}</p><p>void playTimingNotes(){
  for(int i = 0; i < 4; i++){
    playNote(0, 100, 64);
    delay(delayTime/32);
  }
}</p><p>void playNormalNotes(){
  if(noteOne != 0){
    playNote(0, noteOne, 64);
  }
  if(noteTwo != 0){
    playNote(0, noteTwo, 64);
  }
  if(noteThree != 0){
    playNote(0, noteThree, 64);
  }
  if(noteFour != 0){
    playNote(0, noteFour, 64);
  }
}</p><p>void setDelay(){
  delayTime = ((analogRead(A0)/2)+300)*32;
}</p>

Step 11: The Device Is Complete

If simply building this device is all that you intend to do, then you are now finished, enjoy your Black Box! However, I will go on to explain how to connect the Black Box to Fruity Loops Studio to use it in performance mode.

Step 12: Connecting the Black Box to FL Studio

The first thing that you will need to do is make sure that FL Studio is recognizing the Black Box as a MIDI device.

This can be achieved in the MIDI section of the General project settings menu.

Details about this can be found here.

Step 13: Setting the Tempo

In order to use the Black Box, you will have to set the tempo using the potentiometer, then the toggle switch to place the device into tempo detection mode, then finally using the FL Studio tempo tapper to detect the tempo of the Black Box.

Step 14: Set Up the Loops

Set up the loops you wish to trigger using the Black Box in the performance section of the playlist. Keep in mind that the Black Box can't trigger any loops on the first track, and can only trigger up to four on any of the next four tracks. The Black box is also set up to trigger these loops once every two bars, so this is potentially another limitation.

If you do not know how to use performance mode, here is a fairly straightforward guide.