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

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

  1. Dan

    Dan Гик

    Всем привет)
    После последнего моего посещения прошло длительное время, сейчас все мастерю и экспериментирую с пэдом, не так и просто его оказывается сделать, но дело не в этом.

    Так как я использовал предпоследний скетч товарища sslobodyan (которому отдельное спасибо за огроменную помощь :)), я решил сделать бас-бочку и хай-хэт. Но произошла проблема: пьезодатчик подключен только к выводу A1, а звучит и бас-бочка и хэт одновременно. Скетч, который я доделал, естественно, не оптимизированный, но как смог так и поправил под себя, так что если бить, то не по лицу)

    Вот мой код (с контроллером хай-хэта):
    Код (C++):
    #define LED 13

    #include <MIDI.h>

    MIDI_CREATE_DEFAULT_INSTANCE();

    uint16_t kick_sample_time=2; // время звучания семпла
    uint16_t kick_treshold=1; // пороговый уровень датчика
    uint16_t kick_mute_time=20; // время ожидания успокоения датчика в миллисекундах

    uint32_t kick_note_off=0; // счетчик времени звучания семпла
    uint32_t kick_mute=0; // счетчик времени успокоения датчика в микросекундах
    uint16_t kick_val=0; // предыдущее значение датчика
    uint8_t kick_note_number=36; // номер ноты в GeneralMIDI
    const uint8_t kick_pin=A0;

    uint16_t hh_sample_time=2; // время звучания семпла
    uint16_t hh_treshold=1; // пороговый уровень датчика
    uint16_t hh_mute_time=20; // время ожидания успокоения датчика в миллисекундах

    uint32_t hh_note_off=0; // счетчик времени звучания семпла
    uint32_t hh_mute=0; // счетчик времени успокоения датчика в микросекундах
    uint16_t hh_val=0; // предыдущее значение датчика
    uint8_t hh_note_number=49; // номер ноты в GeneralMIDI
    const uint8_t hh_pin=A1;

    int foto_val = 0;
    int foto_pin = A15;

    void test_midi();

    int tmp;
    int tmp_hh;
    void setup() {
      MIDI.begin();
    //  Serial.begin(31250);
      Serial.begin(115200);
      pinMode(kick_pin, INPUT);
      pinMode(hh_pin, INPUT);
      pinMode(LED, OUTPUT);
      pinMode(foto_pin, OUTPUT);
      digitalWrite(LED, LOW);
      // делитель 16 - частота опроса 1МГц разрешение 8 бит
      ADCSRA |= (1 << ADPS2);                     //Биту ADPS2 присваиваем единицу
      ADCSRA &= ~ ((1 << ADPS1) | (1 << ADPS0));  //Битам ADPS1 и ADPS0 присваиваем нули

      test_midi();
    }

    void noteOn(int cmd, int pitch, int velocity) {
        Serial.write( (0x8F+cmd) );
        Serial.write(pitch);
        Serial.write(velocity);
    }

    void test_midi() {
      for (int note = 0x1E; note < 0x2A; note ++) {
        noteOn(10, note, 0x45);
        delay(100);
        noteOn(10, note, 0x00);
        delay(100);
      }
    }

    void loop(){
    // ------------------------------KICK--------------------------
     
      if (kick_note_off > 0) { // здесь проверяем время звучания семпла и выключаем ноту
        if (millis() > kick_note_off) { // нота уже должна отзвучать
          kick_note_off=0;
          //noteOff
          noteOn(10, kick_note_number, 0);
        }
      }

      if (kick_mute > 0) { // здесь проверяем время затухания датчика
        if (millis() > kick_mute) { // уже должны затухнуть
          pinMode(kick_pin, INPUT);
          kick_mute = 0;
          kick_val=0;
          digitalWrite(LED, LOW);
        }
      }
      else {
        tmp = analogRead(kick_pin);
        if (tmp > kick_treshold ) { // уровень превышает порог+гистерезис
          if (tmp <= kick_val ) { // датчик пошел на спад - пик уже получен
            uint8_t velocity = map(kick_val, kick_treshold, 100, 1, 127);
            if (velocity > 127) velocity = 127; // оставил на всякий случай
            kick_note_off = millis() + kick_sample_time; // ставим таймер на время звучания семпла
            kick_mute = millis() + kick_mute_time; // время ожидания успокоения сенсора
            noteOn(10, kick_note_number, velocity); // играем ноту
            digitalWrite(LED, HIGH);
            pinMode(kick_pin, OUTPUT);
            digitalWrite(kick_pin, LOW); // придавливаем датчик чтобы быстрее успокоился
          }
          else { // сигнал сенсора растет
            kick_val = tmp; // запоминаем текущее значение для сравнения со следующим
          }
        }
      }
     
     
     
     
     
    // ------------------------------HIHAT--------------------------
     
      if (hh_note_off > 0) { // здесь проверяем время звучания семпла и выключаем ноту
        if (millis() > hh_note_off) { // нота уже должна отзвучать
          hh_note_off=0;
          //noteOff
          noteOn(10, hh_note_number, 0);
        }
      }

      if (hh_mute > 0) { // здесь проверяем время затухания датчика
        if (millis() > hh_mute) { // уже должны затухнуть
          pinMode(hh_pin, INPUT);
          hh_mute = 0;
          hh_val=0;
          digitalWrite(LED, LOW);
        }
      }
      else {
        kick_val = 0;
        tmp_hh = analogRead(hh_pin);
        if (tmp_hh > hh_treshold ) { // уровень превышает порог+гистерезис
          if (tmp_hh <= hh_val ) { // датчик пошел на спад - пик уже получен
            uint8_t velocity = map(hh_val, hh_treshold, 100, 1, 127);
            if (velocity > 127) velocity = 127; // оставил на всякий случай
            hh_note_off = millis() + hh_sample_time; // ставим таймер на время звучания семпла
            hh_mute = millis() + hh_mute_time; // время ожидания успокоения сенсора
              foto_val = analogRead(foto_pin);
              if(foto_val > 0 && foto_val < 10)
              {
                hh_note_number = 51;
              }
              if(foto_val > 10 && foto_val < 30)
              {
                hh_note_number = 52;
              }
              if(foto_val > 30 && foto_val < 50)
              {
                hh_note_number = 54;
              }
              if(foto_val > 50 && foto_val < 70)
              {
                hh_note_number = 55;
              }
              if(foto_val > 70 && foto_val < 90)
              {
                hh_note_number = 56;
              }
              if(foto_val > 90 && foto_val < 110)
              {
                hh_note_number = 57;
              }
              noteOn(10, hh_note_number, velocity); // играем ноту
            digitalWrite(LED, HIGH);
            pinMode(hh_pin, OUTPUT);
            digitalWrite(hh_pin, LOW); // придавливаем датчик чтобы быстрее успокоился
          }
          else { // сигнал сенсора растет
            hh_val = tmp_hh; // запоминаем текущее значение для сравнения со следующим
          }
        }
      }
    }
     
    pk_vital и sslobodyan нравится это.
  2. sslobodyan

    sslobodyan Гик

    Я бы вам все таки рекомендовал посмотреть последние мои посты :) Там уже целая барабанная установка.
    По вашему коду я не совсем понял что это там за фотовал и каким образом вы выбираете играющую ноту. Зато сразу бросилась в глаза ошибка с определением диапазонов. Вы почему-то выбрасываете из определения границы диапазонов. Например, первый диапазон до 30, а следующий от 30. А куда девать 30?
    И попробуйте сконтактировать с pk_vital, у него все отлично получается :)
     
    Последнее редактирование: 13 фев 2017
    pk_vital нравится это.
  3. mcureenab

    mcureenab Гуру

    Код (C++):
         if(foto_val > 0 && foto_val < 10)
    foto_val зачем 0 не учитывать?

    Код (C++):
           if(foto_val > 0 && foto_val < 10)
              {
                hh_note_number = 51;
              }
              if(foto_val > 10 && foto_val < 30)
    Значение 10 выпало. Нужно проще

    Код (C++):

           if(foto_val < 10)
              {
                hh_note_number = 51;
              }
            else if(foto_val < 30)
     
    pk_vital нравится это.
  4. zsm

    zsm Гик

    интересный ресурс по теме http://www.dimitridiakopoulos.com/hiduino.html
    там есть прошивка для 16u2. что в UNO стоит,
    которая превращает последнюю в USB MIDI устройство ,
    цепляется виндой на ура даже дров не надо.
    пробовал пару лет назад ,работает четко.
     
  5. M0ln1a

    M0ln1a Гик

    Приветствую! Просмотрел я код, но так до конца и не понимаю, зависит ли громкость удара от силы удара палочкой по "пластику" и тарелкам?
    И лично я бы попробовал сделать данную установку с MusicShield'ом... Может я ошибаюсь, и с ним не выйдет играть параллельно на нескольких инструментах, но по крайней мере проверять длительность звучания с ним не надо)
    Так же лучше поставить к каждому пластику датчик давления, с помощью которого и регулировать громкость звучания сэмпла и его длительность (на бочке звук всегда одной длины, поэтому там можно обойтись лишь громкостью)
    Может это и станет некой роскошью, но было бы замечательно вставить в вашу установку стрейнер ( регулировку натяжения пружины под нижним пластиком малого барабана). Сделать это очень просто: просто подключить кнопку и сделать 2 режима (натянутая пружина и растянутая). С учетом выбранного режима включать разные звучания малого барабана!
    А так идея крутая) Может сам позже модифицирую барабан от ps3 и сделаю из него семплер к акустической установке :)
     
  6. sslobodyan

    sslobodyan Гик

    Простите, но вероятно вы несколько не в теме :) Здесь давно уже реализована громкость от силы удара.
     
  7. M0ln1a

    M0ln1a Гик

    Чего я и боялся :)
    А стрейнер тут стоит, или я опять опоздал?
    Вы уж извините, я впервые увидел эту тему, и особо прочесть ее не успел, завтра это исправлю) Все во имя музыки :)
     
  8. sslobodyan

    sslobodyan Гик

    Я не барабанщик :) Так, просто мимо проходил :) Слово "стрейнер" для меня - загадка. Но я уже выше показывал как организовать двухзонку, те. два датчика на пэде и в зависимости от того, куда вы ударите, прозвучит тот или другой инструмент. Наверное это то, что вы называете ослабленой и натянутой пружиной :)
     
  9. M0ln1a

    M0ln1a Гик

    Я не знаю какие там 2 инструмента :)
    При натянутой пружине барабан шуршит, и при раслабленой звучит как африканский))
    В любом случае, есть техника ударов не в центр пластика (чем ближе к ободу бьете, тем выше звук), и на одном барабане можно сыграть целую мелодию! Так давайте усеем весь барабан датчиками? :)
     
  10. sslobodyan

    sslobodyan Гик

    Ну в принципе, так и делают. А еще добавляют "модификаторы" - различные педальки. Перед воспроизведением ноты код проверяет модификатор и посылает разные ноты. Например, открытый и закрытый хэт.
     
  11. M0ln1a

    M0ln1a Гик

    Roland на своих установках делает 3 зоны на пластиках) Ну а открыт или закрыт хет - это уже классика, основа основ! :)
    Понимаю, что скажу это не в тему, но акустический барабан крут не только тем, что его можно вечно настраивать и получать крутые звуки! Можно играть и на его стойках, и на ободах, и на корпусе барабанов... Портятся не только пластики))
    А вот что, если сделать первый в мире электронный барабан с играющими стойками? Такого еще не создавалось)
     
  12. sslobodyan

    sslobodyan Гик

    Так в чем проблема? Лепите датчик на стойку и все. Привязывайте к нему хоть бигбэн. Аналогично датчик на корпус барабана со своим звуком. Я пару постов выше под спойлером это описывал.
     
  13. M0ln1a

    M0ln1a Гик

    Проблема в том, что вряд-ли вы во время игры попадёте по этому датчику... Это же прицеливаться еще надо! Есть вариант поставить датчик вибрации, но тогда он будет срабатывать всегда
     
  14. sslobodyan

    sslobodyan Гик

    Немного сложнее. Датчиков два. При ударе уровень сигнала на них разный - чем ближе к датчику, тем сильнее. Так что будет сильнее слышен ближний датчик. Конечно, вы можете научить свою установку принудительно глушить "конкурирующую" ноту. Но это уже "крутой уровень".
    Мы и так используем пьезодатчики вибрации.
     
    pk_vital нравится это.
  15. Dan

    Dan Гик

    foto_val - это значение фоторезистора, в зависимости от того, сколько света на него падает последовательно воспроизводятся ноты открытия/закрытия хэта. А в последнем скетче я не понял как сделать контроллер хай-хэта, но нужно попробовать, можнт там все куда проще окажется, как знать
     
  16. pk_vital

    pk_vital Нерд

    С Днем Рождненья Наш Дорогой
    тов SSLOBODYAN!!! Счастья Здоровья, Благополучия и Удачи во всём!!!!

    Dan писал:
    Но произошла проблема: пьезодатчик подключен только к выводу A1, а звучит и бас-бочка и хэт одновременно....
    Это из-за того что у вас не заземлены актиивированные аналоговые пины.. выход: либо припоять все пьезы со схемой, либо в скетче отключить все неиспользуемые датчики.
    А так идея с использованием оптики(переменного резистора) на педали хэта очень хорошая.
     
  17. Dan

    Dan Гик

    Присоединяюсь к поздравлениям! С Днем рождения и самых ярких творческих и не только успехов))


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

    pk_vital Нерд

    Там просто кнопка, 2режима... открыт, закрыт
     
  19. Dan

    Dan Гик

    А мне как раз нужно, чтобы он постепенно открывался/закрывался) и кстати, какого номинала лучше взять резистор для заземления других выводов?чем больше, тем лучше?
     
  20. mcureenab

    mcureenab Гуру

    10kOmh.
    Если пин случайно будет настроен на OUTPUT HIGH, ток будет не смертельный.
    Или переключите пины в режим OUTPUT LOW.
     
    pk_vital нравится это.