DIY MIDI Controller

Eine Schritt für Schritt Anleitung

Vorab: Der Bau dieses Conroller liegt mittlerweile 2 Jahre zurück, ich probiere aus den vorhandenen Unterlage bestmöglich den Bau zu rekonstruieren.

Nachdem ich mich mehr und mehr mit Ableton Live beschäftigt habe und ein Menge YouTube Videos geguckt hatte, wollte ich auch ein physisisches Gerät mit dem man in Ableton agieren kann. Dabei war besonders Robert Delong eine große Inspiration, der das live Spielen elektronischer Musik auf ganz neues Level bringt:

Neben dem Launchpad hat es mir vor allem der Midi Fighter 3D angetan. Doch 280€ (Thomann) für ein 4×4 Grid aus Arcade Buttons ist schon eine Ansage. Im Zuge dessen bin ich auf DIY MIDI Controller gestoßen, davon gibt es wirklich einige, einfach mal googlen. Die kostengünstige, zugeschnittene und vor allem spaßige Alternative hatte es mir angetan und so begann ein sehr langer Planung des Designs. Schlussendlich wollte ich einen Controller der mehr Buttons als der Midi Fighter hat (16) und weniger als das Launchpad (64). Zudem 2 Fader für z.B. Master/Headphone Pegel, 4 Potis für Effekte und 6 abseits plazierte Buttons für andere Shortcuts. Das Layout sollte sich gut in Ableton integrieren. Die farbliche Gestalltung wollte ich in bunten knalligen Farben, da bunte Arcade Buttons einfach geil aussehen.

Aber warum überhaupt Arcade Buttons?
Die Midi fighter sind fast die Ausnahme was die Verwendung von Arcade Buttons angeht, andere DAW Controller wie das Launchpad oder Push 2 haben Taster mit Membranen. Diese sind aber sehr schwer DIY zu machen um ein gutes Spielgefühl zu erlangen. Arcade Buttons wurden für ein perfektes Spielgefühl geschaffen.

(finaler Entwurf)

Dann ging es an die Bestellung: auch da habe ich mich wieder am Midi Fighter orientiert. Und habe Sanwa Arcade Buttons importieren lassen. Die sind echt nicht so einfach zu bekommen, da sie sehr begehrt sind. Zur Auswahl standen Buttons mit 30er und 45er Durchmesser. Ich habe mich für die kleineren entschieden, damit das ganze nicht zu groß wird. Buttons gibt es auch wahlweise mit LED Ring, aber den Aufwand der zusätzlichen Lichprogrammierung wollte ich mir nicht machen. Die 4 eckigen Buttons habe ich beim durchklicken gefunden und fand sie sehr schön zur räumlichen Abtrennung. Es sei aber gesagt, dass sie sich nicht für das Fingerdrumming eigenen, sondern nur wenn man ab und zu mal eine Spur triggern möchte o.ä..
Potis und Fader aus einem Elektroladen deiner Wahl. Man sollte aufpassen, dass es Encoder (Endlosdrehregler) und Potis (definierter Start und Endpunkt) gibt, beide sehen sich sehr ähnlich.

Der Mikrocontroller: Zuerst wollte ich dem Projekt den Teensy .. verwenden. Allerdings nahm die benötigte Anzahl an digitalen Inputs Überhand. Deswegen entschied ich mich für den Arduino Mega 2560!!. Wer sich die Mühe machen möchte kann aber auch Multiplexer verwenden, damit wollte ich mich aber nicht beschäftigen.

Das Gehäuse: Bei dem Gehäuse habe ich mich für Akazienholz entschieden, da es sehr einfach zu bearbeiten ist. Aber mit den entsprechenden Geräten und Materialien kann man sich auch ein schickes Alugehäuse bauen. Egal welches Material man verwendet, sollte man einen gewisse Materialdicke haben, da bei so vielen Bohrungen auf einem kleinen Bereich die Stabilität leidet.

Der Bau:

Layout 1:1 ausdrucken und auf vorgeschnittener Platte befestigen, mit Körnerspitze Bohrmakierungen setzen

Vorbohren

Löcher für runde Arcade Buttons mit Foscna Bohrer bohren (Ich hatte keine perfekt passende Größe für die Arcade Buttons, deswegen musste sehr zeitaufwendig jedes einzelne Loch mit einer Dremmel mit Schleiftrommelaufsatz vergrößert werden. Das sollte auf jeden Fall verhindert werden, da es ewig dauert und der Gesamtsymmetrie nicht gerade hilft.)

Schlitz für Fader behutsam mit einer Dremel mit Minikreissägenaufsatz schneiden. Die Rückseite Runterfräsen, sodass der Fader auf der Oberseite herrausguckt. (Auch hier musste ich behelfsmäßig mit mehreren Bohrungen aneinander arbeiten, eine Fräse o.ä. wäre natürlich deutlich besser.)

Auch die Aussparungen für die quadratischen Buttons gestalteten sich als schwierig. Ich habe sie zunächst wie die Runden Buttons gebohrt, dann mit der Stichsäge die jeweiligen vier Ecken rausgesägt und danach nachgepfeilt. Gerade hier ist es schwer alle Buttons symmetrisch zu hinzukriegen.

Dann 4 Seitenteile ankleben, Kanten schleifen und z.B. mit Nussbaum mittel (Lack) bestreichen.

Knöpfe, Fader und Potis einkleben (z.B. mit UHU extra Alleskleber Colle Multi-Materiaux Gel) und gemäß der Schaltzkizze verlöten:

Dies war es erstmal für den Bau, später kommt noch eine Plexiglasplatte an den Boden um die Elektronik zu schützen und Einblick in das Gahäuse zu haben. Bei der Elektronik habe mich zum Großteil an MIDI-Controller selber bauen Tutorial Reihe von Götz Müller-Dürholt gehalten:

Die Verkabelung ist recht simpel. Der eine von zwei Anschlüssen pro Button werden in Reihe mit GND vom Arduino verbunden. Der andere Anschluss der Buttons kommt jeweils in ein Digital IN.

Arduino Sketch und MIDI:

<p><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] --></p><!-- [et_pb_line_break_holder] --><p>
//           __  __ _____ _____ _____    _____            _             _ _                     //
//          |  \/  |_   _|  __ \_   _|  / ____|          | |           | | |                    //
//          | \  / | | | | |  | || |   | |     ___  _ __ | |_ _ __ ___ | | | ___ _ __           //
//          | |\/| | | | | |  | || |   | |    / _ \| '_ \| __| '__/ _ \| | |/ _ \ '__|          //
//          | |  | |_| |_| |__| || |_  | |___| (_) | | | | |_| | | (_) | | |  __/ |             //
//          |_|  |_|_____|_____/_____|  \_____\___/|_| |_|\__|_|  \___/|_|_|\___|_|             //
//        yt.com/technikblock               bit.ly/technikblock                 technikblock.de //
                                                                          


//Potis und Fader                                        //Arrays (0 bis 6 zählen)
int potipin[] =             {A0,A1,A2,A3,A4,A5};         //Analoge Inputs 
int controllernote[] =      { 1, 3, 2, 5, 6, 4};         //MIDI Note
int controllerwert[]=       {0 ,0 ,0 ,0 ,0 , 0};         //MIDI Wert
int controllerwertalt[]=    {0 ,0 ,0 ,0 ,0 , 0};         //alter MIDI Wert
int potiwert[]=             {0 ,0 ,0 ,0 ,0 , 0};         //Potiwert
int smoothpoti[]=           {0 ,0 ,0 ,0 ,0 , 0};         //Potiwert geglättet


//Buttons                                                //Arrays (von 0 bis 6 zählen)
int button[] =      {LOW,LOW,LOW,LOW,LOW,                //Buttondruck
                     LOW,LOW,LOW,LOW,LOW,
                     LOW,LOW,LOW,LOW,LOW,
                     LOW,LOW,LOW,LOW,LOW,
                     LOW,LOW,LOW,LOW,LOW,
                     LOW,LOW,LOW,LOW,LOW,
                     LOW,LOW,LOW,LOW,LOW,
                     LOW,LOW,LOW};  
                                                            
int buttonalt[] =   {LOW,LOW,LOW,LOW,LOW,                //alter Buttondruck
                     LOW,LOW,LOW,LOW,LOW,
                     LOW,LOW,LOW,LOW,LOW,
                     LOW,LOW,LOW,LOW,LOW,
                     LOW,LOW,LOW,LOW,LOW,
                     LOW,LOW,LOW,LOW,LOW,
                     LOW,LOW,LOW,LOW,LOW,
                     LOW,LOW,LOW};      
                             
int buttonpin[] =   { 4, 8, 7,53,51,49,47,               //Digitale Inputs
                     23,27,31,37,44,42,46,
                     50,24,26,32,36,45,43,
                     41,39,35,33,29,25,52,
                     48,40,38,34,30,28,22,
                     6, 5, 9};             
                              
int midinote[] =    {57,58,59,60,61,62,63,               //MIDI Noten
                     64,65,66,67,68,69,70,  
                     71,72,73,74,75,76,77,
                     78,79,80,81,82,83,84,
                     85,86,87,88,89,90,91,
                     92,93,94};                     

long lastdebouncetime = 0;                               //letztes mal als der Knopf getoggelt wurde
                             
long debouncedelay = 40;                                 //Debounce Zeit Standard: 50

int midinoteon = 144;                                    //Status-Byte (144 = Note On)
int midicontrolchange = 176;                             //Status-Byte (176 = Control Change)
int i = 0;                                               //Variable zum schreiben und lesen der Menge


void setup() {                                           //Setup
Serial.begin(9600);                                      //serielle Beginn und Geschwindigkeit (seriell: 9600, MIDI: 31250)
for (i = 0; i < 37; i++) {                               //38 Buttons
  pinMode(buttonpin[i], INPUT_PULLUP);                   //definiert digitalen Pin als Input mit Pullup Resistor
  }
}



void loop() {                                                     //Loop
 
 //Potis und Fader
    for (i = 0; i < 6; i++) {                                     //6 Potis
    potiwert[i] = analogRead(potipin[i]);                         //ließt Analoge Pins
    smoothpoti[i]= (6 * smoothpoti[i] + 4 * potiwert[i])/10;      //0,6 vom geglätteten Poti + 0,4 vom alten Poti (Gleitkommazahl-Berechnung vermieden)
    controllerwert[i] = map(smoothpoti[i],0,1023,0,127);          //umrechnen von alter Skala(0-1023) zu neuer Skala(0-127)

      if (controllerwert[i] != controllerwertalt[i]) {            //Wenn der Controllerwert nicht gleich (!=) controllerwertalt ist, dann:
      Serial.write(midicontrolchange);                            //schreibe MIDI Kanal
      Serial.write(controllernote[i]);                            //schreibe MIDI Note
      Serial.write(controllerwert[i]);                            //schreibe MIDI Wert
      controllerwertalt[i] = controllerwert[i];                   //alten mit neuem controllerwert vergleichen
      }
   }

 
 
 //Buttons
    for (i = 0; i < 38; i++) {                                    //38 Buttons
    button[i] = digitalRead(buttonpin[i]);}                       //ließt Digitale Pins
      
        lastdebouncetime = millis();                           
        for (i = 0; i < 38; i++) {
        
           if (button[i] == HIGH && buttonalt[i] == LOW) {        //Wenn Button hoch, dann schreibe:   
           Serial.write(midinoteon);                              //schreibe MIDI Kanal
           Serial.write(midinote[i]);                             //MIDI Note (24 = C1)
           Serial.write(0);                                       //MIDI Velocity (0 = 0%)
           buttonalt[i] = button[i];
           }
           if (button[i] == LOW && buttonalt[i] == HIGH) {        //Wenn Button tief, dann schreibe:  
           Serial.write(midinoteon);                              //schreibe MIDI Kanal
           Serial.write(midinote[i]);                             //MIDI Note (24 = C1)
           Serial.write(127);                                     //MIDI Velocity (127 = 100%)
           buttonalt[i] = button[i];                   
           } 
           }
           while ((millis() - lastdebouncetime) < debouncedelay){
          //do nothing
          }
      
   
}


//          Midi Syntax
//
//          Status-Byte          Data-Byte          Data-Byte
//          Art, Kanal           Note               Velocity
//          1 011 0000           0 1101010          0 0101111
//      
//          Status-Byte:
//          1 000 Note off
//          1 001 Note on (144)
//          1 010 Poly Presure
//          1 011 Control Change (176)
//          1 100 Program Change
//          1 101 Channel Aftertouch
//          1 110 Pitch Bend
//
//          Data-Bytes jeweils 0-127 dezimal
//
//          binär -> dezimal
</p><!-- [et_pb_line_break_holder] --><p><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] --></p><!-- [et_pb_line_break_holder] -->