Самодельные электронные ударные

Тема в разделе "Arduino & Shields", создана пользователем Dan, 24 дек 2016.

  1. Dan

    Dan Гик

    Аа, понятно
     
  2. mcureenab

    mcureenab Гуру

    Но от программирования это не спасет.)))
     
  3. mcureenab

    mcureenab Гуру

    Добавьте цикл:

    Код (C++):
    KICK_VAL = analogRead(KICK);
           if(KICK_VAL > KICK_THRESHOLD)
           {
                        while(1){ // ждём пик
                            int kv = analogRead(KICK);
                            if(kv <  KICK_VAL ) break;
                            KICK_VAL = kv;
                        }
                        velocity =(KICK_VAL *127)/50;
                       // t_note = (velocity*(0.6*velocity)); пока закомментил
     
  4. mcureenab

    mcureenab Гуру

    После звука ноты добавьте цикл:
    Код (C++):
    MIDI.sendNoteOn(KICK_DRUM, velocity, 1);
                            delay(10); // условно дадим ноте прозвучать. потом заменить 10 на расчетное значение длительности
                MIDI.sendNoteOff(KICK_DRUM, 0, 1);
                        while(KICK_THRESHOLD*0.8  < analogRead(KICK)){}; // убедимся, что датчик успокоился. лучше, чтобы это происходило за время звучания ноты
     
     
    Последнее редактирование: 10 янв 2017
  5. mcureenab

    mcureenab Гуру

    Чтобы получить больше градаций громкости используйте меньшее значение референсного напряжения АЦП. Оно задается функцией
     
  6. Dan

    Dan Гик

    Ну это не страшно)уже есть сдвиги в лучшую сторону, нужно еще пытаться)
     
  7. Dan

    Dan Гик

    попробовал Ваши вставки в код, стало лучше, уже удар стал четче, дребезг, правда, остался. Тут по ходу нужно еще с длительностью ноты пробовать
     
  8. mcureenab

    mcureenab Гуру

    С дребезгом может быть сглаживающий фильтр недостаточно хорош.
    Может быть удар действительно несколько раз происходит. Вместо
    KICK_THRESHOLD*0.8
    можно попробовать меньше коэффициент взять. Этот порог должен быть немного выше фонового шума.
    И дать время прозвучать ноте и успокоится датчику.
     
  9. Dan

    Dan Гик

    А кстати вот еще вопрос: здесь не одно и то же значение сравнивается друг с другом?
    Ведь обе переменные считывают один и тот же сигнал. Ударили со скоростью 127, и вторая переменная kv ведь тоже равна этому значению. Или я все же что-то путаю?
     
  10. mcureenab

    mcureenab Гуру

    Напряжение на пине A0 меняется, поэтому analogRead каждый раз возвращает обновленное значение напряжения.
    Я думаю, что после удара и первого analogRead еще 1 - 2 запроса analogRead возвращают все большее значение, а потом напряжение начинает падать.
     
  11. sslobodyan

    sslobodyan Гик

    Никакие фильтры не помогут. Любой фильтр вносит задержку, а скетчу необходимо максимально быстро обслуживать несколько датчиков. Иначе и не надейтесь на быстрые дроби. Выше я намекал как надо делать. Забудьте о delay внутри цикла опроса.
     
  12. Dan

    Dan Гик

    то есть это все-таки скорее программная проблема, нежели аппаратная?)
    и можно ли тот скетч, есть на данный момент (выложен выше) доделать так, чтобы не было ложных срабатываний датчика или его дребезга?
     
  13. rkit

    rkit Гуру

    Чтобы понять, где проблема, надо знать, что вообще происходит. А для этого надо потыкать осциллографом. Или, хотя бы. оттрасировать чтение с аналогового пина.
     
  14. Dan

    Dan Гик

    с аналогового входа только значения ударов могу предоставить, не более. осциллографа нет
     
  15. sslobodyan

    sslobodyan Гик

    Код (C++):

    #define TIME_SENSOR 3000
    uint32_t time_on=0;
    int tmp;

    void loop()   {
      if (time_on > 0) {
        if (micros() > time_on) { // нота уже должна отзвучать
          time_on=0;
          MIDI.sendNoteOff(KICK_DRUM, 0, 1);
          KICK_VAL = 0;
        }
      }
      else {
        tmp = analogRead(KICK);
        if (tmp > KICK_THRESHOLD) {
          if (tmp < KICK_VAL) { // датчик пошел на спад - пик уже получен
            velocity = (KICK_VAL * 127) / 50; // 50 подобрать
            MIDI.sendNoteOn(KICK_DRUM, velocity, 1);
            time_on = micros() + TIME_SENSOR;
          } else {
            KICK_VAL = tmp; // сигнал сенсора еще растет - запоминаем
          }
        }
      }
    }
     
    Проверьте этот код. Нужно будет только подобрать коефф для пересчета громкости (50) в зависимости от максимального напряжения с сенсора и определить максимальную длительность звучания ноты в дефайне TIME_SENSOR. Эта длительность должна быть БОЛЬШЕ длительности колебаний сенсора, иначе получите фантомные ноты.
    Могу ошибаться, но кмк перкуссии не требуют гашения ноты, это же не пианино и не духовые. Попробуйте вообще sendNoteOff не слать.
    Обратите внимание - нигде нет задержек, все просчитываем максимально быстро. Надеюсь, доработать скетч для нескольких датчиков получится самостоятельно?
     
    Последнее редактирование: 12 янв 2017
  16. Dan

    Dan Гик

    Завтра постараюсь попробовать, спасибо большое за такой кусок скетча, не терпится потестить
     
  17. mcureenab

    mcureenab Гуру

    Тут бы с одним датчиком разобраться. И delay не помеха. В вашем скетче тоже задержка в 3 мс заведена. Хотя у вас это время можно использовать на обработку других датчиков, что определенно хорошо, если не считать затраты на вызов loop и сравнение микросекунд.

    Сглаживающий фильтр не создает задержку, если правильно рассчитан. Но позволяет убрать высокочастотную составляющую - собственные колебания датчика на частоте примерно 4кГц. Если это не сделать придется тратить время МК на исключение ложных срабатываний или просто ждать.

    3 мс на затухание колебаний тут не достаточно. Судя по эксперимента даже 10мс не достаточно. Возможно, эта задержка должна быть меньше звучания ноты, например чтобы дробь создавать. Этот момент еще не учтен, если только MIDI синтезатор это сам не делает.

    Дробь это сколько ударов в минуту? Исходя из этого нужно рассчитывать фильтр и нагрузку датчика. Если датчик с обвязкой звенит дольше чем нужно, то о чем тогда говорить?
     
  18. mcureenab

    mcureenab Гуру

    Думаю, это скетч не решает имеющиеся проблемы и даже может быть немного менее стабильным, поскольку на одно измерение тратит немного больше времени и не ловит физическое затухание датчика (просто ждет около 3000 мкс). Но он хорош тем, что его просто адаптировать под обработку нескольких датчиков, кнопок и прочее.

    Погоняйте датчик с фильтром на скетче осциллограф. Много вопросов будет снято. Пока все идет методом тыка.
     
  19. sslobodyan

    sslobodyan Гик

    Где вы у меня увидели задержку? В каком месте проц задерживает обработку остального алгоритма?

    Вы обратили внимание на RC цепочку в схеме? Откуда там будет 4 килогерца? Ведь эта цепочка специально стоит для того, чтобы перевести колебания в однократный подъем-спуск.

    Вы полностью комментарии моего кода читали? Я там достаточно четко написал, что TIME_SENSOR должно быть больше времени колебания датчика для исключения фантомов. Вы экспериментально подтверждаете 10мс? Прекрасно, пускай ТС поставит 10000 и пробует. В принципе, можно и усложнить код для отлавливания повторного удара по еще колеблещемуся датчику. Но на данной стадии для ТС это избыточно и сложно. Давайте пока подождем результатов эксперимента.
     
  20. sslobodyan

    sslobodyan Гик

    Опять ошибочные размышления без вникания в суть задачи. ТС не создает стенд для каких-то виброисследований. Ему нужна барабанная установка. Длительность звучания семпла барабана в семплере или компе больше, чем длительность колебаний датчика. Поэтому посылать ноте_офф сразу после затухания датчика нельзя - остановится проигрывание ноты. Особенно это будет заметно на райде и крешах. А если вдруг датчик будет колебаться дольше, чем звучит семпл (слабо себе представляю), то надо либо менять механику (делать более жесткую подушку на тарелке), либо переписывать алгоритм под множественные удары, то есть отлавливать не только однократный переход подъем-спуск, но и все последующие подъемы-спуски с учетом гистерезиса, что немного сложнее в реализации. А пока от ТС нужно только одно - запустить скетч и проверить, что как после легкого, так и после сильного удара по датчику на выходе получаем ровно одну команду ноте_он и одну команду ноте_офф. Всего то экспериментально подобрать коефф перевода значения АЦП в громкость, уровень порога KICK_THRESHOLD и время колебаний датчика TIME_SENSOR.