Вопросы по преобразованию диапазонов
- Войдите на сайт для отправки комментариев
Здравствуйте. Помогите, пожалуйста, советом.
Задача: с аналогового датчика (софтпот https://www.sparkfun.com/products/8681, управляю выходными значениями пальцем) я читаю сигнал и преобразую его в диапазон для 37 значений функцией map для последующей передачи по миди. В общем-то, код простейший:
int val = analogRead (0); byte pitch = map (val, 0, 1023, 60, 96);
Собственно 60 и 96 - это границы высоты тонов, с которыми я работаю по миди. Сам потенциометр я стабилизировал конденсатором на 0,1 мкФ. Но возникает проблема, когда на потенциометре я держу палец на "пограничных" зонах. И например между 65 и 66 на мониторе серийного порта мне выдает нечто вроде:
66< 65 < 65> 66 <
И так далее совершенно рандомно. Как с этим бороться - не представляю, перепробовал разные варианты. Один из них - это написать 37 условий с разрывом диапазона такого типа:
if (val>=0 && val<=25) pitch=60; if (val>=30 && val<=54) pitch=61; ..... if (val>=998 && val<=1023) pitch=96;
Но не хочется перегружать код таким количеством условий (у меня будет 2 потенциометра) и к тому же скачок все равно есть, пусть и меньший. Ускорится ли выполнение кода, если засунуть эти условия в библиотеку? Или есть решение проще? Изучал подобные проекты, но ответа там для себя не нашел.
не понял, в чем ваша проблема - в том что данные прыгают с 65 на 66 и обратно? Или то что в мониторе появляется символ ">"
ПРосто когда я подключаюсь уже через конвертор к компу, в секвенсоре в этих положения пальца, соответственно, жуткий треск и перегруз. Дополню, что условия выполнения миди у меня такие:
Пишу не из своего скетча, могут быть синтаксические ошибки.
Соответственно в эти моменты мой код не может переназначить prpitch на pitch(чтобы замолчала предыдущая нота) и постоянно отсылает миди-сигнал, перегружая все и вся
IMHO, map функция тут не причем и 36 IF вам не помогут. У вас скачут исходные значения. Можно попробовать бороться с этим так же - как и с дребезкгом - переключать диапазоны только когда исходная величина находится в новом питче некоторое время
Вы имеете в виду сделать скользящее среднее значений аналогового сигнала до функции map? Я об этом и не подумал. Спасибо, попробую вечером.
Alex_Bryl, нужно делать гистерезис.
Покажу, как реализоваго у меня:
В MIDI используется 128 уровней, поэтому у меня сигналы от всех аналоговых органов управления приводятся из дмапазона 0-1023 к диапазону 0-127. Величина гистерезиса 6. Т.е. изменения менее чем на 6 единиц не фиксируются.
Всего используется 46 аналоговых регуляторов, подключенных к внешним АЦП MCP3008. Текущие значения заносятся в массив unsigned int ADC_data[46]; в функции, которая не приведена. В Вашем случае это будет просто analogRead().
Функция CheckControl(byte index) обрабатывает значение одного регулятора с номером index.
В результате обработки выходное значение помещается в массив byte control[46]; - это уже очищенное от дрожания значение, приведенное к диапазона MIDI.
В функции также проверяется, не пришло ли что-нибудт в MIDI-порт (функция CheckMIDIserial()) и при наличии изменения инициализируется вывод на экран (самого вывода на экран здесь нет по соображениям скорости реакции на сообщения). На экран выводится название изменившегося параметра и его новое значение.
Ускорится ли выполнение кода, если засунуть эти условия в библиотеку?
Ага, в Ленинскую засуньте - тогда ардуинка сразу на бздячей тяге к Марсу полетит.
З.Ы. Библиотека - такой же код на С++, как сам факт, что вы запрячете код туда, повлияет на его (кода) быстродействие?
Отчитываюсь по результатам.
Лучше всего помог вариат с гистерезизом. Вот как я его реализовал в простом варианте:
Звук на выходе получается четким и без дрожания, на мониторе порта еще попадается строчка с символами ">" или "<" при перемещении по датчику, но всего одна и видимо от нее не избавится, на результат уже не влияет.
Выглдит все очень просто и мне стыдно, что сам не догадался, так что спасибо за советы