Портал для радиолюбителей
   Передача MIDI данных от Arduino в компьютер
    Главная -> Статьи -> Проекты на Arduino -> Передача MIDI данных от Arduino в компьютер


<< Назад в раздел   Распечатать Дата добавления: 2011-10-25 | Просмотров: 10982

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

От одного сенсора передать данные от 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

Оригинал статьи на английском языке (перевод Колтыков А.В.)


Добавил:  Павел (Admin)  
Автор:  Неизвестно 

Вас может заинтересовать:

  1. Командная оболочка Bitlash на Arduino
  2. Arduino UNO урок 8 - Ночник
  3. Счетчик расхода воды с термодатчиком и показаниями через интернет
  4. DDS-генератор синусоидального сигнала
  5. Arduino UNO урок 9 - Управление мощной нагрузкой


    © PavKo, 2007-2018   Обратная связь   Ссылки   Яндекс.Метрика