MIDI drum

zsm@nxt.ru
Offline
Зарегистрирован: 27.05.2013

Добрый день , нашел на просторах интернета вот такой проект.
Решив не бросаться сразу на амбразуру попробовал просто передать MIDI с помощью официального примера через Serial MIDI Converter и midi_yoke всё завелось на скорости 19200.
Но когда попробовал пример из первой ссылки столкнулся с тем что данные на любой скорости передаются с ошибками. По факту доходит не читаемая белиберда:(
Подозреваю что дело в функции Serial.print используемой в midi drum . Если заменять Serial.print на Serial.write как в примере то ошибки передачи пропадают, но передаются сразу все ноты...
Буду рад любым советам или просто соображениям по теме :)

//  *****************************************************************************************************************
//  *                                                                                                              *
//  *                                        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);
}

 

 

mihart
Offline
Зарегистрирован: 14.05.2013

В setup у вас serial инициализируется на 57600, в serial midi converter ту же скорость выставили?

 
mihart
Offline
Зарегистрирован: 14.05.2013
Чтобы понять serial виноват или нет, я бы удалил весь код из loop и написал что-нибудь такое:

 

MIDI_TX(144,20,127);
Delat(1000);
MIDI_TX(128,20,127);
Delay(1000);
Раз в секунду должна звучать нота, через секунду сниматься. 
В serial monitor на скорости 57600 должны приходить сообщения вроде 8000157F (пишу с телефона, сейчас провеить точно не могу).
zsm@nxt.ru
Offline
Зарегистрирован: 27.05.2013

Mihart ,большое спасибо, сейчас попробую.

zsm@nxt.ru
Offline
Зарегистрирован: 27.05.2013

Попробовал как Вы советовали на скорости 57600 в serial monitor  приходит 1542012713820127 . 

если включить Serial_MIDI_Converter_    RX мигает  красным , (что не есть хорошо т.к. когда все нормально он должен мигать зелёным),адио редактор миди сигнал  не получает.

короче буду матчасть учить :)   так с разбегу не разобраться

mihart
Offline
Зарегистрирован: 14.05.2013

Буду дома, попробую у себя.

zsm@nxt.ru
Offline
Зарегистрирован: 27.05.2013

спасибо за помошь)

когда меняеш Serial.print  на Serial.write нота передаётся на скорости 19200   , но в скетче с барабанами такая замена приводит к тому что передаются все 6 нот сразу)

mihart
Offline
Зарегистрирован: 14.05.2013

К сожалению MIDI Converter у меня не заработал, застопорилось на выборе MIDI Output Port.

На мой взгляд MIDI Converter ждет байтов, поэтому считаю, что точно нужно менять Serial.print на Serial.write.

Опять же у меня вопрос почему по команде MIDI_TX(144,20,127) вам в сериал монитор приходит 15420127. Вы #define midichannel 0 на десяточку не меняли?

И самое главное, что хотел уточнить, чтобы еще попытаться помочь. Когда вы пишете что все 6 нот передаются сразу вы что имеете в виду:

1. что по всем барабаном одновременно ударили?

2. Или вы по барабанам бьете последовательно с паузами, а вот команды в сериал монитор приходят единой пачкой?

3. Или уже midi converter собирает последовательные команды и единой пачкой выдает их в аудио редактор?

 

Потому как если у вас первая ситуация я бы смотрел строчку 79

hitavg = analogRead(pin);

У вас аналоговые пины к чему подключены? Такое впечатление что там плюс висит, который слету превышает PadCutOff. Пины если висят в воздухе могут собирать наводки. Их лучше подтянуть резистором к земле.

 

А по поводу миди, если вы и по этой теме будете матчасть учить рекомендую мою подборку, которая мне помогла конвертировать треки одной старой игрушки: http://ecstatica2.livejournal.com/33603.html

 

zsm@nxt.ru
Offline
Зарегистрирован: 27.05.2013

Здравствуйте, midichannel действительно зачем то на 10 поменял, видимо во время танцев с бубном:)

По второму вопросу , скорее пункт 2 т.к. midi converter пример с оф.сайта arduino переводит и посылает в аудио редактор   правильно.  

На алоговые пины просто подаю 5v. проводком) это действительно не дело. надо к земле притянуть.

Отдельное спасибо за ссылку, обязательно прочитаю все.

mihart
Offline
Зарегистрирован: 14.05.2013

Проверил у себя. Если не подтягивать 1 кОм или большим резистором все аналоговые пины к земле, то они все 6 и выскакивают. Если подтянуть, то проблема сразу исчезает.

Заработало как нужно?

zsm@nxt.ru
Offline
Зарегистрирован: 27.05.2013

Спасибо за содействие) сегодня ночью обязательно попробую.

На какой скорости завелось?

mihart
Offline
Зарегистрирован: 14.05.2013

На всех. Midi Converter не проверял, он у меня не работает, я писал. А в сериал мониторе приходит по одному сообщению. Думаю и дальше по конвееру проблем не будет.

zsm@nxt.ru
Offline
Зарегистрирован: 27.05.2013

Большое спасибо,   притянул аналоговые пины к земле , и всё заработало :) естественно с serial.write.

Статьи на muzoborudovanie.ru очень интересные оказались, много интересного узнал)

 

unsuy
Offline
Зарегистрирован: 05.08.2014

так же застрял на этом коде.. постоянно выдает одну и ту же ноту (G10) от всех пьезо и тот же velocity 24. Иногда проскакивает F#2 при громкости 127. Пробовал serial.print and serial.write, теже грабли.. Стоит резистор 1М и еще зенер диод 5.1 и даже пробовал с конденсатором 1uF. но пока без изменений.. Миди команды идут с ошибками