Сегодня мы рассмотрим: Настоящие ценители музыки знают, что для качественного...
В очередной раз играя на гитаре и управляя звуком через Peavey ReValver и прочие Amplitube, задумался о приобретении MIDI-контроллера. Фирменные устройства, вроде Guitar Rig Kontrol 3, стоят около 13 000 рублей, и обладают только напольным исполнением. То есть оперативно менять положения нескольких регуляторов весьма проблематично.
Различные контроллеры DJ направленности выглядели интереснее за счет обилия фейдеров и энкодеров. Решено было совместить приятное с полезным и сделать MIDI-контроллер самому.
Начальные требования: 2-7 фейдеров, столько же роторных потенциометров/энкодеров, около 10 кнопок, подключение по USB.
Далее стал выбирать компоненты. Arduino выбрал по причине наличия, в принципе можно использовать ту же ATmega32u4, STM, либо другой контроллер. Фейдеры и кнопки нашел в местном радиомагазине. Энкодер и потенциометры уже были когда-то куплены. Тумблеры нашел в гараже. Корпус решил изготовить из верхней крышки DVD плеера.
Комплектующие:
- Arduino UNO R3 1 шт.
- Фейдеры сп3-25а 5 шт.
- Рот. потенциометры 3 шт.
- Энкодер 1 шт.
- Кнопки pbs-26b 16 шт.
- Крышка от DVD 1 шт.
- Тумблеры 2шт.
Сначала согнул корпус и пропилил в нем бормашиной отверстия под фейдеры:
Затем просверлил отверстия для тумблеров и рот. потенциометров, разметил положение кнопок. Так как сверла на 19 (да и соответствующего патрона для дрели) у меня не было, то отверстия для кнопок сверлил на 13, а затем увеличивал разверткой.
Основа готова, теперь можно думать, как подключать все это добро к Arduino. Во время изучения данного вопроса наткнулся на замечательный проект HIDUINO . Это прошивка для ATmega16u2 на борту Arduino, благодаря которой устройство определяется как USB-HID MIDI device. Нам остаётся только отправлять данные MIDI по UART со скоростью 31250 бод. Чтобы не захламлять исходники дефайнами с кодами MIDI событий, я воспользовался этой библиотекой .
Так как я использовал Arduino, то решил сделать шилд, к которому уже и будут подключаться вся периферия.
Схема шилда:
Как видно из схемы кнопки подключил по матричной схеме. Задействованы встроенные подтягивающие резисторы ATmega328, поэтому логика инверсная.
Инициализация кнопок
for(byte i = 0; i < COLS; i++){ //--Конфигурируем строки мтрчн клвтр как выходы
pinMode(colPins[i], OUTPUT); //--подаём на них лог. 1
digitalWrite(colPins[i], HIGH);
}
for(byte i = 0; i < ROWS; i++){ //--Конфигурируем столбцы мтрчн клвтр как входы---------
pinMode(rowPins[i], INPUT); //--включаем встроенные в мк подтягивающие резисторы--
digitalWrite(rowPins[i], HIGH);
}
Считывание значений
for(byte i = 0; i < COLS; i++) //-Цикл чтения матричной клавиатуры-----
{
digitalWrite(colPins[i], LOW); //--На считываемый столбец выставляем 0---
for(byte j = 0; j < ROWS; j++) //--Построчно считываем каждый столбец--
{ //--И при нажатой кнопке передаём ноту--
dval=digitalRead(rowPins[j]);
if (dval == LOW && buttonState[i][j] == HIGH) MIDI.sendNoteOn(kpdNote[j][i],127,1);
if (dval == HIGH && buttonState[i][j] == LOW) MIDI.sendNoteOff(kpdNote[j][i],127,1);
buttonState[i][j] = dval;
}
digitalWrite(colPins[i], HIGH);
}
Забыл разместить на печатке диоды, пришлось подпаивать к кнопкам.
Потенциометры подключены через мультиплексор 4052b к вводам АЦП.
Считывание положений потенциометров
for(byte chn = 0; chn < 4; chn++) //-Цикл чтения значений потенциометров
{
set_mp_chn(chn); //--Задаём параметры мультиплексора
val=analogRead(0) / 8; //--Считываем значение с канала X
if (abs(val-PrVal) > 5) //--Если текущее значение отл. от прошлого
{ //--больше чем на 5, то посылаем новое значение
MIDI.sendControlChange(chn,val,1);
PrVal=val;
}
val=analogRead(1) / 8; //--Считываем значение с канала Y аналогично X
if (abs(val-PrVal) > 5)
{
MIDI.sendControlChange(chn+4,val,1);
PrVal=val;
}
}
Энкодер повесил на аппаратное прерывание.
Считывание энкодера
void enc() // Обработка энкодера
{
currenttime=millis();
if (abs(ltime-currenttime)>50) // антидребезг
{
b=digitalRead(4);
if (b == HIGH && eval<=122) eval=eval+5;
else if (b == LOW && eval>=5) eval=eval-5;
MIDI.sendControlChange(9,eval,1);
ltime = millis();
}
}
Печатную плату развёл в Sprint layout, Затем изготовил старым добрым ЛУТ"ом с использованием самоклеющейся плёнки и хлорного железа. Качество пайки страдает от ужасного припоя.
Готовый шилд:
Для заливки прошивки в ATmega32u4 я кратковременно замыкал 2 пина ICSP, затем использовал Flip . В дальнейшем подключил к этим пинам кнопку.
Прошивка работает, осталось прикрутить стенки и лицевую панель. Так как я размечал все по месту, то на рисование панели времени ушло больше, чем на всё остальное. Выглядело это так:
- 1. В качестве фона картинки выставлялась миллиметровка
- 2. Размечались отверстия
- 3. Полученное выводилось на печать
- 4. Вырезались все отверстия
- 5. Откручивались и снимались все элементы
- 6. Устанавливалась панель, устанавливались на места все кнопки/потенциометры
- 7. Отмечались несоответствия шаблона и корпуса
- 8. Переход к пункту 2, пока все отверстия не совпадут
Боковые стенки выпилил из фанеры.
Вид устройства на текущий момент:
Стоимость комплектующих:
- Arduino UNO R3 320 р.
- Фейдеры сп3-25а 5х9=45 р.
- Рот. потенциометры + ручки 85 р.
- Энкодер 15 р.
- Кнопки pbs-26b 16х19=304 р.
- Панель 240 р.
- Мультиплексор 16 р.
- Фанера, текстолит, тумблера, корпус от DVD — в моём случае бесплатно.
Контроллер справляется с возложенными на него задачами и рулит звуком практически в любой программе аудио обработки.
В планах покрыть фанеру морилкой и вырезать из оргстекла нижнюю крышку. Так же добавить порт расширения для подключения напольного контроллера.
Код для Arduino и печатка на гитхабе.
It wasn’t user controllable, BUT we learned an essential lesson: How to send a midi signal from an Arduino out of a midi port and to our computer.
Today, we’ll be learning how to make an actual . It can be controlled by knobs (potentiometers), faders, buttons, or in the example we’ll be talking about, switches.
First of all, I want to thank Bharat of Randumb for providing this information. Make sure to checkout his site for more awesome projects.
First, we’ll start by making this midi controller work over usb serial. Once you get that working flawlessly, you can apply the skills learned in my previous article on sending midi signals.
Let me know what you think of this build in the comment section below!
Recommended course : The DIY MIDI Controller Course . If you want to become a master at making your own custom controller, this is the course for you! Packed with 11 action-packed modules that include downloadable images, schematics, sample code, and libraries. Even if you’re a hobby musician that doesn’t know anything about circuitry or programming, this course breaks it down to an understandable sense.
What you need
The hardware needed is pretty basic. If you are going to be converting this project to full-on midi, you’ll additionally need some midi ports.
In this example we are using switches, but feel free to use anything else! Buttons work exactly the same.
An LED, a breadboard, and an enclosure are optional. If you are still in the experimental phase of your midi-mayhem, you can get away without those.
Hardware
- Arduino Uno
- 2x Switches, potentiometers, buttons, or faders
- Spare wires
- (Optional) LED
- (Optional) Bread Board
- (Optional) Enclosure
Software
- Arduino IDE (Link )
- Serial to MIDI converter (Link )
- Midi YOKE Virtual MIDI port (Link )
- MIDI-OX (to monitor midi signals) (Link )
Schematics
Here is the diagram for this project. Keep in mind that the schematic will vary if you decide to implement a midi port into this project.
A breadboard is used in the schematic. Although it is listed as an optional item, I’d still recommend purchasing one. They’re cheap and they make prototyping a hell of a lot easier.
Code
#define LED 13 // LED pin on Arduino board
#define switch1 10 // 1st Switch
#define switch2 9 // 2nd Switch
#define MIDI_COMMAND_CONTROL_CHANGE 0xB0
#define MIDI_COMMAND_NOTE_ON 0x90
#define MIDI_COMMAND_NOTE_OF 0x80
int switch1LastState = 0;
int switch1CurrentState = 0;
int switch2LastState = 0;
int switch2CurrentState = 0;
// the format of the message to send Via serial
uint8_t command;
uint8_t channel;
void blinkLed(byte num) { // Basic blink function
for (byte i=0;i digitalWrite(LED,HIGH); digitalWrite(LED,LOW); pinMode(LED, OUTPUT); pinMode(switch1,INPUT); pinMode(switch2, INPUT); Serial.begin(115200); t_midiMsg midiMsg1; // MIDI message for Switch 1 t_midiMsg midiMsg2; //MIDI message for Swtich 2 switch1CurrentState = digitalRead(switch1); switch2CurrentState = digitalRead(switch2); if (switch1CurrentState == 1){ if(switch1LastState == 0){ midiMsg1.msg.command = MIDI_COMMAND_CONTROL_CHANGE; midiMsg1.msg.channel = 1; midiMsg1.msg.data2 = 1; midiMsg1.msg.data3 = 0; /* Velocity */ /* Send note on */ Serial.write(midiMsg1.raw, sizeof(midiMsg1)); switch1LastState = switch1CurrentState; if (switch2CurrentState == 1){ if(switch2LastState == 0){ midiMsg2.msg.command = MIDI_COMMAND_CONTROL_CHANGE; midiMsg2.msg.channel = 2; midiMsg2.msg.data2 = 2; midiMsg2.msg.data3 = 0; /* Velocity */ /* Send note on */ Serial.write(midiMsg2.raw, sizeof(midiMsg2)); switch2LastState = switch2CurrentState; Like I mentioned earlier, you can apply the knowledge from my to convert this project into a true midi controller. Bharat had an interesting way to turn your Arduino into a midi device without the need of a midi port. Here’s how it works:
Basically, we’re going to be making the Arduino show up as an HID midi device. This is possible by installing midi firmware on your Arduino’s Atmeg8u2 chip. Keep in mind that using this method will be a pain if you plan to go back and revise your code. You’d have to reinstall the previous firmware and then go back to the midi firmware all over again. voilà!!
Hopefully by now your midi controller is fully functioning. Don’t hesitate to leave a comment down below if you can’t get your Arduino midi controller to function properly. I’d be happy to answer! В очередной раз играя на гитаре и управляя звуком через Peavey ReValver и прочие Amplitube, задумался о приобретении MIDI-контроллера. Фирменные устройства, вроде Guitar Rig Kontrol 3, стоят около 13 000 рублей, и обладают только напольным исполнением. То есть оперативно менять положения нескольких регуляторов весьма проблематично. Различные контроллеры DJ направленности выглядели интереснее за счет обилия фейдеров и энкодеров. Решено было совместить приятное с полезным и сделать MIDI-контроллер самому. Начальные требования: 2-7 фейдеров, столько же роторных потенциометров/энкодеров, около 10 кнопок, подключение по USB. Далее стал выбирать компоненты. Arduino выбрал по причине наличия, в принципе можно использовать ту же ATmega32u4, STM, либо другой контроллер. Фейдеры и кнопки нашел в местном радиомагазине. Энкодер и потенциометры уже были когда-то куплены. Тумблеры нашел в гараже. Корпус решил изготовить из верхней крышки DVD плеера. Комплектующие: Сначала согнул корпус и пропилил в нем бормашиной отверстия под фейдеры: Затем просверлил отверстия для тумблеров и рот. потенциометров, разметил положение кнопок. Так как сверла на 19 (да и соответствующего патрона для дрели) у меня не было, то отверстия для кнопок сверлил на 13, а затем увеличивал разверткой. Основа готова, теперь можно думать, как подключать все это добро к Arduino. Во время изучения данного вопроса наткнулся на замечательный проект . Это прошивка для ATmega16u2 на борту Arduino, благодаря которой устройство определяется как USB-HID MIDI device. Нам остаётся только отправлять данные MIDI по UART со скоростью 31250 бод. Чтобы не захламлять исходники дефайнами с кодами MIDI событий, я воспользовался . Так как я использовал Arduino, то решил сделать шилд, к которому уже и будут подключаться вся периферия. Как видно из схемы кнопки подключил по матричной схеме. Задействованы встроенные подтягивающие резисторы ATmega328, поэтому логика инверсная. for(byte i = 0; i < COLS; i++){ //--Конфигурируем строки мтрчн клвтр как выходы
pinMode(colPins[i], OUTPUT); //--подаём на них лог. 1
digitalWrite(colPins[i], HIGH);
}
for(byte i = 0; i < ROWS; i++){ //--Конфигурируем столбцы мтрчн клвтр как входы---------
pinMode(rowPins[i], INPUT); //--включаем встроенные в мк подтягивающие резисторы--
digitalWrite(rowPins[i], HIGH);
}
for(byte i = 0; i < COLS; i++) //-Цикл чтения матричной клавиатуры-----
{
digitalWrite(colPins[i], LOW); //--На считываемый столбец выставляем 0---
for(byte j = 0; j < ROWS; j++) //--Построчно считываем каждый столбец--
{ //--И при нажатой кнопке передаём ноту--
dval=digitalRead(rowPins[j]);
if (dval == LOW && buttonState[i][j] == HIGH) MIDI.sendNoteOn(kpdNote[j][i],127,1);
if (dval == HIGH && buttonState[i][j] == LOW) MIDI.sendNoteOff(kpdNote[j][i],127,1);
buttonState[i][j] = dval;
}
digitalWrite(colPins[i], HIGH);
}
Потенциометры подключены через мультиплексор 4052b к вводам АЦП. for(byte chn = 0; chn < 4; chn++) //-Цикл чтения значений потенциометров
{
set_mp_chn(chn); //--Задаём параметры мультиплексора
val=analogRead(0) / 8; //--Считываем значение с канала X
if (abs(val-PrVal) > 5) //--Если текущее значение отл. от прошлого
{ //--больше чем на 5, то посылаем новое значение
MIDI.sendControlChange(chn,val,1);
PrVal=val;
}
val=analogRead(1) / 8; //--Считываем значение с канала Y аналогично X
if (abs(val-PrVal) > 5)
{
MIDI.sendControlChange(chn+4,val,1);
PrVal=val;
}
}
void enc() // Обработка энкодера
{
currenttime=millis();
if (abs(ltime-currenttime)>50) // антидребезг
{
b=digitalRead(4);
if (b == HIGH && eval<=122) eval=eval+5;
else if (b == LOW && eval>=5) eval=eval-5;
MIDI.sendControlChange(9,eval,1);
ltime = millis();
}
}
Готовый шилд: Для заливки прошивки в ATmega32u4 я кратковременно замыкал 2 пина ICSP, затем использовал . В дальнейшем подключил к этим пинам кнопку. Прошивка работает, осталось прикрутить стенки и лицевую панель. Так как я размечал все по месту, то на рисование панели времени ушло больше, чем на всё остальное. Выглядело это так: Боковые стенки выпилил из фанеры. Вид устройства на текущий момент:
Стоимость комплектующих: Контроллер справляется с возложенными на него задачами и рулит звуком практически в любой программе аудио обработки. В планах покрыть фанеру морилкой и вырезать из оргстекла нижнюю крышку. Так же добавить порт расширения для подключения напольного контроллера. Код для Arduino и печатка на гитхабе. Большинство статей в интернете по изготовлению MIDI клавиатур, контроллеров, пультов и т.п. основываются на использовании MIDI-разъемов, подключение которых к современному компьютеру может оказаться проблематично. На старых звуковых картах был Game-порт, к которому можно было подключить джойстик или MIDI-устройство: Однако, все новые материнские платы идут с встроенным звуковым контроллером, да и на звуковых картах зачастую отсутствует возможность подключения MIDI-устройств. В данной статье я хочу показать, как можно на недорогом контроллере Arduino изготовить простейшую MIDI-клавиатуру с USB-подключением на 8 клавиш и колесом прокрутки. Итак, я использовал: Схема подключения следующая: Для подключения я использовал самый простейший вариант: 1 клавиша - 1 вход. Однако при большем числе клавиш, различных контролеров и т.п. входов может не хватить, поэтому придётся задействовать считывание данных либо через аналоговые входы (путем добавления резисторов разного номинала), либо путем мультиплексирования. Однако, если повесить несколько клавиш на аналоговый вход, то могут возникнуть проблемы со считыванием состояния, когда нажаты одновременно несколько клавиш. Поэтому, на мой взгляд мультиплексирование более приемлемый вариант. Структуру MIDI-данных я не буду рассматривать, т.к. это описано в статье: Энкодер подключен к входам аппаратного прерывания, описание работы с ним я рассматривать не буду, т.к. программа проста и взята с официального сайта Arduino. В данном проекте энкодер используется как колесо прокрутки для изменения модуляции (modulation wheel), однако его можно переназначить и для других целей (pitch bend и т.п.). MIDI-данные от энкодера, с Arduino посылаются следующей строкой: Отдельно стоит упомянуть Pitch Bend. Из спецификации MIDI следует, что необходимо послать сообщение из трех байт: 0xE0 (код Pitch Bend), MSB (старший байт), LSB (младший байт). Два крайних байта хранят 14-битное значение pitch которое может лежать в пределах 0...16383 (0x3FFF). Середина находится 0x2000, все что выше этого значения - происходить изменение высоты тона вверх, если ниже, то высота тона изменяется вниз. Код определения нажатия клавиши включает в себя три состояния: клавиша нажата, клавиша удерживается и клавиша отпущена. Сделано это для того, чтобы можно было передавать значение длительности нажатия клавиши. Если это не нужно, то можно оставить только одно состояние (нажатие клавиши), программа в данном случае существенно упростится. If (buttonState_C == HIGH && note_C_send_on == false) // Нажатие клавиши
{
noteOn(0x90, note_C, 0x7F);
note_C_send_on = true; // Команда Note On послана
note_C_send_off = false; // Команда Note Off не послана
}
else if (buttonState_C == HIGH && note_C_send_on == true) // Если клавиша удерживается
{
noteOn(0x00, note_C, 0x7F);
note_C_send_on = true;
note_C_send_off = false;
}
else if (buttonState_C == LOW && note_C_send_off == false) // Если клавишу отпустили
{
noteOn(0x90, note_C, 0x00);
note_C_send_on = false;
note_C_send_off = true;
encoder0Pos = 0; // Возвращаем позицию колеса в ноль
}
.......
.......
.......
// Функция посылки MIDI-сообщения в последовательный порт
void noteOn(int cmd, int pitch, int velocity) {
Serial.write(cmd);
Serial.write(pitch);
Serial.write(velocity);
delay(20);
}
Обратите внимание, что если будет использоваться pitch bend, то encoder0Pos нужно будет возвращать не в ноль, а в 0x2000 (а лучше задать define в начале программы). Итак, схема собрана, скетч в контроллер залит, запускаем Serial Monitor, меняем скорость передачи на 115200 и нажимая клавиши или крутя энкодер смотрим значения. Для того, чтобы принимать данные через USB виртуальный COM-порт от Arduino и передавать их в какую-либо программу MIDI-секвенсор, необходима специальная утилита: Serial MIDI Converter V2D (оф. сайт) Программа мультиплатформенная, у меня заработала под Windows 7 x64, правда с некоторыми тормозами. Запускаем ее, выбираем порт USB, скорость передачи (115200) и MIDI Input Port и MIDI Output Port. Теперь, все те MIDI-данные, которые поступают на USB виртуальный СОМ-порт 12 перенаправляются на порт MIDI Yoke 6 (для создания виртуальных MIDI портов я воспользовался программой MIDI Yoke). Можно перенаправить их на Microsoft GS Wavetable Synth и др. порты. Для визуального отображения поступающих MIDI данных с порта мне очень пригодилась программа MIDI-OX (оф. сайт): Обратите внимание, что в настройках MIDI Devices необходимо выставить порт MIDI Input. Теперь, нажимая клавиши нот или вращая колесо, в Monitor-Output вы увидите MIDI-данные. Т.о. при помощи программно-аппаратных средств мы получили возможность сделать на контроллере Arduino простейшую MIDI-клавиатуру с передачей данных в компьютер, для последующей их обработки, например в Cubase, в. т.ч. в реальном времени. Ниже вы можете скачать скетч INO, Serial MIDI Converter V2D, MIDI-OX и MIDI YokeTurning your Arduino into an actual midi device
Final Notes
Схема шилда:
Забыл разместить на печатке диоды, пришлось подпаивать к кнопкам.
Энкодер повесил на аппаратное прерывание.
Печатную плату развёл в Sprint layout, Затем изготовил старым добрым с использованием самоклеющейся плёнки и хлорного железа. Качество пайки страдает от ужасного припоя.
Панель изготовлена из миллиметрового ПЭТ, покрытого плёнкой с принтом и ламинированием, отверстия вырезались лазером по cdr файлу. У иркутских рекламщиков все это обошлось мне всего в 240 рублей.
Итого: 1025 руб.
Остается либо покупать современную MIDI-клавиатуру, ди-джейский пульт и т.п. с USB выходом подключения к компьютеру, либо покупать/паять переходник, или же покупать специальную звуковую карту с возможностью подключения MIDI-устройств. Купить конечно не проблема, но мы же на этом сайте не для этого собрались, верно?
контроллер Arduino UNO
8 шт. кнопок
8 резисторов 10 кОм
поворотный энкодер 25LB22-Q
макетная плата и перемычкиПрограммное обеспечение Arduino
noteOn(0xB0, 0x01, encoder0Pos);
где 0xB0 - сообщение контроллера (control change)
0x01 - код контроллера (в нашем случае Modulation)
encoder0Pos - значение контроллера (в нашем случае 0-127).
Меняя коды контроллера вы можете использовать колесо прокрутки (энкодер) для самых разных контроллеров.
В коде программы я закомментировал строчки если вы вдруг вместо modulation захотите использовать Pitch Bend (середина значения, разложение на 2 байта и др.)
Для обработки состояния каждой из восьми клавиш, используется следующий код:
Если все нормально, то переходим к следующей части. Сразу скажу, что для меня она оказалось самой проблемной, и если бы я не нашел виртуального USB -> Midi конвертора, то этой статьи не было бы.Программное обеспечение ПК (Windows)
Программа постоянно должна быть включенной. При нажатии клавиш или повороте ручки энкодера, внизу должен мигать индикатор Serial RX.
На основе данного проекта можно сделать DJ-пульт, полноценную MIDI-клавиатуру и т.п.