DYI USB Midi Controller

by Pif_art in Circuits > Audio

2785 Views, 13 Favorites, 0 Comments

DYI USB Midi Controller

P1010048.JPG

How to make an 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.

Planning

P1010023.JPG
P1010043.JPG
P1010068.JPG

The first step is components selection.

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

Slide potentiometers - ALPS RS60N1119006 logarithmic 60mm travel or other according to you choose. (logarithmic for audio, linear for lights)

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

Buttons - according to your preference, 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 can be bought for about 300 $ without PCB and front panel. PCB and the front panel cost about 100 $.

Wiring

genuino-micro.jpg
4067.jpg
8575.jpg
encoder.jpg
pot.jpg
switch.jpg

Arduino Micro board

4 x 74HC4067 - 16 channel analog multiplexer

Every one 4067 use only one analog input of Arduino. Driving 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 in case of the encoders.

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

PCB Brain

P1010012.JPG
P1010014.JPG
usbm_41_214_v13_bottom.jpg
usbm_41x214_v13_top.jpg

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

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

PCB Analog

P1010041.JPG
P1010032.JPG
pot.jpg
knob_120x52_v13.jpg
P1010068.JPG

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

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

PCB Digital

P1010035.JPG
P1010034.JPG
switch.jpg
button_115x35_v13.jpg
P1010036.JPG
encoder.jpg
enc_121x24_top_v13.jpg
enc_121x24_bottom_v13.jpg

Buttons PCB dimensions 115 x 35 mm.

Encoders PCB have 121 x 24 mm and they are double sided.

PCB Master

P1010039.JPG
master_31x209_v13.jpg

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

Update - two digital pins not connected to the ground.

PCB Soldering

P1010028.JPG
P1010029.JPG
P1010025.JPG
P1010051.JPG
P1010055.JPG
P1010058.JPG
P1010060.JPG

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

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

For junctioning the top and bottom side PCB use unisolated wire ovelapping both side above 1 mm and squeeze them together. That makes small rivet and solders it.

Front Plate Design

plate.jpg
P1010074.JPG

My design come from analog mixing console. Best is to make it by laser, you save your time. Actually my piece is in production right now.

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...

Downloads

Programming

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

Analog:

// 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 - ");

Serial.println(ka[0]);

}

kaL[0] = ka[0];

}

...

I don't use loops, the code is a little messy, but save 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]) {

counter_enc6++;

if (debug) {

Serial.print("counter_enc6 - ");

Serial.println(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.

Downloads

Testing

Code have debug function.

Boolean debug and boolean debug_code should be switched to true. But in this case, if serial monitor is not present, controller will 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.

Assembly

P1010129.JPG
IMG_20180901_221107.jpg
P1010079.JPG
P1010084.JPG
P1010124.JPG
P1010116.JPG
IMG_20180901_221031.jpg

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

Thanks

Arduino for platform and MIDIUSB library

PJRC

Fuzzy-Wobble

and many more nameless people for ideas

Controller designed for Ableton and Traktor

Special thanks to AnnaM for EN proofreading :)