H USB MIDI-контроллер на Arduino Из песочницы. Информационный портал по безопасности
В очередной раз играя на гитаре и управляя звуком через 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 и печатка на гитхабе.
Некоторые музыканты, которые разбираются в электронике, или электронщики, которым нравится музицировать, хотели бы подключить своё MIDI-устройство к Arduino, но не знают как это правильно сделать. Данный проект поможет разобраться в этом вопросе.
Для начала немного разберемся, что такое MIDI. MIDI расшифровывается как Musical Instrument Digital Interface или по-русски цифровой интерфейс музыкальных инструментов. В передаваемом коде этого интерфейса могут быть зашифрованы параметры громкости, тональности, темпа и других характеристик музыкальных инструментов. Данные интерфейса MIDI обычно передаются по пятипрошодным шинам с разъемами круглой формы DIN 41524 также с пятью контактами, как показано будет на схеме, приведенной ниже. Стандартная скорость передачи данных такого последовательного интерфейса составляет 31.25 кбит/с. Передача осуществляется однонаправленно, то есть в связанной интерфейсом MIDI системе музыкальные инструменты, например, синтезаторы могут только передавать данные головному устройству, например, пульту управления звуковым окружением или компьютеру. Следует помнить, что данные интерфейса MIDI представляют собой не оцифрованный звук, а команды и значения, например, ноты, параметры звука и т.п.
Необходимые компоненты
- 5-выводной разъём DIN/MIDI – 1 шт.
- Оптопара 4n35 или аналог – 1 шт.
- Диод IN914 или аналог – 1 шт.
- Резистор 220 Ом – 1 шт.
- Резистор 560 Ом (можно 220 и 230 в послед.) – 1 шт.
- Монтажная плата – 1 шт.
- Arduino – 1 шт.
- Кабель MIDI – 1 шт.
- MIDI-устройство – 1 шт.
Схема подключения Arduino к MIDI-устройствам
Схема, созданная с помощью fritzing, довольно подробно показывает соединения компонентов. Всё здесь подключается достаточно просто и легко. В основе схемы мы видим микросхему оптической гальванической развязки. Эта оптопара нужна для гальванической развязки линии MIDI от схемы Arduino. Без неё можно сжечь вход Arduino. В данном случае была взята оптопара серии 4n35, состоящая из светодиода и фототранзистора, впрочем, вместо нее подойдет любой другой оптрон со схожими характеристиками.
Будьте внимательны при подключении диода, соблюдайте полярность. Данная схема была создана с учетом стандартов и характеристик интерфейса MIDI. Оригина схемы можно найти здесь http://www.midi.org/techspecs/electrispec.php
Код (скетч для Arduino)
Это простой скрипт взаимодействия с MIDI с использованием библиотеки MIDI.h (скрипт MIDI CALLBACK). Он проверяет, поступил ли сигнал (нота) NoteOn и переходит в соответствующую область обработки. В эту область вы можете вставить свой код.
#include
Индикатор нажатия клавиш
Используем цветную светодиодную ленту для индикации номера и силы нажатия клавиши синтезатора.
Понадобится:
midi-ledStrip.ino #includeВ очередной раз играя на гитаре и управляя звуком через 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 и печатка на гитхабе.
В очередной раз играя на гитаре и управляя звуком через 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. Во время изучения данного вопроса наткнулся на замечательный проект . Это прошивка для 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, затем использовал . В дальнейшем подключил к этим пинам кнопку.
Прошивка работает, осталось прикрутить стенки и лицевую панель. Так как я размечал все по месту, то на рисование панели времени ушло больше, чем на всё остальное. Выглядело это так:
- 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 и печатка на гитхабе.