Arduino midi drum

Тема в разделе "Глядите, что я сделал", создана пользователем varvik85, 27 мар 2013.

  1. varvik85

    varvik85 Нерд

    Здравствуйте уважаемые знатоки!Существует проект http://www.spikenzielabs.com/SpikenzieLabs/DrumKitKit.html который великолепно работает,единственное он занимает все шесть аналоговых входов ардуино,хотелось бы расширить возможности использовав мультиплексор http://arduino.net.ua/Arduino_articles/Kak rasshirit kolichestvo analogovyh vhodov i vyhodov na vashem Arduino/

    но как это сделать?
     
  2. varvik85

    varvik85 Нерд

    КАК ЭТО :


    Код (Text):
    //  *****************************************************************************************************************
    //  *                                                                                                             *
    //  *                                       SpikenzieLabs.com                                                   *
    //  *                                                                                                             *
    //  *                                         Drum Kit - Kit                                                      *
    //  *                                                                                                             *
    //  *                                                                                                             *
    //  *****************************************************************************************************************
    //
    //  BY: MARK DEMERS Copywrite 20009
    //  April. 2009
    //  VERSION: 1.b
    //
    //  DESCRIPTION:
    //  Arduino analog input used to sense piezo drum hits then sent serialy to processing.
    //
    //  Required - Hardware:
    //  1. Drum kit - kit (From SpikenzieLabs.com)
    //  2. Arduino
    //
    //  Required - Software:
    //  1. Serial MIDI converter
    //  2. Garage Band, Ableton Live etc ...
    //
    // LEGAL:
    // This code is provided as is. No guaranties or warranties are given in any form. It is your responsibilty to
    // determine this codes suitability for your application.
     
     
     
     
    //*******************************************************************************************************************
    // User settable variables         
    //*******************************************************************************************************************
     
    unsigned char PadNote[6] = {52,16,66,63,40,65};     // MIDI notes from 0 to 127 (Mid C = 60)
     
    int PadCutOff[6] = {600,600,600,600,600,600};         // Minimum Analog value to cause a drum hit
     
    int MaxPlayTime[6] = {90,90,90,90,90,90};             // Cycles before a 2nd hit is allowed
     
    #define  midichannel    0;                            // MIDI channel from 0 to 15 (+1 in "real world")
     
    boolean VelocityFlag  = true;                         // Velocity ON (true) or OFF (false)
     
     
     
     
     
    //*******************************************************************************************************************
    // Internal Use Variables          
    //*******************************************************************************************************************
     
    boolean activePad[6] = {0,0,0,0,0,0};                 // Array of flags of pad currently playing
    int PinPlayTime[6] = {0,0,0,0,0,0};                 // Counter since pad started to play
     
    unsigned char status;
     
    int pin = 0;  
    int hitavg = 0;
     
    //*******************************************************************************************************************
    // Setup           
    //*******************************************************************************************************************
     
    void setup()
    {
      Serial.begin(57600);                                // connect to the serial port 115200
    }
     
    //*******************************************************************************************************************
    // Main Program        
    //*******************************************************************************************************************
     
    void loop()
    {
      for(int pin=0; pin < 6; pin++)
      {
        hitavg = analogRead(pin);                             // read the input pin
     
        if((hitavg > PadCutOff[pin]))
        {
          if((activePad[pin] == false))
          {
            if(VelocityFlag == true)
            {
    //        hitavg = 127 / ((1023 - PadCutOff[pin]) / (hitavg - PadCutOff[pin])); // With full range (Too sensitive ?)
              hitavg = (hitavg / 8) -1 ;                                                // Upper range
            }
            else
            {
              hitavg = 127;
            }
     
            MIDI_TX(144,PadNote[pin],hitavg);
            PinPlayTime[pin] = 0;
            activePad[pin] = true;
          }
          else
          {
            PinPlayTime[pin] = PinPlayTime[pin] + 1;
          }
        }
        else if((activePad[pin] == true))
        {
          PinPlayTime[pin] = PinPlayTime[pin] + 1;
         
          if(PinPlayTime[pin] > MaxPlayTime[pin])
          {
            activePad[pin] = false;
            MIDI_TX(128,PadNote[pin],127);
          }
        }
      }
    }
     
     
     
     
    //*******************************************************************************************************************
    // Transmit MIDI Message           
    //*******************************************************************************************************************
    void MIDI_TX(unsigned char MESSAGE, unsigned char PITCH, unsigned char VELOCITY)
    {
      status = MESSAGE + midichannel;
      Serial.print(status);
      Serial.print(PITCH);
      Serial.print(VELOCITY);
    }
     
    ОБЪЕДИНИТЬ С ЭТИМ :
    int led = 13 ; // Настраиваем на 13 ноге светодиод
    int r0 = 0 ; // значение выбрать вывод на 4051 (S0)
    int r1 = 0 ; // значение выбрать вывод на 4051 (S1)
    int r2 = 0 ; // значение выбрать вывод на 4051 (S2)
    int row = 0 ; // storeing the bin code
    int count = 0 ; // щётчик
    int bin [ ] = { 000, 1, 10, 11, 100, 101, 110, 111 } ; // Массив двоичных числ определяющих номер выбранного входа/выхода микросхемы 4051, с 1 по 8.
    void setup () { // ИНИЦИАЛИЗАЦИЯ
    pinMode (2, OUTPUT) ; // s0 выход
    pinMode (3, OUTPUT) ; // s1 выход
    pinMode (4, OUTPUT) ; // s2 выход
    digitalWrite (led, HIGH) ; //зажечь светодиод
    beginSerial (9600) ; // скорость обмена по UART
    }

    void loop () {
    for (count = 0 ; count ≤ 7 ; count ++) { // цикл перебора элементов массива с 1 по 8
    row = bin [ count ] ;
    r0 = row & 0x01 ;
    r1 = (row >> 1) & 0x01 ; //
    r2 = (row >> 2) & 0x01 ; //
    digitalWrite (2, r0) ;
    digitalWrite (3, r1) ;
    digitalWrite (4, r2) ;
    Serial.println (bin[count]);
    delay (1000) ;
    }
    }

    ????
    Дабы расширить количество аналоговых входов ардуино и задействовать их ???
     
  3. varvik85

    varvik85 Нерд

    На сколько я понял вторая программа что для работы с мультиплексором просто переключает входы с 1 по 8-ой ,а как считывать данные то с этих входов???
     
  4. varvik85

    varvik85 Нерд

  5. Megakoteyka

    Megakoteyka Оракул Модератор

    Нужно выход мультиплексора завести на аналоговый вход. Затем переключать входы мультиплексора и считывать с аналогового входа значения разных каналов. 1 аналоговый вход тогда даст 8 каналов, 6 входов - 48, но потребуют ставить 6 мультиплексоров. Управляющие сигналы мультиплексоров можно объединить и переключать адреса синхронно. Тогда на каждое переключение мультиплексоров будет считывание с 6 аналоговых входов.
     
    nailxx нравится это.
  6. varvik85

    varvik85 Нерд

    Это я понимаю что нужно выход завести на аналоговый вход,но как сделать это программно?
    Код (Text):
    int r0 = 0;   //value of select pin at the 4051 (s0)
    int r1 = 0;   //value of select pin at the 4051 (s1)
    int r2 = 0;   //value of select pin at the 4051 (s2)
    int count = 0;  //which y pin we are selecting
    void setup(){
    pinMode(2, OUTPUT); // s0
    pinMode(3, OUTPUT); // s1
    pinMode(4, OUTPUT); // s2
    }
    void loop () {
    for (count=0; count<=7; count++) {
    r0 = bitRead(count,0);  // use this with arduino 0013 (and newer versions)  
    r1 = bitRead(count,1);  // use this with arduino 0013 (and newer versions)  
    r2 = bitRead(count,2);  // use this with arduino 0013 (and newer versions)  
    digitalWrite(2, r0);
    digitalWrite(3, r1);
    digitalWrite(4, r2);
     
    //Either read or write the multiplexed pin here
     
    }
     
     
    }

    вот пожалуйста пример,теперь мне нужно сделать считывание с аналогово входа,но как?и как отслеживать входы мультиплексора и присваивать им значения?например если на аналоговом входе y1 появилась лог1 то
    Код (Text):
    for(int pin=0;)
      {
        hitavg = analogRead(pin);                             // read the input pin
     
        if((hitavg > PadCutOff[pin]))
        {
          if((activePad[pin] == false))
          {
            if(VelocityFlag == true)
            {
    //        hitavg = 127 / ((1023 - PadCutOff[pin]) / (hitavg - PadCutOff[pin])); // With full range (Too sensitive ?)
              hitavg = (hitavg / 8) -1 ;                                                // Upper range
            }
            else
            {
              hitavg = 127;
            }
     
            MIDI_TX(144,PadNote[pin],hitavg);
            PinPlayTime[pin] = 0;
            activePad[pin] = true;
          }
          else
          {
            PinPlayTime[pin] = PinPlayTime[pin] + 1;
          }
        }
        else if((activePad[pin] == true))
        {
          PinPlayTime[pin] = PinPlayTime[pin] + 1;
       
          if(PinPlayTime[pin] > MaxPlayTime[pin])
          {
            activePad[pin] = false;
            MIDI_TX(128,PadNote[pin],127);
          }
        }
      }
    }
     
  7. hibiki

    hibiki Гик

    меня все не покидает желание задать вопрос - а что будет, если я ударю по обоим падам одновременно? а несколько раз в довольно быстром темпе? а если по одному из падов буду водить пальцем, имитируя игру щеткой?
    я хочу не по одному барабану "пальчиком" забивать, а всю дорожку играть сразу.

    мне кажется, нужно более специализированное решение....
     
  8. varvik85

    varvik85 Нерд

    будет воспроизводится одновременно,скорость переключения мультиплексора очень велика,так что должно работать
     
  9. varvik85

    varvik85 Нерд

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



    Код (Text):
    unsigned char PadNote[6] = {52,16,66,63,40,65};     // MIDI notes from 0 to 127 (Mid C = 60)
    int PadCutOff[6] = {600,600,600,600,600,600};         // Minimum Analog value to cause a drum hit
    int MaxPlayTime[6] = {90,90,90,90,90,90};             // Cycles before a 2nd hit is allowed
    #define  midichannel    0;                            // MIDI channel from 0 to 15 (+1 in "real world")
    boolean VelocityFlag  = true;                         // Velocity ON (true) or OFF (false)
    boolean activePad[6] = {0,0,0,0,0,0};                 // Array of flags of pad currently playing
    int PinPlayTime[6] = {0,0,0,0,0,0};                 // Counter since pad started to play
    unsigned char status;
    int pin = 0;
    int hitavg = 0;
    int r0 = 0;   //value of select pin at the 4051 (s0)
    int r1 = 0;   //value of select pin at the 4051 (s1)
    int r2 = 0;   //value of select pin at the 4051 (s2)
    int count = 0;  //which y pin we are selecting
    void setup()
     
    {
    Serial.begin(57600);
    pinMode(2, OUTPUT); // s0
    pinMode(3, OUTPUT); // s1
    pinMode(4, OUTPUT); // s2
    }
    void loop () {
    for (count=0; count<=7; count++) {
    r0 = bitRead(count,0);  // use this with arduino 0013 (and newer versions)  
    r1 = bitRead(count,1);  // use this with arduino 0013 (and newer versions)  
    r2 = bitRead(count,2);  // use this with arduino 0013 (and newer versions)  
    digitalWrite(2, r0);
    digitalWrite(3, r1);
    digitalWrite(4, r2);
    for(int pin=0; pin < 6; pin++)
      {
        hitavg = analogRead(pin);                             // read the input pin
     
        if((hitavg > PadCutOff[pin]))
        {
          if((activePad[pin] == false))
          {
            if(VelocityFlag == true)
            {
    //        hitavg = 127 / ((1023 - PadCutOff[pin]) / (hitavg - PadCutOff[pin])); // With full range (Too sensitive ?)
              hitavg = (hitavg / 8) -1 ;                                                // Upper range
            }
            else
            {
              hitavg = 127;
            }
     
            MIDI_TX(144,PadNote[pin],hitavg);
            PinPlayTime[pin] = 0;
            activePad[pin] = true;
          }
          else
          {
            PinPlayTime[pin] = PinPlayTime[pin] + 1;
          }
        }
        else if((activePad[pin] == true))
        {
          PinPlayTime[pin] = PinPlayTime[pin] + 1;
       
          if(PinPlayTime[pin] > MaxPlayTime[pin])
          {
            activePad[pin] = false;
            MIDI_TX(128,PadNote[pin],127);
          }
        }
      }
    }
     
     
     
     
    //*******************************************************************************************************************
    // Transmit MIDI Message         
    //*******************************************************************************************************************
    void MIDI_TX(unsigned char MESSAGE, unsigned char PITCH, unsigned char VELOCITY)
    {
      status = MESSAGE + midichannel;
      Serial.print(status);
      Serial.print(PITCH);
      Serial.print(VELOCITY);
    }
    //Either read or write the multiplexed pin here
     
    }
     
     
    }
     
  10. hibiki

    hibiki Гик

    меня, собственно, интересует именно постоянный "шум" с одного из сенсоров. если получится сделать девайс, который будет плодить большое количество "тихих" нот (velocity имеется ввиду) - будет круто
     
  11. varvik85

    varvik85 Нерд

    какой шум?нет шума обсолютно,или я не правильно Вас понимаю,ктонибуть может помочь объединить прогу мультиплексора совместно с drum kit???
     
  12. varvik85

    varvik85 Нерд

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

    varvik85 Нерд

    Собственно попробовал объединить программу обработки мультиплексора уважаемого Megakoteyka
    с драм кит,не могу объединить массивы нот и массив чисел с мультиплексора,подскажите как доделать уже эту программу то?
    Код (Text):
    #define S0 2    // нога адреса мультиплексора
    #define S1 3    // вторая
    #define S2 4    // третья
    int buffer[8];  // массив на 8 элементов для хранения данных с 8 каналов мультиплексора
    unsigned char PadNote[8] = {52,16,66,63,40,65,21,34};           // Миди ноты с 0 до 127 (Mid C = 60)
    int PadCutOff[8] = {600,600,600,600,600,600,600,600};           // Чувствительность аналогового входа
    int MaxPlayTime[8] = {90,90,90,90,90,90,90,90};             // Длительность ноты
    #define  midichannel    0;                                  // Миди канал - 0 до 15
    boolean activePad[8] = {0,0,0,0,0,0,0,0};                   // Array of flags of pad currently playing
    int PinPlayTime[8] = {0,0,0,0,0,0,0,0};                   // Counter since pad started to play
    unsigned char status;
    int pin = 0;  
    int hitavg = 0;
    boolean VelocityFlag  = true;      
    void setup()
    {
      pinMode(S0, OUTPUT);
      pinMode(S1, OUTPUT);
      pinMode(S2, OUTPUT);
      Serial.begin(57600);
    }
    void loop()
    {
      // запросили данные с 8 каналов мультиплексора
      GetAnalogData();
      // теперь используем эти данные - например, выводим все в терминал
      for(int i = 0; i < 8; i++)
        PrintMuxChannel(i);
      delay(500);
    }
    // функция перебирает все каналы мультиплексора и сохраняет данные в массиве buffer
    void GetAnalogData()
    {
      // перебираем 8 каналов мультиплексора - с 0-го по 7-й включительно
      for(int i = 0; i < 8; i++)
      {
        SetMuxAddress(i);           // выставляем на мультиплексоре адрес очередного канала
        buffer[i] = analogRead(A0);  // читаем аналоговый вход и сохраняем его в i-й элемент массива
      }
    }
     
    // функция выставляет на мультиплексоре адрес заданного канала
    void SetMuxAddress(int address)
    {
        digitalWrite(S0, (address >> 0) & 0x1);
        digitalWrite(S1, (address >> 1) & 0x1);
        digitalWrite(S2, (address >> 2) & 0x1);
    }
     
    // функция выводит один канал данных в терминал
    void PrintMuxChannel(int channel)
    {
     
        hitavg = analogRead(pin);                             // read the input pin
     
        if((hitavg > PadCutOff[pin]))
        {
          if((activePad[pin] == false))
          {
            if(VelocityFlag == true)
            {
    //        hitavg = 127 / ((1023 - PadCutOff[pin]) / (hitavg - PadCutOff[pin])); // With full range (Too sensitive ?)
              hitavg = (hitavg / 8) -1 ;                                                // Upper range
            }
            else
            {
              hitavg = 127;
            }
     
            MIDI_TX(144,PadNote[pin],hitavg);
            PinPlayTime[pin] = 0;
            activePad[pin] = true;
          }
          else
          {
            PinPlayTime[pin] = PinPlayTime[pin] + 1;
          }
        }
        else if((activePad[pin] == true))
        {
          PinPlayTime[pin] = PinPlayTime[pin] + 1;
         
          if(PinPlayTime[pin] > MaxPlayTime[pin])
          {
            activePad[pin] = false;
            MIDI_TX(128,PadNote[pin],127);
          }
        }
      }
     
     
    void MIDI_TX(unsigned char MESSAGE, unsigned char PITCH, unsigned char VELOCITY)
    {
      status = MESSAGE + midichannel;
      Serial.print(status);
      Serial.print(PITCH);
      Serial.print(VELOCITY);
     
    }
     
  14. Nodit

    Nodit Нуб

    Уважаемые, вопросы по первоначальному проекту есть. Там используется плата с резисторами. Где-то можно схему распайки резисторов найти? И по самим пьезоэлементам вопрос - мощность сигнала, получаемый с пьезика зависит от размера элемента? Т.е. в зависимости от размера элемента (27 мм, 35 мм) надо будет подбирать соответствующие резисторы?
     
  15. unsuy

    unsuy Нуб

    интересно, получилось ли? у меня те же грабли... собираю миди контроллер на MEGA с multiplex HFC4051 ... код не заводится
     
  16. unsuy

    unsuy Нуб

    arduino_midi_schematic.png

    вот у меня так работает.. еще конденсатор на 1 uF паралельно добавил для уменьшения шумов и чуствительности