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

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

  1. sslobodyan

    sslobodyan Гик

    Всенепременно прошу объяснить господам каким образом Мега может опросить 32 канала? Может она и 50 каналов потянет? Конечно же, если вы хотите минимизации и вам достаточно однозоновости, да еще и набор барабанов минимальный, то нет проблем - даже 328 имеет 8 входов, на попробовать хватит. Но если есть желание сделать полноценную многозоновку, то придется юзать мультиплексоры, такова селяви :)
     
  2. Dan

    Dan Гик

    Желание сделать установку из следующих комплектуюших:
    1. Бас-бочка
    2. Малый барабан
    3. Альт-том
    4. Тенор-том
    5. Напольный том
    6. Крэш
    7. Райд
    8. Хай-хет

    С этим мега уже не справится?)
     
  3. sslobodyan

    sslobodyan Гик

    Почему нет, справится. У нее вроде 16 входов АЦП? Даже двухзонка получится. Но дальше - предел. Не расширяемо.
     
  4. mcureenab

    mcureenab Гуру

    На UNO 8 штук аналоговых входов мультиплексора АЦП. Может только притормаживать будет.
    Если много датчиков потребуется, проще будет несколько МК поставить и собрать в MIDI поток обработанных данных.
     
  5. Dan

    Dan Гик

    Двухзонка местами получится. Но мне вот такую простенькую стандартную и хочется сделать
     
  6. Dan

    Dan Гик

    Я использую Mega
     
  7. mcureenab

    mcureenab Гуру

    Тем более. Входов еще больше.
     
  8. Dan

    Dan Гик

    Да, я просто уточнил)
     
  9. mcureenab

    mcureenab Гуру

    Посмотрел вариант. http://www.spikenzielabs.com/SpikenzieLabs/DrumKitKit.html
    Судя по разводке платки, тут 1МОм резистор и диод включены параллельно датчику. Диод шунтирует отрицательную полуволну. Положительная полуволна накачивает S/H конденсатор.
    И скетч есть. Но в нем порог срабатывания задран и в расчет принимается сразу первый замер.
    Время отсчитывается просто количеством итераций цикла. Интересное решение.
    Ну и видно как работать с множеством датчиков.
     
  10. Dan

    Dan Гик

    это я тоже находил, но я тогда не задумывался о том, что по сути можно обойтись и без физического MIDI-разъема. Вообще в принципе, плату такую и самому можно сделать, для начала попробовать на макетке, только в скетч прописать подключение к MIDI-библиотеке. Попробовать охота, конечно, интересно какой будет результат.
    Это тогда че получается? Для полноценной работы нужны всего резистор с диодом на датчик и скетч?
     
    Последнее редактирование: 16 янв 2017
  11. mcureenab

    mcureenab Гуру

  12. Dan

    Dan Гик

  13. mcureenab

    mcureenab Гуру

    Припаять все можно. Вопрос, какой флюс использовать
     
  14. sslobodyan

    sslobodyan Гик

    Не знаю какие там у вас юсб-ком преобразователи стоят, но у меня на ср2102 дают офигенную задержку. Чуть не полсекунды. Короче, играть у меня не получается. Срочно пришлось приколхозивать аппаратный миди-проигрыватель. О, там уже можно бить такты. Без пик-детектора конечно же громкость шалит, но уже прикольно.
     
  15. Dan

    Dan Гик

    Вот вся проблема то в этом и заключается, что громкость рандомная и время срабатывания разное
    Можно три раза быстро стукнуть, а звук может быть всего лишь
     
  16. mcureenab

    mcureenab Гуру

    Чипы и драйвера FTDI латентность держат под контролем. В Arduino Nano такой чип служит мостом между МК и USB.
     
  17. mcureenab

    mcureenab Гуру

    Про латентность тут написано http://projectgus.com/2011/10/notes-on-ftdi-latency-with-arduino/
    Пол сек это конечно перебор.
     
  18. sslobodyan

    sslobodyan Гик

    Нет, громкость чуть разная, все равно громко и тихо явственно различается. Но на счет быстро стукнул и пропустило - такого практически нету.
    Даю свой рабочий код.
    Код (C++):

    #define LED 13


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

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

    void test_midi();

    int tmp;
    void setup() {
      Serial.begin(31250);
      //Serial.begin(115200);
      pinMode(kick_pin, INPUT);
      pinMode(LED, 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(){
     
      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, 1023, 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; // запоминаем текущее значение для сравнения со следующим
          }
        }
      }
    }
     
  19. Dan

    Dan Гик

    это уже для меня сложно, потому что я кроме ардуино ниче не программил, да и в ардуино-то новичок)
     
  20. sslobodyan

    sslobodyan Гик

    Прекратить панику на корабле! Все с чего-то начинали. Я специально подробно комментирую код для вас. Сложного там нет ничего, коллеги поддержат. Смело берите и пробуйте.
    Для начала вот вам по-проще.
    Код (C++):

    #define LED 13

    uint16_t kick_treshold=180; // пороговый уровень датчика
    uint16_t kick_val=0; // предыдущее значение датчика
    const uint8_t kick_pin=A0;

    int tmp;
    void setup() {
      Serial.begin(115200);
      Serial.println("MIDI Drumer TEST");
      pinMode(kick_pin, OUTPUT);
      digitalWrite(kick_pin, LOW);
      pinMode(LED, OUTPUT);
      digitalWrite(LED, LOW);
      pinMode(kick_pin, INPUT);
    }


    uint32_t tm=0, t_null=0;
    byte cnt=0;

    void loop(){
        kick_val = analogRead(kick_pin);
        if (kick_val > kick_treshold) {
          if (tm==0) tm=micros();
          t_null = 0;
          digitalWrite(LED, HIGH);
          Serial.print(kick_val); Serial.print(" "); Serial.println( (micros()-tm) );
        }
        else {
          if (t_null==0) {
            t_null=micros();
          }
          if (t_null>0) {
            if ( (micros()-t_null) > 80000 ) {
              if (tm>0) {
                cnt+=1;
                pinMode(kick_pin, OUTPUT); delay(2);
                Serial.print(cnt);Serial.println(" ========");
                pinMode(kick_pin, INPUT);
              }
              tm=0;
            }
          }
         
          digitalWrite(LED, LOW);
        }

    }
    Меняйте трешолд пока не перестанут бежать фантомные удары. У меня это 160, у вас другое значение. В левой колонке будут захваченные значения АЦП.