Delay arduino: delay() — Arduino Reference

Arduino MIDI Delay — простые электронные музыкальные проекты своими руками

Кевин Новичок, MIDI-управление 6 минут

Как уже упоминалось, когда я делал свой MIDI In-Out Half-Shield, есть несколько полезных возможностей для эффектов, связанных с MIDI, поэтому это моя реализация задержки MIDI.

Это помечено как «новичок» с точки зрения «просто загрузите код и используйте его», но если вы хотите покопаться в коде, он действительно находится в категории «продвинутый» по содержанию. Но вам не нужно беспокоиться о внутренностях, чтобы начать играть с ним.

Внимание!  Я настоятельно рекомендую использовать старую или бывшую в употреблении клавиатуру для экспериментов с MIDI. Я не несу ответственности за любые повреждения дорогих инструментов!

Вот ключевые руководства по Arduino для основных концепций, используемых в этом проекте:

  • Arduino Timer1
  • MIDI-библиотека Arduino
  • Arduino без прерываний

Если вы новичок в Arduino, см. страницы «Начало работы».

Список запчастей

  • Ардуино Уно
  • MIDI In/Out Shield или модули (см. MIDI-интерфейсы Arduino)

Цепь

Цепи как таковой нет. Я снова использовал свой MIDI-щит, сделанный своими руками, как вы можете видеть здесь.

Как видите, я также использовал свой преобразователь Mini USB-MIDI в MIDI (питание от контактов Arduino 5V и GND), чтобы я мог воспроизводить его с помощью своих Korg miniKeys.

Код

Итак, «начинающий» уровень «все, что нужно знать» о коде выглядит следующим образом.

Реализует функцию задержки MIDI путем записи воспроизводимых нот и повторного воспроизведения после фиксированной задержки. Он может хранить до 16 заметок, но это настраивается (я тестировал только 16). Чтобы это работало, код отключит автоматическую функцию MIDI THRU библиотеки Arduino MIDI.

В верхней части файла есть ряд значений, которые можно использовать для установки параметров задержки. Есть комментарии, объясняющие их использование следующим образом.

 // MIDI-канал для прослушивания
// Установите его в MIDI_CHANNEL_OMNI для прослушивания на всех каналах
#define MIDI_CHANNEL 1
// Количество эхо для воспроизведения каждой ноты
# определить ЭХОС 5
// И задержка в миллисекундах между ними
#define ECHO_DELAY 300
// Мы можем уменьшить скорость каждого эха, если хотим
#define ECHO_DECR 30
// Вы можете изменить высоту эха с помощью этого значения
// Например, установите значение 1, чтобы каждое эхо повышалось на полтона
// или до -1, чтобы упасть на полтона. 
#define ECHO_SHIFT 0
 

Каждое эхо (5 в приведенном выше примере) будет возвращаться через заданный период времени (300 мс в примере) и громкость будет немного уменьшена (на 30 «шагов» выше).

Обработка задержки довольно грубая, поэтому будут обстоятельства, когда она не будет работать должным образом, но, надеюсь, это будет относительно редко!

Найдите его на GitHub здесь.

Далее следует более полное «расширенное» обсуждение кода!

Вероятно, существует множество способов реализации функции задержки, но все они должны учитывать следующее:

  • Чтобы воспроизвести ноту, вы должны отправить ноту On, а затем ноту off MIDI-событие.
  • Вы должны подумать о перекрывающихся нотах — некоторые ноты будут играть до того, как закончится предыдущая — например. играть аккорды.
  • Вам нужен какой-то способ запомнить, какие ноты были сыграны, а также сколько эхо ноты было сыграно.
  • Вы не можете использовать встроенные функции задержки () Arduino, так как выполнение всего другого кода останавливается, поэтому вы не сможете прослушивать новые (перекрывающиеся или иные) ноты.
  • Ноты, скорее всего, будут воспроизводиться нерегулярно (по сравнению с хорошими временными интервалами) и это должно быть сохранено при воспроизведении нот.
  • Вам нужно решить, что делать с другими MIDI-сообщениями — они пересылаются или игнорируются?

Чтобы придать коду ощущение времени, чтобы я мог считать задержки «вручную», я решил снова использовать библиотеку TimerOne. Это позволяет вам указать функцию, которая будет вызываться на обычном «тике», который вы определяете. Я решил, что вся работа по подсчету эха и измерению задержки может быть выполнена здесь. Я настроил код для «тика» 1 кГц, то есть для запуска каждую миллисекунду.

Основная логика, которой я придерживался, выглядит следующим образом.

 При получении примечания On:
   Воспроизведение ноты по MIDI
   Сохраните заметку в таблице
   Храните время, когда мы получили записку
Каждый «тик» кода:
   Просмотрите все сохраненные заметки и:
      ЕСЛИ нота все еще имеет эхо для воспроизведения И ее время истекло, ТО
         воспроизвести ноту по MIDI
         уменьшить количество эхо-сигналов, оставшихся для воспроизведения 

Я снова использовал функцию Arduino millis() для записи времени, когда была получена нота. Это записывает количество миллисекунд с момента включения Arduino и будет выполняться примерно через 50 лет. На самом деле, я записываю время, в которое я хочу воспроизвести эхо, так что на самом деле он сохраняет millis() + ECHO_DELAY.

Некоторые сложности включали, что делать с событиями note Off. В конце концов, я выбрал второе измерение времени millis(), чтобы записать время, в которое я затем хочу также отправить событие note Off. Опять же, это сохраняется как millis() + ECHO_DELAY.

Чтобы отслеживать ноты, которые нужно сыграть, я создал следующую структуру.

 // Нужно отслеживать, какие ноты находятся на разных стадиях задержки
#define NUMNOTES 16
структура delayNotes_s {
  беззнаковый длинный миллион;
  беззнаковый длинный миллиофф;
  байтовая заметка;
  байтовая скорость; // Здесь сохраняется только скорость NoteOn, поэтому нет "после касания"
  байтовый канал;
  количество байтов;
};
delayNotes_s delayNotes[NUMNOTES]; 

«count» изначально установлен на ECHOES, и эхо будет воспроизводиться, пока оно больше нуля. Он будет уменьшаться каждый раз, когда воспроизводится эхо.

Еще одна проблема, с которой следует быть осторожным, заключается в том, что ноты добавляются в эту структуру в основном потоке программы, хотя и с помощью функций обратного вызова MIDI, но ноты удаляются процедурой «tick». Это означает, что существует вероятность проблем с параллелизмом. Теперь это целая тема сама по себе, но в основном это означает, что я не хочу, чтобы галочка появлялась, пока я решаю, что один из моих «слотов для заметок» свободен, и начинаю заполнять его, иначе галочка может увидеть частично заполненная структура. Способ сделать это — временно отключить прерывания и, следовательно, функцию тика, пока я заполняю структуру — таким образом тик будет видеть только полную структуру.

Другие вещи, о которых следует помнить:

  • Мне нужно, чтобы подпрограмма отметок выполнялась как можно быстрее, иначе обработка основного потока кода невозможна. Один из способов сделать это — не просматривать каждый раз все 16 слотов для заметок, а вместо этого делать только один слот для заметок за тик.
  • Я нахожу следующую свободную ячейку в моем списке структур, ища записи, где «примечание» равно нулю.
  • Я не могу одновременно указать время дляmillOn иmillOff – я должен ждать, пока не получу сообщение note Off, чтобы установить миллиOff. Но мне нужно установить дляmillOff какое-то значение, иначе логика проверки галочки может пойти наперекосяк. Поэтому я устанавливаю для milliOff значение 0xFFFFFFFF, т. е. максимальное возможное длинное значение без знака, до тех пор, пока не получу событие note Off, после чего смогу установить его правильно.
  • Как только я нашел свободный слот и добавил в него новую ноту, я должен обязательно перестать просматривать структуру (я забыл об этом, и как только одна нота была сыграна, она заполняла структуру той же нотой !).
  • Возможно, что синхронизация времени включения и выключения ноты сбивается, если одновременно воспроизводится много одной и той же ноты. Теоретически этого не должно происходить, так как вам придется остановить воспроизведение ноты, чтобы воспроизвести ее снова, но если секвенсор или другой механизм допускает несколько событий «включения ноты» для одной и той же ноты перед любыми событиями «выключения ноты», может запутаться… (и я тоже).
  • Наконец, я, вероятно, должен отметить, что я не уменьшаю значение «count» для количества оставшихся эхо-сигналов до тех пор, пока я не сыграю «note off» для соответствующего эха.

Думаю, это почти все, о чем стоит упомянуть.

Заключительные мысли

Вероятно, это один из самых сложных эффектов, которые нужно пытаться закодировать. Другие опции включают арпеджиатор, который может быть вариантом предыдущего кода.

С каналами также можно делать причудливые вещи – напр. слияние или разделение, но в наши дни вы, вероятно, просто получите компьютер, чтобы управлять такими вещами за вас.

Кевин

Нравится:

Нравится Загрузка…

Просто еще одна душа, блуждающая по Интернету… Просмотреть все сообщения Кевина

Опубликовано

  • Arduino Multi-pot Mozzi FM Synthesis — пересмотренный вариант
  • Плата Arduino Mozzi Experimenter Shield — часть 2
  • Arduino Nano Multi-pot FM и синтез струн
  • Тоны Arduino — новая, новая надежда
  • Arduino Nano Multi-tone или PWM PCB — часть 2

КатегорииВыбрать категориюLo-Fi Orchestra  (43)Категории проектов  (338)   Arduino Tone  (33)   CD Rack Modules  (12)   Digital Synthesis   (37)   Digital Synthesis  (37)   Digital Synthesis  (19)   MIDI Control (92)   MIDI-интерфейсы  (51)   MIDI-мониторы (19)   Разное аппаратное обеспечение  (44)   Mozzi Synthesis  (31)   Дизайн печатной платы  (34)   Ударные инструменты  (6)   Секвенсоры  (23)   Одноплатные компьютеры   (18)   Модули синтезаторов  (25)   Touch Music (14) Сложность проекта  (323)    Дополнительно )   Начинающий  (55)   Средний  (130)Рабочие листы  (4)

74hc4067 объявление9833 адафрут аналог ардуино ардуино леонардо ардуино нано ардуино про мини ардуино уно atmega32u4 аудио оголенный метал кнопка емкостный датчик схемапитон неуклюжий миди изменение контроля дак ддс цифровые контакты цифро-аналоговое преобразование прямой цифровой синтез ударные пух Перо фильтр FM-синтез общий миди гранулированный синтез холст i2c или9488 клавиатура матрица клавиатуры клавиатура кикад ЛДР вел светодиодный дисплей светодиодная матрица лоу-фай группы лоу-фай классика лоу-фай темы лолшилд mcp3008 mcp4725 микропитон миди миди-контроллер миди фильтр миди слияние миди монитор миди роутер миди щит минииндексированный модульный синтезатор моцци мп3 мпр121 mt32-пи мультиплексор мультиплекс печатная плата ПКМ5102 пио полифония потенциометр изменение программы про микро ШИМ р2р Raspberry Pi малиновый пи пико реле резисторная лестница поворотный циферблат энкодер самд пробоотборник секвенсор семисегментный дисплей щит серийный номер программного обеспечения последовательность шагов телефон tft-дисплей планеты таймеры тон трогать сенсорный экран игрушка безделушка UART USB-хост usb-хост миди usb миди vs1003 vs1053 волновая таблица зинтиан

facebook.com/diyelectromusic/»> Простые электронные музыкальные проекты своими руками
Лоу-фай оркестр
Ищи:
  • Декабрь 2022 (2)
  • ноябрь 2022 (11)
  • Октябрь 2022 (11)
  • сентябрь 2022 (14)
  • август 2022 (9)
  • июль 2022 (4)
  • июнь 2022 (4)
  • май 2022 (11)
  • апрель 2022 (13)
  • март 2022 (15)
  • Февраль 2022 (7)
  • январь 2022 (12)
  • декабрь 2021 (6)
  • ноябрь 2021 (4)
  • Октябрь 2021 (10)
  • Сентябрь 2021 (9)
  • август 2021 (12)
  • июль 2021 (19)
  • июнь 2021 (17)
  • май 2021 (13)
  • апрель 2021 (10)
  • март 2021 (16)
  • Февраль 2021 (19)
  • январь 2021 (21)
  • Декабрь 2020 (11)
  • ноябрь 2020 (20)
  • Октябрь 2020 (13)
  • сентябрь 2020 (18)
  • август 2020 (19)
  • июль 2020 (8)
  • июнь 2020 (23)

Как и зачем использовать таймеры вместо функции Delay() — The Arduino Maker Man

Пожалуйста, положите немного денег в банке с чаевыми, нажав на кнопку пожертвовать, чтобы поддержать меня, чтобы я мог продолжать создавать конкуренцию, как это. P.S. пожалуйста, пожертвуйте более $ 1 как PayPal берет минимум 0,30 доллара США за транзакцию

 

Распространенная проблема с проектами Arduino заключается в том, что кнопки или другие датчики ввода работают с перебоями или с отложенной реакцией. В таких случаях ваш проект может страдать от задержек.

С самого начала нас учат использовать функцию delay(), если мы хотим создать временные задержки при выполнении определенных частей нашего скетча Arduino. Недостатком является то, что ваш цикл останавливается, а функции выше и ниже delay() не выполняются в течение этого интервала.

Подход с таймером немного сложнее реализовать, но ваш основной цикл продолжает выполняться и исключает только тот код и функции, которые вы хотите исключить. Чтобы упростить это, мы можем использовать библиотеки таймеров, такие как elapsedMillis.

Щелкните здесь, чтобы загрузить библиотеку elapsedMillis

Давайте кратко рассмотрим несколько простых примеров ниже.

Первым шагом является включение библиотеки и создание переменной экземпляра библиотеки. Это можно сделать в верхней части эскиза. Смотрите ниже, как это делается:

#include //загрузить библиотеку
elapsedMillis timeElapsed;//Создать экземпляр

Теперь в вашем цикле вы используете оператор if(), чтобы проверить, истек ли соответствующий интервал: и сбросить ваш таймер вернуться к нулю. Если вы хотите выполнять блок кода каждые 5 секунд, вы делаете что -то подобное:

Loop () {

IF (TimeElapsed> 5000)
{
Сделайте что -нибудь
истекшее время = 0; // сброс счетчика на 0, чтобы отсчет начался сначала…
  }

}

Пример

Чтобы проиллюстрировать эффект задержек, мы собираемся создать проект, который имеет 4 светодиода, которые будут мигать последовательно с интервал в одну секунду. У вас будет кнопка, которая зажжет все огни одновременно при нажатии.

Я создал 2 примера скетча, чтобы показать эффекты функции delay() и то, что происходит при использовании библиотеки elapsedMillis.h. Чтобы воссоздать демонстрацию, вам понадобится оборудование, указанное ниже 9.0007 Список материалов Fritzing

Список деталей

Сумма Тип детали Свойства
2 Красный светодиод цвет красный; пакет 5 мм [ТНТ]; ножка да
2 Желтый светодиод цвет желтый; пакет 5 мм [ТНТ]; ножка да
1 Arduino Uno (Rev3) — ICSP тип Arduino UNO (Rev3) — ICSP
4 Резистор 330 Ом сопротивление 330 Ом; допуск ±5%; полосы 4; пакет ТНТ
1 Резистор 10 кОм сопротивление 10 кОм; допуск ±5%; полосы 4; пакет ТНТ
1 Кнопка пакет [THT]

Настройка оборудования

Восстановите настройку оборудования, показанную ниже. Вы можете нажать на изображение, чтобы получить более четкое представление о том, как создавать соединения

Скетчи Arduino

Файлы для загрузки для этого проекта:

  • Timer_demo1.ino
  • Timer_demo2.ino
  • elapsedMillis-master.zip

После того, как вы создали первый файл setup_1demo.ino. и загрузите его в свой Arduino Uno. Убедитесь, что вы сначала загрузили файл elapsedMillis.h и установили его в Arduino IDE. Чтобы узнать, как установить библиотеку, нажмите здесь. Скетч Timer_demo1 использует задержки для последовательного мигания индикаторов. Когда вы нажимаете кнопку, чтобы зажечь все огни, вы заметите задержку реакции или похоже, что она работает только с перерывами.

Теперь загрузите Timer_demo2 и загрузите его в Arduino Uno. В этом скетче используется библиотека elapsedMillis. Вы видите, что код более сложный, но кнопка работает всякий раз, когда вы ее нажимаете. Вы не столкнетесь с задержками или прерывистой работой кнопки ввода.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *