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

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

  1. Dan

    Dan Гик

    Попробовал я последний скетч, все равно воспроизводится почему то один датчик, хотя подключено два. Но ноту воспроизводит нужную и четко, это радует
     
    sslobodyan нравится это.
  2. sslobodyan

    sslobodyan Гик

    если внимательно посмотреть на скетч, то там надо правильно расписать массивы. сильно рекомендую прикладывать сюда свои правленные скетчи, иначе будет разговор глухого со слепым :)
    и к своим скетчам давать словесную ремарку что и куда подключал. бывают ляпы :)
     
  3. Dan

    Dan Гик

    Договорились)
     
  4. Dan

    Dan Гик

    попробовал с двумя датчиками, массивы, в скетче, соответственно, также сократил до 2 датчиков. Подключил один к А0, второй к А1. На А1 играет ноту, на А0 нет.
    Вот скетч:
    Код (C++):
    /*

      MIDI ударная установка
      sslobodyan@ya.ru 2017
    */


    #define LED 13

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

    #define ANOTHER_MUTE_PIN_
    #define SHOW_

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

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

    // ноты на каналах
    byte kick_note[PIEZ_CNT]={35,38};

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

    // ножка датчика
    const uint8_t kick_pin[PIEZ_CNT]={A0,A1};

    #ifdef ANOTHER_MUTE_PIN
      const uint8_t stop_pin[PIEZ_CNT]={A0,A1};
    #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(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(){

        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    
          }
        }

    }
    Я, кажется, нашел косяк - ноту, видимо, не ту прописал одну
    Все-таки, косяк не в ноте, все равно не хочет два датчика воспроизводить
     
    Последнее редактирование: 12 авг 2017
  5. Dan

    Dan Гик

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

    Stas48 Нерд


    Я тоже собираю установку. Справился с проблемой некорректного извлечения удара следующим образом:
    1) пэд: не принципиально у кого как он сделан, но у меня так: сделан из фонеры 10мм или пластмассы 3-4 мм, на нем резина. Далее принципиально важно: внизу под фонерой половинка СД диска приклеена к ней миллиметровым двусторонним скотчем по углам -всего в двух местах, больше не надо ( полосками примерно 1х2 см), датчик приклеен к диску снизу тонким двусторонним скотчем (толстый все испортит) и по верху датчика полоска вспененного скотча для оклейки окон примерно 3х6 см.- без нее почему-то тоже не очень хорошо работает. Пробовал лепить датчик на целый диск СД- результат не обрадовал, а вот на половинку нормально.
    2) на плюсе датчика внутри пэда (именно внутри !!! иначе не прокатит, будут наводки на другие провода!) в разрыв провода (т.е. последовательно ) резистор 510 кОм. Сигнал в итоге совсем чуток потише, но задержка при сильных ударах по пэду исчезла!!! Сам был удивлен что сигнал приходится глушить дополнительным резистором внутри пэда, как будто это реакторы, а не датчики, но это так)). Схема со стабилитроном на 3,3 В (max.) параллельно датчику тоже была опробована, но к нему опять же потребовался нагрузочный, правда уже поменьше, резистор на плюс датчика. В итоге со стабилитроном делать не стал- зачем усложнять, если результат тот же.
    3) параллельно датчику- резистор 1 МОм (как положено по инструкции подключения пьезы)
    4) Провод должен быть экранированный. Если делаете двухзонный пэд, то нужно взять провод где каждая жила экранирована, иначе гарантированы наводки от одного провода на другой и как следствие будут звучать оба датчика. То же самое если рядом будут провода от других пэдов- то и они зазвучат. Короче однозначно ЭКРАН НА КАЖДУЮ ЖИЛУ НА ВСЕХ ПРОВОДАХ от пэдов до модуля.

    PS. Скетч брал от Evan Kale- в интернете найти легко. И далее настраивал его под себя- количество датчиков, их чувствительность, пришлось также регулировать время между нотами и пиками сигнала и какой-то там буфер сигнала.
    В итоге все работает хорошо, не получилось только пока функцию CHOKE для крэшей сделать. Знаний в программировании не хватает((
    Но думаю их мы еще победим.))))
     
    sslobodyan нравится это.
  7. sslobodyan

    sslobodyan Гик

    Очень не хватает фоток или видео как сделать пэд.
    Объясните что такое CHOKE - постараюсь помочь.
     
  8. Dan

    Dan Гик

    Choke так называется функция глушения тарелок
    Я сам все никак не доделаю свою ударку, но с пэдами у меня менее замороченная конструкция
    И до осцилла никак не доберусь
     
  9. Dan

    Dan Гик

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

    Stas48 Нерд

    у меня пока так. все исправно работает. пэд фото.jpg
    Со временем пришел к тому, что лучше делать не из фонеры, а из пластика 3-5 мм. На него клеил вспененную резину 6 мм.
    Фонера передает вибрацию хуже пластика, соответственно чувствительность пэда слабее что не есть хорошо.
    Половинки лазерных дисков тоже заменил на более компактного размера пластик примерно такой же или даже чуть потоньше как у диска толщины, прямоугольной формы, размер 3 на 5 см.
     
    Последнее редактирование: 27 янв 2018
  11. Stas48

    Stas48 Нерд

    На фирмовых уже внутри пэдов стоят ограничители по току в виде сопротивлений, стабилитронов и тд.., да и в целом на них схемотехника уже под конкретную задачу заточена. А мы имеем дело с конструктором.
    В моих пэдах никакие колебания датчика не нужно останавливать. Вам надо воспользоваться проверенным рабочим кодом, а ваш, как я понял, изначально не корректно работает. Я особо не вникал в ваш код, но вопрос : в вашем коде есть функция отсечки лишних колебаний? времени срабатывания между нотами и пиками сигнала?
    Я ничего доказывать вам не хочу, можете и дальше возиться с проблемой колебаний, и, как я вижу, вы уже почти год не можете ее одолеть, а у меня с этим кодом за три недели вопрос закрылся, с учетом того что две недели пробовал разные конструкции пэдов и неделю подстраивал под себя код. Так что мой вам совет- перепрошейте на код Evan Kale, а там уже посмотрите что получится.
     

    Вложения:

  12. Stas48

    Stas48 Нерд

    Нужно подключить две кнопки к цифровым входам, чтобы при их нажатии уходил миди сигнал к кодом 78 и 80 соответственно. с любым , пусть например 50 значением велосити. буду признателен, если поможете. я код сам дорабатывал, но работают кнопки некорректно, надо по нескольку раз нажимать, поэтому я даже его не сохранял, чтобы выложить. Прикладываю скетч без подключенных кнопок.
     

    Вложения:

  13. Dan

    Dan Гик

    Я пробовал этот скетч, но у меня нужно сильно стучать по пэду, чтобы звук был. Дробь не постучишь особо
     
  14. Stas48

    Stas48 Нерд

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

    sslobodyan Гик

    Код хороший, смущает только вот эта конструкция
    Код (C++):
    void noteFire(unsigned short note, unsigned short velocity)
    {
      if(velocity > MAX_MIDI_VELOCITY)
        velocity = MAX_MIDI_VELOCITY;
     
      midiNoteOn(note, velocity);
      midiNoteOff(note, velocity);
    }
    По идее, нота включается и тут же глушится? Чем играете МИДИ? Мне кажется, что midiNoteOff(note, velocity) здесь лишний.
     
  16. Stas48

    Stas48 Нерд

    в этом коде есть переменная THRESHHOLD- ставишь ее поменьше, методом подбора, но мне меньше = 5, и будет счастье. и еще в этом коде как уже говорил я скорректировал параметры буфера и тд.
    Во втором коде, который на 9 пэдов, эти параметры не менял. попробуй именно на два пэда, а там внутри увидишь как исправить на большее кол-во датчиков.
     
  17. Stas48

    Stas48 Нерд

    так и должно быть. удар прошел- больше сигналу делать нечего!
     
  18. Stas48

    Stas48 Нерд

    void noteFire(unsignedshort note, unsignedshort velocity)
    {
    if(velocity > MAX_MIDI_VELOCITY)
    velocity = MAX_MIDI_VELOCITY;

    а это чтобы ограничить значение удара, поскольку миди только до 127 понимает
     
  19. Stas48

    Stas48 Нерд

    по поводу кода не сомневайся, он 100% рабочий. им уже много кто пользовался
     
  20. Dan

    Dan Гик

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