Точність синхронізації MIDI з використанням Arduino


11

Я будую ці послідовники музики .

введіть тут опис зображення

Тільки це не зовсім секвенсор, це фізичний інтерфейс для секвенсора. Секвенсер - це програма, яка працює на ноутбуці, до якого підключається секвенсор, ця річ дозволяє користувачеві робити петлі барабана. Це досить весело, але для цього потрібен ноутбук, оскільки секвенсор не "вбудований".

Мені б хотілося зробити послідовність вбудованого мого пристрою.

Тепер припустимо, що я знаю, як вирішити відповідність класу для підключення USB MIDI, а також припустимо, що я можу розібратися, як підключити ардуїно для надсилання MIDI-приміток з 5-контактного порту DIN. Що мене найбільше хвилює, це темп переміщення у часі через невідповідність часу в хвилинній кількості за кожен цикл циклу подій.

Я знаю деякі речі:

  1. Не слід покладатися на delay()керування циклом темпу. Затримка зупиняє всю роботу вбудованого програмного забезпечення, і це не може працювати, тому що мені потрібно опитати фізичний інтерфейс користувача щодо змін під час запуску послідовності.

  2. Розрахунки на основі millis()краще, тому що прошивка може продовжувати працювати та діяти, коли минув певний підрахунок.

  3. Незважаючи на те, що жоден з моїх фізичних засобів управління не викликає переривання підпрограми, деякі операції можуть затримати роботу основного loop(). Якщо я спроектую функцію, яка чекає на введення користувачем, це, очевидно, може спричинити проблему відсутності "строку" для дії, якщо millis()підрахунок закінчився. Я знаю, що ця проблема є власним дизайном ...

Запитання:

A. Чи ардуїно на базі AVR є відповідним мікроконтролером для опитування користувальницького інтерфейсу та запуску критичного циклу хронометражу? Я знаю, що зараз Arduino на базі зброї - це набагато швидше. Буде Teensy 3.0 кращою альтернативою? Обидва ці плати 3,3 В, тож це ще один набір питань, з якими потрібно працювати ... але я поки що це ігнорую.

B. Чи слід розділити завдання на два мікропроцесори? Один для обробки опитування та оновлення користувальницького інтерфейсу, а другий для критичного циклу хронометражу місії.

c. Щось ще?

Моя головна мета - взагалі не потрібно користуватися комп’ютером. Я також хочу обчислити гойдалки, але в цьому випадку гойдалка не означає нічого, якщо у мене немає точного темпу. Дякую за вашу пораду!


1
Ардуїно завжди встановлює деякі перериви підпрограми, викликаючи тремтіння. У багатьох випадках це не проблема, але добре це усвідомлювати. noInterrupts();зупиняє тремтіння, але також зупиняє всі бажані переривання.
jippie

1
Коли ви говорите "робити секвенування на борту", чи означає це налаштування ударів за бар, BPM та бортовий трек? Тоді, мабуть, ви хочете запам’ятати натискання кнопок, які спрацьовували всередині панелі, щоб «мізки» пристрою могли надсилати міді-нотатки на ваш ноутбук? Тоді ви хочете видалити певні звуки перкусії, якщо ви знову натиснете їх на ноту, яка була записана раніше? І т.д. .. як далеко ти хочеш зайти? Зберігання ваших ударів? Створення послідовності смуг, які відповідають повній доріжці? Редагування певних барів? Зміна темпу конкретних барів? Це все їсть процесор, тому йдіть на кращий процесор.
Енді ака

Так, все.
Стів Кулі

2
Це милий вигляд, який ви зробили!
shuckc

3
Окрім сказаного іншими, це виглядає як думка, яку, можливо, ви маєте намір виробляти та продавати. Ардуїно коштує 20 доларів, а AVR - 2 долари. Ви не тільки отримаєте контроль над обладнанням, яке вимагає ваша програма, але ви заощадите багато грошей.
Філ Мороз

Відповіді:


5

Перерви є вашим другом для визначення чутливих до часу завдань, але лише якщо ви ставите критичні аспекти хронометражу в переривання, і немає інших переривань, які мають більш високий пріоритет. Мікроконтролери на "базі AVR" Arduino (наприклад, ATmega328P) мають фіксовані пріоритети переривання, як це детально описано на сторінці 58ff таблиці . Отже, якщо ви використовували TIMER2 COMPA в якості критичного переривання часу і жодних інших переривань, ви повинні бути в порядку (оскільки він має найвищий пріоритет). Якщо ви також хочете використовувати переривання з нижчим пріоритетом, вам потрібно переконатися, що всі вони повторно вмикають глобальні переривання під час входу у свою службову процедуру переривання:

Коли відбувається переривання, очищається I-біт загального переривання Enable, а всі переривання вимикаються. Користувацьке програмне забезпечення може записати логічний код на I-біт, щоб увімкнути вкладені переривання. Усі включені переривання можуть перервати поточну процедуру переривання.

(стор. 14 даних )

Це дещо відрізняється від Arduinos на базі ARM, оскільки в їх ядрі Cortex-M3 є "Вкладений векторний контролер переривань", де пріоритети не визначені (можна встановити в програмному забезпеченні), а вкладене управління перериваннями є нормою. Таким чином, що стосується критично важливих додатків, Arduino на основі ARM надасть вам більше гнучкості. Однак я не думаю, що це дійсно потрібно для вашої заявки.

Питання в тому, що насправді легко реалізувати ці речі з бібліотеками Arduino. Для досягнення найкращої продуктивності вам, мабуть, доведеться певною мірою кодувати поза бібліотеками, принаймні, для критичних бітів хронометражу, тобто уникати таких речей, як delay () або millis ().

Потрібно розділити чи ні, залежить від того, яку обробку ви плануєте зробити. Знову ж таки, вихід за межі бібліотек потенційно може забезпечити вам кращу ефективність.


3

Це, за умови відповідного програмування, найвиразніше можна зробити на ATmega328P (дещо залежно від складності барабанного циклу. Я припускаю, що ~ <50 барабанних подій у циклі. Це розумно?).

Зауважте, що я сказав ATmega328P , не обов'язково Arduino .

У середовищі Arduino багато предметів за замовчуванням відбувається у фоновому режимі, що робить надзвичайно детермінованим програмування (оскільки вам знадобиться щось критичне для часу) складне завдання.

Справжнє питання, яке вам потрібно задати тут, - наскільки ви зацікавлені в програмуванні, а наскільки ви зацікавлені в розробці інструменту?

Хоча я цілком впевнений , що це можна робити все , що ви хочете на одного ATmega (петлі барабана, кілька аналогових входів, LCD, кнопки, MIDI інтерфейс), реальний питання , скільки роботи буде вичавити все , що в? Знову ж таки, ви хочете навчитися оптимізувати вбудований код MCU або створювати інструменти? Досить легко просто перейти до більш швидкого MCU, якщо потрібно, але вам потрібно визначити продуктивність MCU, яка вам зараз потрібна , тому шість місяців роботи, ви не розумієте, що не можете зробити так, щоб все працювало так швидко, як ви потреба.


Якби я був ти, перше, що я б зробив, це змусити його працювати без ардуїно (в основному, ставитися до цього як до сирого ATmega та використовувати AVR-студію чи подібне). Тоді ви можете набагато ефективніше проаналізувати, яка саме продуктивність вам потрібна, і якщо ATmega зможе керувати нею.

Коли ви не будете мати ардуїно, ви можете набагато вільніше використовувати різні MCU (вони, як правило, більш схожі, ніж різні. Якщо ви можете розібратися з документацією, ви, ймовірно, можете зробити те ж саме для інших).

Я нещодавно працював з пристроями ATxmega, і вони дуже приємні. Ви отримуєте три пріоритети переривання, які полегшують управління критично важливими для часу речами. З ними також дуже приємно працювати (Зразкові периферійні конструкції! Зручні структури портів! І т.д. ...).

Є також пристрої LPC від NXP, які базуються на ARM, а також деякі ARM-пристрої Atmel (як використовуються на Arduino Due) або MCU-модулі STM32 від ST. Будь-яка з них матиме значно більшу продуктивність, ніж ATmega або навіть ATxmega.

Основним недоліком більшого, більш потужного процесора є ціна, але якщо ви не робите тисячі цих одиниць, витрати на збірку та виготовлення на одиницю настільки значно перевищуватимуть різницю у витратах (що, швидше за все, буде лише декілька доларів ) що це в основному не має значення.


Примітно, що для комерційного продукту Arduino - це просто не той шлях - вони живуть голодно, повільно, а IDE не розроблений для оптимального (швидкого / маленького) коду, а зручності та простого навчання. За менших витрат у вас може бути навіть STM32 F4 (32-бітний Cortex M4> 100 МГц) або подібний, хоча це буде надмірним. Я думаю, щось подібне до одного з менших PIC32, Cortex M3s або AVR32 - це, мабуть, шлях. Численні пріоритети перерв, DMA, витончена периферія, швидка / низька потужність та велика кількість оперативної пам’яті робить його легким вибором порівняно з Arduino.
Олі Глазер

@OliGlaser - Я думаю , вам потрібно чітко розмежувати між Arduino і ATmega . Ви можете робити невеликий швидкий код на ATmega, і що ATmega може бути навіть на дошці Arduino. З іншого боку, "IDE" Arduino - це один із найшмішніших редакторів коду, який я коли-небудь використовував. З іншого боку, завантажувач OptiBoot дуже приємний. Тільки тому, що деякі частини - це лайно, не означає, що ви повинні кинути всю справу.
Коннор Вольф

Абсолютно - я мав на увазі Arduino в цілому, включені дошка та IDE - не ATmega, який, напевне, такий же хороший, як і будь-який інший порівнянний UC (PIC16 / 18F тощо), я б включив його до свого списку, але Я думаю, якщо ціна між 8-бітною та 16/32-бітною є настільки близькою, що сьогодні, мабуть, гарна ідея витратити додаткові $ 1 і знати, що у вас є запас енергії процесора (якщо, як ви вже згадували, ми говоримо про величезну кількість і побудували до абсолютної найнижчої ціни, але тоді я сумніваюся, Ардуїно вважався б :-))
Олі Глазер

1

Мені потрібно було прочитати таймери, перш ніж я почав думати про точність синхронізації (також будувати секвенсор секції міді з ардуїно, хоча це гарантовано виглядає менш круто, ніж ті ^^). Ця серія статей була найбільш інформативною:

http://maxembedded.com/category/microcontrollers-2/atmel-avr/avr-timers-atmel-avr/

Зараз я думаю, що моє рішення отримати точний термін буде.

A. Використовуйте AVR arduino

B. Зберігайте завдання на одному мікропроцесорі

C. Мудро використовуйте дошкільні пристрої, таймери та переривання, щоб отримати необхідну точність.

ОНОВЛЕННЯ

Використовуючи основний підручник з міді для Arduino та переглянувши цю статтю про таймери та дошкільні прилади, наступний код - це те, що я придумав. Код використовує режим timer1 та CTC для відтворення ноти міді на кожну чверть секунди та відмітки щоквартальної секунди (що має становити рівно 120 bpm). На жаль, це все ще відбувається лише повільніше, ніж 120pm, хоча це найближче, що я дістав ...

// Includes
#include <avr/io.h>
#include <avr/interrupt.h>

int last_action=0;

void setup()
{
    //  Set MIDI baud rate:
    Serial.begin(31250);

    // initialize Timer1
    cli();          // disable global interrupts
    TCCR1A = 0;     // set entire TCCR1A register to 0
    TCCR1B = 0;     // same for TCCR1B

    // set compare match register to desired timer count:
    OCR1A = 15624;
    // turn on CTC mode:
    TCCR1B |= (1 << WGM12);
    // Set CS12 bits for 256 prescaler:
    TCCR1B |= (1 << CS12);
    // enable timer compare interrupt:
    TIMSK1 |= (1 << OCIE1A);
    // enable global interrupts:
    sei();
}

void loop()
{
    // do some crazy stuff while my midi notes are playing
}

ISR(TIMER1_COMPA_vect)
{
  // Turn notes on
  if (last_action == 0) {
    send_note(0x90, 60, 0x45);
    last_action = 1;

  // Turn notes off
  } else {
    send_note(0x90, 60, 0x00);
    last_action = 0;
  }
}

//  plays a MIDI note
void send_note(int cmd, int pitch, int velocity) {
  Serial.write(cmd);
  Serial.write(pitch);
  Serial.write(velocity);
}

ОНОВЛЕННЯ

Я боровся з цим вже ~ 24 години і, нарешті, отримав кілька відповідей з форуму. Я думаю, що код, який я використовував вище ^^, досить хороший. Використання ISR, використання режиму CTC та prescalers і т. Д. Після звернення до форуму я думаю, що рішення полягає не в тому, щоб досягти точності на секвентарі midi, але отримати всю мою апаратну установку (мої синтезатори та пробовідбірники) підключені до того ж самого годинник міді, незалежно від того, годинник походить від Ардуїно чи ні.


0

Залежно від того, наскільки поступово ви хочете здійснити перехід від прив'язаного комп'ютера до системи на основі µC, ви можете розглянути можливість розміщення Raspberry Pi всередині цього вікна ( роздрібний продаж у розмірі 25-35 доларів ). Таким чином, ви можете мати повний (хоч і малопотужний) комп'ютер на базі Linux з USB-портами та GPIO-штифтами.


Я впевнений, що є щити розширення або як би вони їх називали для Pi, але на борту є 17 штифтів GPIO. Я використовую кожен шпильку на мега arduino. 31 такт + 30 світлодіодів, 10 аналогових дюймів 70+ введення / виведення.
Стів Кулі

О, я мав на увазі, якщо найближчою метою було видалення зовнішнього комп'ютера, ви можете зберегти "секвенсор [це] додаток, який працює на ноутбуці" і запустити його на Pi, внутрішньо підключеному до вашої існуючої системи так само, як це підключено зараз.
Роб Старлінг

@SteveCooley - Здається, вам потрібно вивчити IO мультиплексування / матриці кнопок. Вам не знадобиться цілий виділений рядок вводу-виводу на одну кнопку.
Коннор Вольф

@SteveCooley - Чорт, вам навіть не потрібна матрична кнопка. Ви можете зробити ВСІ свої цифрові IO, використовуючи лише 4 штифти rPi. Просто повісьте всі кнопки та світлодіоди на деякі регістри зсуву (паралельно-послідовний для кнопок, послідовно-паралельний для світлодіодів) та заведіть регістри зсуву з SPI-порту rPi. Ви можете легко отримати> 1 КГц швидкості оновлення для всієї матриці за допомогою апаратного забезпечення SPI.
Коннор Вольф

Якщо ви використовуєте Argaino Mega єдиною причиною використання IO, ви витрачаєте багато грошей на те, що можна зробити дуже легко за допомогою декількох зовнішніх пристроїв за <3 $.
Коннор Вольф
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.