Контроллер миди клавиатуры своими руками
MIDI контроллер на Atmega16U4
Автор: ProAlex, proalexx@yandex.ru
Опубликовано 21.07.2015
Создано при помощи КотоРед.
Многие музыканты, как профессиональные исполнители, так и любители, глядя на хорошее цифровое пианино, иногда думают про то, что ему не хватает колес и нескольких контроллеров, для того, чтобы можно было пофантазировать с тембрами. Но производители добавляют такие возможности, как правило на достаточно дорогих, концертных инструментах. А миди клавиатуры, часто не устраивают качеством самих клавиш, или размерами и весом инструмента, а иногда и ценой.
Поэтому я задумался над тем, как создать устройство, позволяющее восполнить данный недостаток. Поэксперементировав с разными микроконтроллерами, остановился на Atmega16U4 фирмы Atmel, как наиболее подходящий для решения данной задачи. Так же добавив в устройство возможность использовать его, как MIDI-USB переходник, для тех инструментов у которых отсутсвует USB-MIDI интерфейс.
В результате появился миди контроллер, который я назвал ATEMP MC1. Следующее видео показывает его возможности при разных вариантах включения.
Рассмотрим сначала теоретическую часть работы данного устройства.
1. Поток миди сообщений генерируется инструментом в случае разных действий со стороны музыканта. Это может быть, как нажатие клавиш инструмента, так и нажатия кнопки или поворота ручки контроллера. Миди сообщения в основном идут трех байтовой пачкой, но бывают и двух и одно и более трех. Например нажатие клавиши в сообщении выглядит, как 0x90 0x3C 0x40 (Note On/chan 0, Middle C, Velocity ), а изменения контроллера громкости, как 0xB0 0x07 0x40 (Control Change/chan0, Volume, Lеvel). Подробная информация о протоколе миди выложена на специальных сайтах, где с ней может подробно ознакомится любой желающий, например https://www.gweep.net/
2. Базовая функция устройства состоит в том, чтобы принимать со входа MIDI IN и передавать на выход MIDI OUT или USB порт все входящие миди сообщения, а для добавления в поток сообщения с собственных контроллеров, необходимо прерывать программу и считывая положение ручек контроллера вставлять эти сообщения в поток. При передачи в USB поток следует учитывать специфику данного протокола, так как здесь сообщения миди нужно дополнительно перепаковывать в пакеты USB. Например нажатие клавиши будет уже выглядеть, как 0x09 0x90 0x3C 0x40 ( Note-on message on virtual cable 0 (CN=0x0; CIN=0x9) Note On/chan 0, Middle C, Velocity)
3. Прерывание необходимо так же, для динамического сканирования кнопок ввода и вывода информации на четырех разрядный восьмисегментный индикатор.
4. В зависимости от настроек функций можно сдвигать нажатую клавишу на полутона вверх или вниз или плюс на октаву вверх или вниз, отключать активность клавиатуры, производить выбор инструмента, переключатся на работу на USB для передачи данных в программу секвенсор на компьютере.
Рассмотрим более подробно работу узлов данной схемы.
В Atmega16U4 для приема передачи данных миди сообщений мы используем порт USART1 его вход, выход RXD, TXD, и настраиваем его на частоту MIDI протокола, то есть Baud Rate: 31250 Гц, для считывания данных с потенциометров контроллеров используем входы ADC 1,2,4,5,6,7,8. Для динамического отображения на четырех разрядном восьмисегментном индикаторе, включенном по схеме с общим анодом и для подвески опроса кнопок используем для сегментов порт PB0..7, разрядов порт PD0..1 и PC6..7. Развязанные через диоды кнопки опрашиваются динамически на порт кнопок PD5 (в следующих статьях я на простом примере расскажу, как организовать простой драйвер для динамической индикации и опроса кнопок, в случае индикатора с общим анодом или катодом). Для прерывания необходимого для вывода информации на разряд индикатора, опроса нажатия кнопки, а так же запуска канала ADC я использую внутренний таймер TIMER0.
Для работы по аппаратному USB порту подключаемся к его D+ D-. Питание вся схема получает от USB порта. В MIDI протоколе для подключения и передачи приему данных используется схема — токовая петля через оптрон. Она позволяет гальванически развязать устройства, для предотвращения попадания в разные фазы. В данной схеме используется стандартное включение оптрона типа 4N33 наш аналог АОТ127А, в качестве буферного элемента используется микросхема 74LS00 наш аналог к555ла3, при достаточной крутизне спадов оптрона ее можно и не ставить, но тем не менее в миди адаптерах и прочих схемах для порта миди ее рекомендуют использовать.
Для корректной работы с USB портом я использовал стандартный Атмеловский стек series4-usb_software_library_template для данной серии микроконтроллеров U4 и в настройках usb_dexyinaors.c, h прописал конфигурацию класса миди порта, USB Endpoint dexyinaors для считывания и записи данных (описания взяты с сайта конфигураций usb.org: https://www.usb.org/developers/devclass_docs/midi10.pdf), он также подходит и для Atmega32U4, то есть в данной схеме они заменяемы, просто при компиляции надо указать под какой контроллер компилировать. В следующих статьях я поподробнее напишу про работу с этим удобным USB стеком, на стандартных примерах. Для программирования использую софтовый Атмеловский программатор Flip, через USB порт, чтобы программировать при включении нужно держать нажатой кнопку B4 подача низкого уровня на вход HWB запускает вшитый в чип загрузчик.
В качестве управления колесом питча и модуляции RV1,RV2 я использовал джойстик от пульта управления радиоуправляемыми моделями вертолета:), но можно поставить и колеса от старой миди клавиатуры или синтезатора.
Источник
Делаем MIDI-клавиатуру из старого детского синтезатора
В один из дней, возвращаясь домой, возле мусоропровода в подъезде я увидел старую детскую игрушку-синтезатор. Прошел мимо, так как брать с мусорки «грешно», но в душе захотелось утащить ее оттуда. Уже поздно ночью, где-то часа в 2 я решил посмотреть, не стоит ли она все еще там. И да, она все еще была там! С виду она был вполне целой и чистой, так что никакой брезгливости, чтобы не забирать ее не было. Так что да, я ее забрал.
Давно хотел себе пианино, я не профессиональный музыкант, но просто побаловаться — почему нет? Покупать что-то «ради побаловаться» меня «душила жаба», а тут — халявная игрушка. Когда я ее забирал с мусорки, то даже мысли не было пользоваться ей как детской игрушкой, была сразу мысль: «О-о-о…, хорошая база, чтобы попробовать сделать MIDI-клавиатуру».
Так как у меня уже есть некоторый опыт общения с профессиональными клавишными инструментами и MIDI-клавиатурами, то я сразу понимал все минусы моей идеи. То есть игрушка по факту так игрушкой и останется. На базе нее невозможно будет реализовать силу нажатия клавиш. Сами «легкие» пластиковые клавиши, которые к тому же еще и неполноразмерные не дадут возможности что-то на ней достойно исполнять.
В первую очередь синтезатор-игрушка была разобрана «до винтика», хорошо вымыт с мылом весь пластик. Также почищены платы и контактные группы клавиш.
После разборки пришло понимание, почему люди ее выкинули. У игрушки (не знаю от чего: от времени, от китайского качества комплектующих или жесткой эксплуатации) во-первых: развалились встроенные динамики, а во-вторых: в разъеме наушников торчал отломанный разъем от них, так что вытащить его не было практически никакой возможности. Наверное, после того как игрушка перестала играть встроенными динамиками, ей пользовались с наушниками, а потом после того как и там сломали разъем – просто выкинули.
Внутри игрушка-синтезатор состояла из трех плат, которые между собой были спаяны шлейфом проводов. Центральная плата, которая отвечала за генерацию звука и прочего, была сразу же отпаяна от двух других плат и отложена в сторону. На двух других платах находились контакты для кнопок на лицевой панели игрушки и непосредственно самих клавиш пианино. К ним я припаял разъемы PBS, тем более что шаг отверстий на платах как раз был 2.54 мм.
После этого я потратил пару часов на составление схем этих плат с клавишами. Как выяснилось, схема представляет простую матричную клавиатуру.
На картинке в желтых кружочках цифры – это номера контактов «горизонталей», а цифры на клавишах – номера контактов «вертикалей» в разъеме PBS-13 на плате клавиатуры.
После этого все это было закинуто в угол и пылилось целый год. И тут наступил период самоизоляции… Стало скучно и захотелось что-то поделать своими руками, тем более что ходить некуда, да и нельзя…
В итоге решил все-таки попробовать хоть немного доделать эту игрушку. В качестве основы для контроллера взята плата Arduino, а так как количество цепей клавиш больше, чем количество выводов Arduino UNO, то решил использовать сдвиговые регистры 74HC595 и 74HC165. В итоге получилась вот такая схема.
Схема была изначально собрана на беспаечной макетной плате. Для проверки работоспособности схемы (что нигде нет ошибок в соединениях) разработана тестовая программа, которая показала, что вроде как все работает. Алгоритм тестовой программы был простой: включается один из выходов микросхемы сдвигового вывода и считываются в цикле значения с микросхемы сдвигового ввода, нажимая при этом клавиши. На первый взгляд ничего не предвещало беды… и вроде бы все прекрасно работало…
Следующие несколько дней я не спеша занимался «домашним творчеством», а именно, аккуратно распаивал все компоненты платы на макетную плату. Собирал это все из того, что было у меня дома. В качестве управляющей платы взял Arduino NANO.
Такой «бутерброд» из плат обусловлен тем, что две платы игрушки (одна с кнопками, а вторая с клавиатурой) расположены на разном уровне и я, прежде чем паять все это подумал: «а нельзя ли это как-то соединить между собой, используя те компоненты, которые есть у меня дома, чтобы выглядело более или менее хорошо»? Так и получилась эта конструкция из двух плат, соединенных между собой разъемами. С моей точки зрения для домашнего варианта, когда сидим в самоизоляции, получилось достаточно хорошо. Пришлось только обрезать макетную плату и чуть-чуть доработать корпус игрушки, чтобы можно было подключать кабель USB в плату Arduino.
Осознание что устройство работает не совсем так, как я хотел, пришло тогда, когда доработал тестовую программу. Алгоритм был простой: по очереди включить каждый выход микросхемы 74HC595, считав при этом состояние входов у микросхемы 74HC165, и записать результат в отдельные переменные. Всего на клавиатуру подключено 5 выходов 74HC595, поэтому в итоге я получил 40 бит (5*8) данных после этого опроса. Строка из 40 бит выводилась в консоль, и нажимались клавиши, чтобы посмотреть, как устройство обрабатывает одновременные нажатия нескольких клавиш.
Тут-то и всплыла проблема: если нажимать по одной клавише, то все было отлично, но при попытке нажать более 2-х клавиш одновременно возникала ситуация, когда невозможно было предугадать, что будет прочитано. Результат мог быть правильным при одном сочетании, а при другом мог быть совсем непредсказуем. Проблема была в том, что не была учтена особенность данной схемы. При нажатии нескольких клавиш одновременно происходит замыкание не только нескольких вертикалей сканирования клавиатуры (это допустимо), но и могут быть замкнуты через клавиши несколько горизонталей (что никак не допустимо). Более подробно об этой проблеме и о способах ее решения можно почитать вот здесь.
Я выбрал «кардинальное решение» проблемы, а именно: решил, что на каждую клавишу в клавиатуре будет поставлено по диоду.
В голове я уже мысленно начал думать, как мне придется перерезать дорожки на плате и ставить в разрыв диод в SMD корпусе. Залез в свои запасники и увидел, что диодов в SMD корпусе в таком количестве у меня просто нет (не забываем, что все мы сидим на самоизоляции и поход в магазин за радиодеталями не очень возможен – так как это точно не предметы первой необходимости). Немного расстроившись, решил более внимательно посмотреть на плату: может быть есть возможность поставить на часть дорожек выводные диоды (их тоже какое-то количество у меня было). И тут я увидел, что у каждой клавиши, есть перемычка (плата односторонняя) и схема сделана так, что вместо этой перемычки можно поставить по диоду. Сразу же подумалось – даже и ничего резать не надо, надо только везде поставить вместо перемычек выводные диоды. Такого количества выводных диодов у меня тоже не было. В голове мелькнула мысль: «а может быть поставить светодиоды»? Работа схемы идет на уровне +5V и если поставить красные светодиоды, у которых минимальное падение напряжения (среди светодиодов), то в итоге должно хватать логического уровня для правильного определения: нажата клавиша или нет.
С этой мыслью я снова полез в свои запасы и выгреб откуда только можно было красных светодиодов. Их оказалось ровно столько, сколько клавиш на клавиатуре! Это знак, подумал я, и впаял для пробы несколько светодиодов вместо перемычек. Результаты тестирования показали, что решение рабочее. После этого запаял остальные светодиоды вместо перемычек. Тестовая программа показала, что можно нажать хоть все клавиши одновременно, и они все считываются правильно.
На дополнительные кнопки, которые есть на игрушке, решил не ставить диоды, потому что вряд ли их будут нажимать сразу несколько штук одновременно. Тем более что в программе у меня пока нет обработки нажатий на эти кнопки. Ну и я банально пока не придумал, как их использовать.
Настало время разобраться с тем, как сделать, чтобы это устройство виделось в компьютере как MIDI-клавиатура и в каком формате нужно отправлять данные.
Информация, найденная в интернете, говорила мне о том, что можно из Arduino сделать MIDI-клавиатуру очень легко и просто, если залить в нее прошивку, которая заставит компьютер видеть ее не как COM-порт, а именно как MIDI-клавиатуру. Изначально я на это решение и ориентировался, особо не вдаваясь в то, как оно реализовано.
Теперь, когда я добрался до него и внимательно прочитал, то понял, что моя плата Arduino NANO не подойдет для этого решения, так как у нее COM порт был реализован на базе микросхемы CH340. Для использования прошивки по ссылке выше подойдут только те платы, где USB-порт уже есть на контроллере (например: AtMega32u4) или же общение по COM-порту сделано не на микросхемах преобразования типа FT232RL и им подобным, а на микроконтроллерах AtMega. Поэтому прошивка в плате должна отдать данные в формате MIDI в COM порт, а на компьютере придется установить и настроить программное обеспечение, которое будет эти данные перехватывать и передавать в виртуальный MIDI-порт.
Алгоритм считывания клавиш и формирования MIDI-команд у меня получился следующий:
Нет смысла расписывать подробно, как работать с MIDI данными, потому что это можно прочитать здесь.
Остановлюсь чуть более подробно на программном обеспечении для компьютера и тех проблемах, с которыми я столкнулся. Проблемы возникли, просто из-за отсутствия нормальной документации на это программное обеспечение. Итак, для того, чтобы компьютер успешно мог принимать MIDI-данные с такого устройства как у меня, понадобится две программы: loopMIDI и Serial-Midi Converter. Для программы Serial-MIDI Converter дополнительно нужно установить Java, если на компьютере она не установлена.
Запускаем программу loopMIDI и создаем два виртуальных порта. Я назвал их «Arduino IN» и «Arduino OUT». Эта программа как раз и будет виртуальным MIDI-устройством.
Далее запускаем Serial-MIDI Converter и при запуске проходим процесс ее настройки. К сожалению, это приходиться делать каждый раз при запуске, но это не очень страшно, делается буквально в четыре нажатия на клавиатуре. Номер COM-порта может быть другой, он появляется на компьютере при подключении платы Arduino NANO. Скорость порта задается в прошивке Arduino NANO. Красными стрелками обозначены мои параметры, при которых у меня все работало.
Собственно на этом процесс настройки завершен и можно уже использовать какое-либо программное обеспечение, которое будет воспроизводить звуки, принимая нажатия клавиш от устройства. В настройках программного обеспечения необходимо выбрать в качестве входа «Arduino_OUT». На картинке ниже пример настройки Kontakt Player.
Работает в конечном итоге это вот так:
Что дальше? А дальше все произошло именно так, как я и ожидал – игрушка остается игрушкой ровно со всеми теми недостатками, о которых я упоминал в самом начале. Наверное, ребенку поиграть на таком будет в кайф, но вот взрослому человеку, после нормальных клавишных инструментов… Проще купить достаточно дешево любую MIDI-клавиатуру б/у и она будет на порядок лучше этой игрушки. Я решил оставить эту игрушку как она есть, но сделать некоторые модификации с ней:
- Оставить оригинальный корпус.
- Поставить исправные динамики и сделать усилитель для них.
- Сделать так, чтобы она работала в режиме «детской игрушки» без подключения к компьютеру, то есть, чтобы сама могла играть звуки.
- Сделать возможность подключения FootSwitch (та самая педаль на пианино внизу), чтобы можно было сделать удержание звука после отпускания клавиш, как на нормальном инструменте.
- Добавить в прошивке поддержку клавиш, которые сейчас не опрашиваются и не задействованы.
- Подключить в схему переменный резистор, который остался физически на панели игрушки-синтезатора, и добавить его функциональность в прошивку.
Реализацию большинства пунктов, пока все мы дружно «сидим дома», сделать не могу, так как у меня дома просто нет всех требуемых компонентов для этого.
Для реализации пункта 3 в интернете было найдено решение под названием SamplerBox. Суть проекта в том, что можно подключать любую MIDI-клавиатуру к плате Raspberry Pi, которая обрабатывает MIDI-команды с клавиатуры и воспроизводит звуки или переключает инструменты и т.д. Остается только поставить плату Raspberry Pi внутрь корпуса игрушки, без возможности замены SD-карты (не разбирая корпус), настроить кнопки на корпусе игрушки так, чтобы они переключали инструменты и этого будет достаточно, чтобы оставить этот проект в таком виде.
Но все это будет уже после того, когда закончится период самоизоляции.
Надеюсь, что кому-нибудь мой опыт окажется полезным.
Источник