ARDUINO MIDI DRUM SET

varvik85
Offline
Зарегистрирован: 28.01.2013

Добрый день!Давно хочу собрать миди барабанную установку,и недавно приобрел контроллер ARDUINO,собственно в программировани еще новичек.Опробовал проектик http://www.spikenzielabs.com/SpikenzieLabs/DrumKitKit.html ,работает неплохо,единственное занимает все шесть аналоговых входа.Хочется расширить возможности применив мультиплексор 4051,но вот с ним уже который день бьюсь и ничего не выходит,помогите пожалуйста с программой,вот собственно что получается

#define S0 2	// нога адреса мультиплексора
#define S1 3	// вторая
#define S2 4	// третья
int buffer[8];  // массив на 8 элементов для хранения данных с 8 каналов мультиплексора
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 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;
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)
{
 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); 
      }
    }
  } 
}

void MIDI_TX(unsigned char MESSAGE, unsigned char PITCH, unsigned char VELOCITY) 
{
  status = MESSAGE + midichannel;
  Serial.print(status);
  Serial.print(PITCH);
  Serial.print(VELOCITY);

}

 

varvik85
Offline
Зарегистрирован: 28.01.2013

Не получается объединить два массива,вернее присвоить нотам числа из массива с аналогого входа,помогите.

varvik85
Offline
Зарегистрирован: 28.01.2013

Пардон,немного накосячил...так правильнее

#define S0 2	// нога адреса мультиплексора
#define S1 3	// вторая
#define S2 4	// третья
int buffer[8];  // массив на 8 элементов для хранения данных с 8 каналов мультиплексора
unsigned char PadNote[8] = {52,16,66,63,40,65,45,48};         // MIDI notes from 0 to 127 (Mid C = 60)
int PadCutOff[8] = {600,600,600,600,600,600,600,600};           // Minimum Analog value to cause a drum hit
int MaxPlayTime[8] = {90,90,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 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};  

 

varvik85
Offline
Зарегистрирован: 28.01.2013

Изначально программа выглядела так :

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

 

varvik85
Offline
Зарегистрирован: 28.01.2013

Программа обработки мультиплексора :

#define S0 2	// нога адреса мультиплексора
#define S1 3	// вторая
#define S2 4	// третья
int buffer[8];  // массив на 8 элементов для хранения данных с 8 каналов мультиплексора
 
void setup()
{
  pinMode(S0, OUTPUT);
  pinMode(S1, OUTPUT);
  pinMode(S2, OUTPUT);
 

}
 
// основной цикл - опрашиваем мультиплексор, выводим данные, делаем паузу
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);
}
 

 

varvik85
Offline
Зарегистрирован: 28.01.2013

Ну и вот что то не получается их объединить,точнее я не совсем понимаю как из массива buffer вытащить числа и обозначить их как ноты и прочее.

varvik85
Offline
Зарегистрирован: 28.01.2013

Спасибо за помощь!Акуенный форум!

leshak
Offline
Зарегистрирован: 29.09.2011

 

varvik85 пишет:

Спасибо за помощь!Акуенный форум!

Да всегда пожалуста. Вы тоже Акуенный посетитель. 

А задуматься "а почему молчат?" не пробовали? Ведь другим же помогают/отвечают

Варианты:

1. Никто не знает как вам помоч
2. Никому не интерестна тема
3. Слишком много вникать нужно, то есть фактически "это работа", а не "нужен маленький совет на бегу" .
4. Просто никто не понял что именно вам нужно

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

 

varvik85
Offline
Зарегистрирован: 28.01.2013

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

 

P.S если человек дол..еб и хочет заново изобрести велосипед ради бога,когда есть готовый код, не вижу препятствий чтоб его не использовать в своих целях.

leshak
Offline
Зарегистрирован: 29.09.2011

varvik85 пишет:

P.S если человек дол..еб и хочет заново изобрести велосипед ради бога,когда есть готовый код, не вижу препятствий чтоб его не использовать в своих целях.

Браво, вы так не замутнены, что ваша ругать даже не обижает, а вызывает умиление. 

Так что если будут еще вопросы от вас - постараемся помочь, если сможем.

А "кто, когда..,". Ну так ведь не сидит никто на зарплате. Я например, когда вы изначальную ветку создавали - вообще на форум не заходил. Занят был.

Своим постом - вы подняли в топ. Глянул сегодня  - увидел ваш пост... в принциме можно с чем-то разбиратся, но реально не очень ясно что вы хотите (сразу несколько версий возникло). А опять вытягивать клещами что нужно ... ну честно, надоело уже. 

А "изобретать велосипед" - так никто не призывал вас отказатся от использования готового кода. Но что-бы начать его модифицировать, в него нужно "втыкнуть". Вы пару дней над этим сидели, вам "все ясно" (вернее даже в этом случае не все ясно). И вы хотите что-бы кто-то бегло, потратив десятки секунд сразу вник? Часто проще закрыть вкладку и открыть где понятней. Недостататка в том кому что-то подсказать - особо нет.

Так что не обижайтесь, просто постарайтесь учесть тот список "почему могут игнорировать". Попробуйте посмотреть глазами постороннего человека. Который не в контексте, который просто "зашел не форум..". Возможно нужно какие-то вводные объяснения давать, возможно просто сузить задачку до именно вызывающего проблемы места.

А криками и обидами - тут делу не поможешь. Понятно что вы получили негативный опыт. Бывает. Вы думаете у меня небыло что "задал вопрос и тишина"? - тоже бывало. ну и что? Раз на раз - не приходится. Где-то ответили, где-то сам в итоге раскопал (и выложил на форум ответ, для других).

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

Да и вообще. Сегодня день смеха. Не нужно злится. Хорошего вам дня.

ugc
Offline
Зарегистрирован: 23.04.2013

Привет, а можно поподробнее, получилось ли желаемое с мультиплексором? столкнулся с такой же проблемой.

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

у меня пьезо вместе с миди передают еще аналоговый сигнал в аблетон... была ли у тебя такая проблема?

 

1nsant
Offline
Зарегистрирован: 06.04.2017

Доброго времени суток ! 

Использую скетч ТС`а , у меня получается какаято ересь. При одном ударе по одному пьезо сенсору вылетает 3-4 ноты.В чем может быть причина. И еще хотелось бы разделить бараны по миди каналам , есть идеи как это реализовать в коде? 

Клапауций 112
Клапауций 112 аватар
Offline
Зарегистрирован: 01.03.2017

1nsant пишет:
При одном ударе по одному пьезо сенсору вылетает 3-4 ноты.В чем может быть причина. И еще хотелось бы разделить бараны по миди каналам , есть идеи как это реализовать в коде?

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

Jeka_M
Jeka_M аватар
Offline
Зарегистрирован: 06.07.2014

Клапауций 112 пишет:

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

Но они действительно существуют :-)

Клапауций 112
Клапауций 112 аватар
Offline
Зарегистрирован: 01.03.2017

Jeka_M пишет:

Но они действительно существуют :-)

ну, это же не музыкальные ноты, а так понимаю - сила удара.

пусть вопрошающий теперь задаст вопрос сам себе, зачем он по пьезо элементу не стучит с одинаковой силой.

1nsant
Offline
Зарегистрирован: 06.04.2017

Вы глумитесь чтоли? Скетч подразумевает , что за каждым аналоговым входом на котором висит пьезо закреплена нота , которая играется с разной громкостью(силой?) в зависимости от силы сигнала. Вопрос в том что один пьезо играет 3-4 ноты за один удар (рабочий , хай хэт , крэш ) .

Клапауций 112
Клапауций 112 аватар
Offline
Зарегистрирован: 01.03.2017

1nsant пишет:

Вы глумитесь чтоли? Скетч подразумевает , что за каждым аналоговым входом на котором висит пьезо закреплена нота , которая играется с разной громкостью(силой?) в зависимости от силы сигнала. Вопрос в том что один пьезо играет 3-4 ноты за один удар (рабочий , хай хэт , крэш ) .

это ты глумишься над собой - если скетч подразумевает, что играется одна нота, то значит играется одна нота и никак иначе.

1nsant
Offline
Зарегистрирован: 06.04.2017

Ты скриншот видишь? Последние 3 строки - один удар , вылетают три разные ноты с одинаковым велосити.
У меня подключено 2 пьезо на разных входах , на обоих одно и тоже .

Клапауций 112
Клапауций 112 аватар
Offline
Зарегистрирован: 01.03.2017

1nsant пишет:
Ты скриншот видишь? Последние 3 строки - один удар , вылетают три разные ноты с одинаковым велосити. У меня подключено 2 пьезо на разных входах , на обоих одно и тоже .

значит, скетч не подразумевает одну ноту - это же очевидно. ¯\_(ツ)_/¯

Yarik.Yar
Offline
Зарегистрирован: 07.09.2014

ДребеСк?

Клапауций 112
Клапауций 112 аватар
Offline
Зарегистрирован: 01.03.2017

Yarik.Yar пишет:

ДребеСк?

точно! дребезг аналоговых пьезоэлементов.

как всё просто оказалось - расходимся.