Реклама ⓘ
Главная » Arduino
Призовой фонд
на апрель 2024 г.
1. 100 руб.
От пользователей

Реклама ⓘ

Передача MIDI данных от Arduino в компьютер

Передача одиночного потока данных

От одного сенсора передать данные от Arduino в Max/MSP очень просто. Для примера возьмем потенциометр и подключим его к pin 0 контроллера Arduino. Контроллер будет считывать состояние потенциометра и передавать данные последовательным потоком в компьютер в ПО Max/MSP. Диапазон чисел от потенциометра будет лежать в пределах 0-127, что как раз подходит для MIDI.

Как только данные приняты Max/MSP, они сразу же будут перенаправлены на объект ctlout, что дает возможность контроля над любым параметром в любом приложении, которые принимают MIDI данные.

Подключение потенциометра к Arduino

Скетч для Arduino очень прост:

byte val;

void setup() { 
Serial.begin(57600); // Открываем последовательный вывод данных
} 

void loop() { 
val = analogRead(0) / 8; // считываем значение потенциометра и преобразовываем к диапазону 0 - 127 
Serial.print(val, BYTE); // отдаем значение в послед. порт
delay(5); // задержка
}
}

Патч для Max/MSP:

Патч для Max/MSP

Но что делать, если необходимо передавать данные от 2-х, 3-х, или сразу от 4-х потенциометров? Вот тут сразу начнутся проблемы. Дело в том, что в один промежуток времени может передаваться/приниматься только один байт. И будут возникать неизбежные задержки в передаче данных.

В данном варианте в первом байте будет содержаться информация от первого потенциометра, во втором байте - от второго. На стороне ПК, в MIDI-секвенсоре будет трудно разделять эти данные, да и неэффективно.

Передача многопоточных данных

Одним из решением данной проблемы является преобразование всех данных от потенциометров в MIDI-формат в контроллере Arduino, а затем уже передача MIDI-данных от Arduino в Max/MSP.

MIDI структура

Структура MIDI кажется сложной только на первый взгляд, на самом деле вы в ней быстро освоитесь. Каждое действие (взятие ноты, снятие ноты, питч-бенд и др.) передается в виде MIDI-событий. Мы будем работать с MIDI-событиями состоящими из трех байт. Соответственно в каждом байте хранится 8 бит и мы охватываем диапазон от 0 до 255.

Первый байт - статус, за ним идут 2 байта с данными. В статусном байте содержится информация о типе события, который мы передаем (взятие ноты, снятие ноты, пауза и т.п.) и номер канала от 1 до 16. Байты с данными содержат информацию о действии, к примеру если бы нажали клавишу какой-либо ноты, то данные будут содержать тон ноты и как резко вы ее нажали (velocity): Status Byte; Data Byte #1; Data Byte #2;

Байт статуса

Статусный байт разделен на два полубайта. Первый полубайт содержит биты 4-7 байта, а второй полубайт биты 0-3. Для удобства, принято использовать шестнадцатеричную систему счисления, т.о. первый полубайт может содержать значение от 0 до F, то же самое и второй 0-F.

Первый полубайт указывает на тип события:
8 = Note Off
9 = Note On
A = After Touch
B = Control Change
C = Patch Change
D = Channel Pressure
E = Pitch Bend
F = System Message

Второй полубайт указывает на номер канала:
0 = Канал 1
1 = Канал 2
2 = Канал 3
3 = Канал 4
4 = Канал 5
5 = Канал 6
6 = Канал 7
7 = Канал 8
8 = Канал 9
9 = Канал 10
A = Канал 11
B = Канал 12
C = Канал 13
D = Канал 14
E = Канал 15
F = Канал 16

Если совместить два полубайта, то мы получим всю необходимую информацию статусного байта о MIDI-действии. К примеру, если необходимо передать информацию о взятии ноты на 1-м канале, то значение статусного байта будет 0x90. Префикс 0x указывает на то, что используется шестнадцатеричная система счисления, 9 - взятие ноты, 0 - 1 канал. Или, если необходимо передать питч-бенд на 3-канале, то значение статус-байта будет 0xE2.

Байты данных

После того, как передан статусный байт, нужно передать два байта с данными. Для того, чтобы стало более понятно, приведу два примера:в первом будет взятие ноты (note-on), во втором сообщение контроллера (control change).

При взятии ноты в байте #1 содержится значение тона (pitch) в диапазоне 0-127. В байте #2 содержится значение velocity также в диапазоне 0-127. К примеру, если необходимо передать взятие ноты на 3 канале с pitch 60 и velocity 123, то последовательность байтов для передачи будет следующая:
0x92
60
123
В статусном байте 9 указывает на взятие ноты, 2 - третий канал. В следующем байте #1 цифра 60 указывает на тон, в байте #2 цифра 123 - значение velocity. Если передается взятие ноты (note-on), но с значением velocity - 0, то это равносильно снятию ноты (note-off).

Если статусный байт передает сообщение контроллера, то в 1-ом байте содержится номер контроллера 0-127, а во втором его значение 0-127. К примеру:
0xB4
1
82
Здесь значение B в статусном байте указывает, что это сообщение контроллера (control change), 4 - пятный канал. Первый байт данных содержит цифру 1, это контроллер Modulation. Второй байт содержит величину 82 контроллера.

Основные контроллеры MIDI

Modulation (CC #1)
Breath (CC #2)
Foot Pedal (CC #4)
Portamento Time (CC #5)
Volume (CC #7)
Pan (CC #10)
Expression (CC #11)
Soft Pedal (CC #68)

Передача данных с Arduino

Итак, после всего вышеописанного мы сможем легко посылать MIDI-данные с Arduino. Затем эти данные поступают в Max/MSP и дальше передаются в virtual MIDI path (IAC Driver Bus 1 под OS X или LooBe1 под Windows), а затем уже в музыкальное ПО или DAW (Live, Logic, ProTools, Reason).

Приведу примеры с взятием ноты и с передачей сообщения контроллера.

Пример 1. Отсылаем событие взятия ноты, пауза 1 сек, снятие ноты, пауза 1 сек.

Arduino

Скетч Arduino:

void setup() { 
Serial.begin(57600);
} 

void loop() { 
// посылаем note-on 
Serial.print(0x90, BYTE); // MIDI Note-on; канал 1 
Serial.print(60, BYTE); // MIDI note pitch 60 
Serial.print(127, BYTE); // MIDI note velocity 127 
delay(1000); // пауза 1 сек

// посылаем note-off 
Serial.print(0x90, BYTE); // MIDI Note-on; канал 1 
Serial.print(60, BYTE); // MIDI note pitch 60 
Serial.print(0, BYTE); // MIDI note velocity 0 (т.е. note off) 
delay(1000); // пауза 1 сек
}

Патч для Max/MSP:

Патч для Max/MSP

Пример 2. Отсылаем событие контроллера каждую секунду

Arduino

Скетч Arduino:

void setup() { 
Serial.begin(57600);
} 

void loop() { 
// посылаем сообщение контроллера
Serial.print(0xB2, BYTE); // MIDI control change; канал 3 
Serial.print(1, BYTE); // MIDI controller #1 
Serial.print(127, BYTE); // MIDI controller value of 127 
delay(1000); // пауза 1 сек
}

Патч для Max/MSP:

Патч для Max/MSP

Соединяем все воедино

Теперь, мы легко можем считает состояние нескольких потенциометров, сформировать и послать MIDI-данные в Max/MSP. Рассмотрим пару примеров.

Пример 1. Считываем значение потенциометров, подключенных к аналоговым входам 0 и 1. Эти значения будут посылаться в MIDI канал 1, контроллер 1 и канал 2, контроллер 1.

Arduino и 2 потенциометра

Скетч Arduino:

byte val = 0; 

void setup() { 
Serial.begin(57600);
} 

void loop() { 
val = analogRead(0) / 8; // считываем значение потенциометра 1

// let's send a control change message 
Serial.print(0xB0, BYTE); // MIDI control change; канал 1 
Serial.print(1, BYTE); // MIDI controller #1 
Serial.print(val, BYTE); // MIDI controller значение потенциометра 1 

val = analogRead(1) / 8; // считываем значение потенциометра 2 

// let's send a control change message 
Serial.print(0xB1, BYTE); // MIDI control change; канал 2 
Serial.print(1, BYTE); // MIDI controller #1 
Serial.print(val, BYTE); // MIDI controller значение потенциометра 2 
delay(5); 
}

Патч для Max/MSP:

Патч для Max/MSP

Пример 2. Считываем значение с 6 потенциометров и передаем данные контроллера 1 в канал 1, 2, 3, 4, 5 и 6.

Arduino и 6 потенциометров

Скетч Arduino:

byte val = 0; 

void setup() { 
Serial.begin(57600);
} 

void loop() { 
for(int i = 0; i < 6; i ++) { 
val = analogRead(i) / 8; // считываем значения потенциометров
// (на аналоговых входах 0 - 5) 

// посылаем сообщение контроллера

Serial.print(0xB0 + i, BYTE); // MIDI control change; номер канала 
Serial.print(1, BYTE); // MIDI controller #1 
Serial.print(val, BYTE); // MIDI controller значение от потенциометра 
delay(1); // пауза
} 
}

Патч для Max/MSP:

Патч для Max/MSP

Оригинал статьи

Теги:

Колтыков А.В. Опубликована: 2011 г. 0 0
Я собрал 0 0
x

Оценить статью

  • Техническая грамотность
  • Актуальность материала
  • Изложение материала
  • Полезность устройства
  • Повторяемость устройства
  • Орфография
0

Средний балл статьи: 0 Проголосовало: 0 чел.

Комментарии (9) | Я собрал (0) | Подписаться

0
Борис #
Здравствуйте. Скажите пожалуйста, а можно ли наоборот отправлять миди сообщения с компьютера на ардуино. Например играет нота С горит светодиод на pin1, играет нота G горит светодиод подключенный к pin2, играют обе ноты горят оба светодиода и т.п.? При этом идет синхронное воспроизведение этих нот через колонки компьютера
Ответить
0
talibanich #
Да, можно
Ответить
+1
Андрей #
А можно подробней, пожалуйста!
Ответить
0
Вячеслав #
Закидываю скетчи в ардуино и возникает вот такая ошибка:
sketch_mar26a.cpp: In function 'void loop()':
sketch_mar26a:5: error: 'BYTE' was not declared in this scope

As of Arduino 1.0, the 'BYTE' keyword is no longer supported.
Please use Serial.write() instead.
Как переделать код, дабы он поддерживался более свежим софтом ардуино?Т.е. без использования "BYTE"?
Ответить
0
Роман #
А если мне нужно не 6 переменных резисторов, а 60? И около 200 кнопок и всяких энкодеров и прочей лабуды - что делать тогда?
Ответить
0
talibanich #
Ответить
0
виктор #
Расскажите, пожалуйста, как максфорлайв настроить, чтобы он принимал сообщения от ардуино?
Ответить
-1
Роман #
Каким образом на Ардуино уно можно подключить больше потенциометров, штук 15?
Ответить
0
talibanich #
Вверху ответ на точно такой же вопрос.
Ответить
Добавить комментарий
Имя:
E-mail:
не публикуется
Текст:
Защита от спама:
В чем измеряется напряжение?
Файлы:
 
Для выбора нескольких файлов использйте CTRL

Raspberry Pi 2
Raspberry Pi 2
Мультиметр Mastech MS8268 Лазерный модуль 650нм 5мВт
вверх