Электронные барабаны на Arduino кривыми руками.

Тема в разделе "Arduino & Shields", создана пользователем vinichenko.dl, 20 май 2018.

  1. vinichenko.dl

    vinichenko.dl Нерд

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

    Характеристики модуля:
    - 8 аналоговых входов для пэдов
    - цифровой вход для подключения педали хэй хета (т.е. при нажатии педали хэт закрывается при отпушенной открывается, педаль работает как кнопка)
    - цифрой вход для глушилки краша (при необходимости можно добавить еще несколько глушилок для разных тарелок)

    Необходимые компоненты:
    - ардуино нано https://ru.aliexpress.com/item/ATme...447.html?spm=a2g0s.9042311.0.0.656633edAm1yqj
    - аудио разъемы на 3.5мм - 10шт https://ru.aliexpress.com/item/10PC...432.html?spm=a2g0s.9042311.0.0.656633edAm1yqj
    - резисторы на 1 мегом - 8шт https://ru.aliexpress.com/item/100-...736.html?spm=a2g0s.9042311.0.0.656633edAm1yqj
    - резисторы на 10 килоом - 2шт
    - шилд для ардуино (хотя можно и без него я взял для удобства монтажа) https://ru.aliexpress.com/item/Free...675.html?spm=a2g0s.9042311.0.0.656633edAm1yqj
    - корпус ( я в качестве корпуса использовал распред коробу которую купил в хозяйственном магазине за 25 рублей)
    На все вместе у меня ушло порядка 500 рублей.
    Так же понадобится провод для монтажа но его покупать не обязательно думаю у каждого есть под рукой кокой ни будь не нужный провод который можно пустить в дело.

    [​IMG]
    Вот таким образом необходимо все соединить, все контакты 1 ауди разъемов входов пэдов на GND, все 3 контакты на А0, А1, А2, А3, А4, А5, А6, А7 соответственно и по резистору на 1 мегом между контактами 1 и 3.
    Загружаем скетч:
    Код (C++):
    /*

      MIDI ударная установка

    */

    int buttonState = 0;
    int rt = 0;

    int buttonState1l = 0;
    int rt1l = 0;

    #define LED 13

    #define PIEZ_CNT 8 // количество датчиков
    #define DRUM_CHANNEL 9

    #define ANOTHER_MUTE_PIN_
    #define SHOW_

    // пороговый уровень датчика
    int kick_treshold[PIEZ_CNT]={50,50,50,50,50,50,50,50};

    // время на остановку колебаний
    long kick_mute_time[PIEZ_CNT]={50000,50000,50000,50000,50000,50000,50000,50000};

    // ноты на каналах
    byte kick_note[PIEZ_CNT]={7,46,40,71,36,69,67,45};

    // канал молчит
    bool mute[PIEZ_CNT]={1,1,1,1,1,1,1,1};

    // ножка датчика
    const uint8_t kick_pin[PIEZ_CNT]={A0,A1,A2,A3,A4,A5,A6,A7};

    #ifdef ANOTHER_MUTE_PIN
      const uint8_t stop_pin[PIEZ_CNT]={A0,A1,A2,A3,A4,A5,A6,A7};
    #endif

    int kick_val[PIEZ_CNT]; // предыдущее значение датчика
    int velocity;

    uint32_t tm[PIEZ_CNT], tm_led;
    byte cnt=0, piez_idx=0;

    void noteOn(int chan, int note, int velocity) {
        Serial.write( (0x90 | chan) );
        Serial.write(note);
        Serial.write(velocity);
    }

    void noteOff(int chan, int note, int velocity) {
        Serial.write( (0x80 | chan) );
        Serial.write(note);
        Serial.write(velocity);
    }

    void channelVolume(int chan, int velocity) {
        Serial.write( (0xb0 | chan) );
        Serial.write( 0x07 );
        Serial.write(velocity);
    }

    void channelPan(int chan, int pan) {
        Serial.write( (0xb0 | chan) );
        Serial.write( 0x0a );
        Serial.write(pan);
    }

    void channelBank(int chan, int dat) {
        Serial.write( (0xB0 | chan) );
        Serial.write( 0x00 );
        Serial.write( dat );
    }

    void channelInstrum(int chan, int dat) {
        Serial.write( (0xC0 | chan) );
        Serial.write( dat );
    }

    void setup() {
      //Serial.begin(115200); // эмулятор МИДИ на компе
      Serial.begin(115200); // реальный МИДИ
      pinMode(3, INPUT);
      pinMode(4, INPUT);
      pinMode(LED, OUTPUT);
      digitalWrite(LED, LOW);
      for (byte i=0; i<PIEZ_CNT; i++) {
        digitalWrite(kick_pin[i], LOW);
        pinMode(kick_pin[i], INPUT);
    #ifdef ANOTHER_MUTE_PIN
        digitalWrite(stop_pin[i], LOW);
        pinMode(stop_pin[i], INPUT);
    #endif
      }
      channelBank(1, 0);
      channelInstrum(1, DRUM_CHANNEL);
      channelVolume(1, 70);

      // делитель 16 - частота опроса 1МГц разрешение 8 бит
      ADCSRA |= (1 << ADPS2);                     //Биту ADPS2 присваиваем единицу
      ADCSRA &= ~ ((1 << ADPS1) | (1 << ADPS0));  //Битам ADPS1 и ADPS0 присваиваем нули
    }


    void loop(){
       buttonState = digitalRead(3);

       buttonState1l = digitalRead(4);
    if (buttonState == HIGH && rt == 0)
    {

      Serial.write(185);
      Serial.write(4);
      Serial.write(127);

    rt = 10;

    }
    if (buttonState == LOW && rt == 10)
    {

      Serial.write(185);
      Serial.write(4);
      Serial.write(0);

    rt = 0;

    }

    if (buttonState1l == HIGH && rt1l == 0)
    {

      Serial.write(0x90);
      Serial.write(68);
      Serial.write(127);
    rt1l = 10;


    }
    if (buttonState1l == LOW && rt1l == 10)
    {

      Serial.write(0x90);
      Serial.write(68);
      Serial.write(0);
    rt1l = 0;

    }

        if(piez_idx>0) piez_idx--; else piez_idx=PIEZ_CNT-1; // выбор следующего датчика
        int adc = analogRead(kick_pin[piez_idx]);
     
        if (adc > kick_treshold[piez_idx]) {
          if ( tm[piez_idx] == 0 ){
            tm[piez_idx] = micros() + 2000;
            kick_val[piez_idx] = 0;
            digitalWrite(LED, HIGH);
            tm_led = millis()+10;
          }
        }

        if (tm_led > 0) {
          if (millis() > tm_led) {
            tm_led = 0;
            digitalWrite(LED, LOW);
          }
        }
         
        if ( tm[piez_idx] > 0 ) {
          if ( micros() > tm[piez_idx] ) {
            if ( mute[piez_idx] ) {
              mute[piez_idx] = false;
              velocity = map(kick_val[piez_idx], kick_treshold[piez_idx], 1023, 1, 127);
              if (velocity > 127) velocity = 127;
              noteOn(DRUM_CHANNEL, kick_note[piez_idx], velocity); // играем ноту
              tm[piez_idx] += kick_mute_time[piez_idx];
              #ifdef ANOTHER_MUTE_PIN
                pinMode(stop_pin[piez_idx], OUTPUT); // разряжаем кондер
              #else
                pinMode(kick_pin[piez_idx], OUTPUT); // разряжаем кондер
              #endif
              #ifdef SHOW
                cnt++;
                velocity = kick_val[piez_idx];
                Serial.print("IDX="); Serial.print(piez_idx);
                Serial.print(" Vel="); Serial.print(velocity);
                Serial.print(" cnt="); Serial.println(cnt);
              #endif
            }
          }
          if ( kick_val[piez_idx] < adc ) {
            kick_val[piez_idx] = adc; // ищем максимум сигнала от датчика
          }
          if ( micros() >  tm[piez_idx] ) {
            // закончили сканирование одного удара
            tm[piez_idx] = 0;
            mute[piez_idx] = true;
            // отключаем разрядку кондера
            #ifdef ANOTHER_MUTE_PIN
              pinMode(stop_pin[piez_idx], INPUT);
            #else
              pinMode(kick_pin[piez_idx], INPUT);
            #endif    
          }
        }

    }
    Для создания виртуального МИДИ порта я использую программу loopmidi, и программу hairless-midiserial для направления в него сигнала из serial port. В качестве синтезатора использую адиктив драмс.
    Если тема интересна могу рассказать как сделать пэды и тарелки, ну и выложу фотки модуля.
     
  2. sslobodyan

    sslobodyan Гик

    О, очень даже интересно. Особенно мне как автору данного скетча :)
     
  3. vinichenko.dl

    vinichenko.dl Нерд

    Привет, да если бы не твой скетч не было бы этой темы, вот думаю приладить еще синтезатор на модуле с VS1053 но ты не хочешь рассказывать как это сделать, а было бы здорово, еще думаю миди выход приделать чтоб не использовать loopmidi и hairless.
     
  4. vinichenko.dl

    vinichenko.dl Нерд

    Вот фотки
     

    Вложения:

  5. sslobodyan

    sslobodyan Гик

    Фотки это здорово, но хотелось бы почитать описание как пэды делались. Скетч, кстати, достаточно кривой. На ютубе есть видео одного португальца по самопальным барабанам - он сделал намного лучше, плюс прога по настройке.Поищи Instrumento Caseiro
     
  6. sslobodyan

    sslobodyan Гик

    По 1053 даешь поиск "vs1053+realtime midi+arduino" и читаешь. Информация не секретная :)
     
  7. vinichenko.dl

    vinichenko.dl Нерд

    Да я все его видосы смотрел, только в програмировании я полный ноль и не смогу его скетч под себя переделать, кстати а чем этот скетч кривой работает стабильно мне нравится. А по поводу vs1053 вроде бы разобрался только шилды на али продаются с нераспаянными ногами которые нужны чтоб перевести его в режим реалтайм миди вот и не решоюсь его заказать не уверен что получится подпоятся к микросхеме, у тебя же вроде получилось вот я и хотел чтоб ты опытом поделился.
     
  8. vinichenko.dl

    vinichenko.dl Нерд

    Пэды делал так дно из ДВП на нем пенопласт, обод из ДСП мембрана из пористой резины к которой приклеен диск из жести с приклеенным пьезо. Тарелка из двух вениловых платинок склеенных вместе погрел феном и вдавил середину на куске ДВП с вызезанным кругом который остался от изготовления обода получилось хоть както похоже на тарелку, глушилку сделал из двух кусочьков текстолита. Потом выложу фотки разобранного пэда. Единственно что не нравится в этой конструкции так называемая горячая точка т.е. если ударяеш по центру над пьезиком то идет макимальны велосити 127.
     
  9. sslobodyan

    sslobodyan Гик

    У 1053 есть возможность запустить МИДИ софтово без перепайки ножек. Но я не успел попробовать - коротнул и попалил чип. Уже дважды заказывал чип на перепайку и дважды китаезы не высылали.
     
  10. vinichenko.dl

    vinichenko.dl Нерд

    А как звук барабанов у 1053 нормальный или может с ним и заморачиватся не стоит?
     
  11. sslobodyan

    sslobodyan Гик

    Примерно как дешевая самограйка :) Там софтовая генерация, не звукосэмплы. Зато не нужен комп и есть выход на наушники. Концерты играть не выйдет, но для тренировки ритма - вполне.
     
  12. Малыш

    Малыш Нуб

    Здравствуйте. Я подключил только один пьезо датчик к ардуино Мега 2560 и в актив драм на любом из каналов срабатывают сразу все ноты (инструменты). Что-то надо прописать отдельно? Или я не так делаю что? Спасибо заранее.
     
  13. В скетче пропиши количество датчиков 1.
     
    Малыш нравится это.
  14. Малыш

    Малыш Нуб

    Спасибо, что помогли! Логику понял!
     
  15. vinichenko.dl

    vinichenko.dl Нерд

    Входы к земле подтяни.
     
    Малыш нравится это.
  16. Малыш

    Малыш Нуб

    Приветствую. Народ, ещё вопрос: на раму (алюминиевая труба) установил два пэда (фанера, датчик, паралон, слой резины сверху и прижимное кольцо к самой фанере) рядом прикрепил полу круглым хомутом. При ударе по одному второй заводится, от вибрации по ходу, можно как-то настройками убрать, чувствительность или ещё что? Если кто сталкивался прошу помочь. Код как в теме. Спасибо!
     
  17. int kick_treshold[PIEZ_CNT]={50,50,50,50,50,50,50,50}; чуствительность датчиков попробуй поставь 200 или 300 или 150 в общем поирай с чуствительностью .
     
    Малыш нравится это.
  18. Малыш

    Малыш Нуб

    Я попробую. Спасибо!
     
  19. Малыш

    Малыш Нуб

    Если можно, то опишите, что представляет из себя педаль и Глушилка физически со схемой подключения. Не совсем понимаю. Спасибо.
     
  20. Педаль это педаль хай-хета (открыть-закрыть) , глушилка это глушение тарелки райда. То есть это две обычные кнопки. На этоей схеме всё понятно. Удачи!
     
    Последнее редактирование: 4 дек 2018 в 23:29
    Малыш нравится это.