DYI USB Midi Controller

How to make affordable large midi controller for DJ, VJ and producers?

This midi controller is based on Arduino Micro, support on board: 64 analog inputs, 64 digital inputs and interface for connecting other 32 digital inputs. Digital inputs are usable for encoders. In this configuration response of analog inputs is 250ms and digital inputs is 16ms.

This is the result of my work for the year of testing...

Unfortunately I do not have enough time, so writing will be longer.

Update code for analog inputs response about 100ms.

Step 1: Planning

First step is components selection.

Rotary potentiometers - good quality Bourns PTV111-3415A-B103 / ALPS RK11 series, option is cheaper ALPS RK09K series.

Slide potentiometers - ALPS RS60N1119006 logarithmic 60mm travel or any other what you choose. (logarithmic

for audio, linear for lights)

Encoders - Bourns PEC11R-4215F-S0024 (24 detents, with switch).

Buttons - whatever you choose, but they should not be noisy (my choose is Highly KS01-BV).

Brain section:

Arduino Micro board

74HC4067 (SOP24)

PCF8575 (SOP24)

10k (0805)

10k (0204)

100nF (0805)

IDC connectors 2 x 5 pins and cables 10 lines

Cliff K85 rotary knobs with selectable caps

All components should be cost about 300 $ without PCB and front panel. PCB and the front panel should cost about 100 $.

Step 2: Wiring

Arduino Micro board

4 x 74HC4067 - 16 channel analog multiplexer

Any one 4067 use only one analog input of Arduino. Drivig with four digital pins.

4 x PCF8575 - 16 bit I/O expansion for I2C + 2 x PCF8575 external interface option

Every two PCF8575 use one Arduino interrupt pin.

10 x Encoders withs capatitors and resistors for HW debounce.

53 x Potentiometers + 8 slide

32 x Switches - debounce is the same as at the encoders.

Update - two int section are connected to Vcc over resistor 10k.

Step 3: PCB Brain

PCB is double sided. I'm made pcb by my self and all junction of top and bottom side is made with wire - see at soldering part.

Update - now i have new design pcb with 32u4 chip on the board and RJ45 connector.

Step 4: PCB Analog

Analog potentiometers have distance 30 mm at the same channel and 32,5 mm at the between channels. PCB have 120 x 52 mm.

Slide potentioteres is single logarithmic with solder lugs and T bar actuator.

Step 5: PCB Digital

Buttons PCB have 115 x 35 mm.

Encoders PCB have 121 x 24 mm and it's double sided.

Step 6: PCB Master

Master PCB have 31 x 209 mm and two output, one digital and one analog.

Update - two digital pins not connected to ground.

Step 7: PCB Soldering

You don't need hot air necessarily. All components could be solder with small soldering station, tweezers and souder paste tin cream.

If you don't know how to solder SMD, find any inctruction and make some practise first.

For junction top and bottom side PCB use unisolated wire ovelapping both side above 1 mm and squeeze both side together. That make small rivet and solder it.

Step 8: Front Plate Design

My design come from analog mixing console. Best is made it on the laser, you spare your time. Actualy my piece is in production.

Update - first version have small hole dia... Encoders dia - 7.5 mm, potentiometers dia - 9.5 mm, buttons dia - 9.5 mm. New drawing will be uploaded...

Step 9: Programing

Code is fully function for brain v2 , but if you use v1 make changes in four 4067 directional pins (5, 9, 10, 13).


// select 4067 channel Y0 (pin 9)

digitalWrite(13, LOW); // S0 - 4067 pin 10

digitalWrite(5, LOW); // S1 - 4067 pin 11

digitalWrite(9, LOW); // S2 - 4067 pin 14

digitalWrite(10, LOW); // S3 - 4067 pin 13

delayMicroseconds(2); // delay for signals to stabilize

ka[0] = analogRead(0) / 8;

if (abs(ka[0] - kaL[0]) > analogAttach) {

controlChange(16, ka[0]);

if (debug) {

Serial.print("16 ka0 - ");



kaL[0] = ka[0];



I'm not use loops, code is a little messy, but spare 15 x 4 x 2ms time to stabilize chips.

digital buttons:

after read pcf lo + hi

// buttons btnM1
for (uint8_t i = 0; i < 8; i++) {

btnM1[i] = (bitRead(lo_data, i ));

if (btnM1[i] != btnM1L[i]) {

if (btnM1[i] == 0) {

noteOn(i + 24, 127); // 24 - C1 > start midi note (31 - G1 > end)

if (debug) {

pressed(1, i, i + 24);



if (btnM1[i] == 1) {

noteOff(i + 24, 0);

if (debug) {

released(1, i, i + 24);



btnM1L[i] = btnM1[i];




digital encoders:

// encoder 6
// count encoder pulse

if (encM1[7] != encM1L[7] || encM1[0] != encM1L[0]) {


if (debug) {

Serial.print("counter_enc6 - ");




if (counter_enc6 == 3) {

if (encM1[0] == 0 && encM1[7] == 1) {

controlChange(70, 127);

if (debug) {

Serial.println("enc 6 - 70 <<");



if (encM1[7] == 0 && encM1[0] == 1) {

controlChange(70, 1);

if (debug) {

Serial.println("enc 6 - 70 >>");



counter_enc6 = 0;


// reset rotation pulse if rotate other encoder

if (encM1[7] == 1 && encM1[0] == 1) {

counter_enc6 = 0;



Encoders count impulse and evaluate only every third pulse.

Step 10: Testing

Code have debug function.

Boolean debug and boolean debug_code should be switch to true. But in this case, if not serial monitor present, controller not working properly.

Boolean debug_code - enable counter of runnig whole code per 10s

Boolean debug:

- send info about any potentiometer - number of potentiometer (CC channel), module id, value if changed.

- send info about any button - module id, number of button and value.

- send info about encoder - module id, number of encoder and << or >>.

- all int send pcf lo + hi value when it change values, in binary.

All midi signals should be captured with Midi-OX.

Step 11: Assembly

The lower part is made of plywood 4mm and wooden sticks 8 x 30 mm.

Step 12: Thanks

Arduino for platform and MIDIUSB library



and many more nameless for ideas

Controller desined for Ableton and Traktor



    • First Time Author

      First Time Author
    • Make it Glow Contest 2018

      Make it Glow Contest 2018
    • PCB Contest

      PCB Contest

    7 Discussions


    Answer 2 months ago

    41 x 210 mm, but the new PCB design is not released yet.


    2 months ago

    what is the original size of this layout ?

    1 reply

    3 months ago

    Nice build! I'm thinking about building something like this for Traktor. Do you think those potentiometers are as smooth as the ones that Native-instruments equip?

    1 reply

    Reply 3 months ago

    I don't have any experience with Native-instruments equip. But there is no difference compared to AH Xone K2. Now I do not have time to complete the external modules with jog wheel - is not a priority, I not need them. If you want to do it, you need to use different code for reading encoders, because they have no detent and their reading will be better in half a step.