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

Тема в разделе "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 в 23:14
  5. Dan

    Dan Гик

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