arduino midi через usb

Dmitry K
Offline
Зарегистрирован: 11.08.2011

являюсь обладателем craftDuino на 328 меге, хочу попробовать разработать полноценный миди контроллер, хотел бы услышать ваши мысли по данной теме.  требования к устройсву: подключения большого количесва кнопок и потенциометров энокодеров и трансляция их состояний через уарт(физечки через USB) спец софту а именно Tracktor DJ pro

Adessit
Adessit аватар
Offline
Зарегистрирован: 12.04.2011

 Расширители портов, или сдвиговые регистры (лучше первое) это на кнопки (можно будет их каскадно включать и будет мильйон кнопочек). 6 аналоговых входов - тоесть шесть переменников мало? То надо будет внешние ацп микросхемы цеплять или вот такого плана самому собрать http://www.appliedplatonics.com/anshield/

Adessit
Adessit аватар
Offline
Зарегистрирован: 12.04.2011

Кнопки можно подключать в матрицу и на сдвиговые регистры. например 64 кнопки займут 16 ног сдвиговых регистров тоесть 2 микросхемки дешевые справятся

Mogalkov
Offline
Зарегистрирован: 23.06.2011

Кнопки можно вешать и на аналоговый вход через разные резисторы (типа набор делителей), аналоговаый вход даст до 1023 кнопок, но без поддержки одновременного нажатия.

Soso
Offline
Зарегистрирован: 22.03.2011

 Думается мне одновременное нажатие на midi-контроллере критично. А "большого количества кнопок", это сколько?

Dmitry K
Offline
Зарегистрирован: 11.08.2011

огромное спасибо за хороший старт и интересные идеи. Soso почему вы считаете что одновременное нажатие кретично? хотелось бы конкретный аргумент услышать так как в этом есть своя необходимость.  Adessit имею в наличии 2 SPI-расширителя на 8 входов, 
74hc165 подойдут ли они если да то подскажите как собрать из них матрицу? или как включать каскадно? каскадно я так понимаю это паралельно добовляя только RCK для каждого сдвигового регистра? как насчет их количесва? сколько душе угодно?

Dmitry K
Offline
Зарегистрирован: 11.08.2011

Adessit 6 аналоговых входов маловато посмотрел вашу ссылку по аналоговому вводу точнее его расшерение весьма интересный вариант и количесво аналоговых входов превлекло, не разобрал маркировки микросхем кроме (4051N можно по точнее маркировку) как считаете если взять по максимуму тоесть расширить все аналоговые и все цифровые вход ардуина выдержит такого натиска?

Dmitry K
Offline
Зарегистрирован: 11.08.2011

и весьма не маловажный вопрос ктонибуть может скинуть пример кода например для кнопок для начала через здвиговый регистр чтобы в результате получить миди передачу присвоить ее какой либо функции в Tracktor чтобы поуправлять чемнибуть через ардуину. Теория тоже преветсвуется :) 

Adessit
Adessit аватар
Offline
Зарегистрирован: 12.04.2011

http://www.appliedplatonics.com/anshield/parts.html

это раз .

во вторых этот набор можно с готовой платой у них купить. 20 долларов + доставка, не больно большие деньги.  

Вы сами определитесь с количеством кнопок) И начните без расширтелей и усложнителей, подцепите 2-3 переменника, и 4-5 кнопок, напишите скетч и программу для трактора, а там и подумаете стоит ли игра свеч и что к чему) Не беритесь сразу за сложное отработайте простое до идеала, а там уже и сто кнопок подцепите при желании)

Dmitry K
Offline
Зарегистрирован: 11.08.2011

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

Adessit
Adessit аватар
Offline
Зарегистрирован: 12.04.2011

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

А там и обычную пс/2 клаву подключите) с наклеенными на клавиши стикерами функций)

Dmitry K
Offline
Зарегистрирован: 11.08.2011

)) интересное предложение но всеже хотелось бы по предложенной вами схеме и если есть возможность то подскажите форум(ы) где специалисты натолкнут на мысль как написать код

Adessit
Adessit аватар
Offline
Зарегистрирован: 12.04.2011
Dmitry K
Offline
Зарегистрирован: 11.08.2011

спасибо уважаемый Adessit, гугль люблю, пользоваться умею, читал данные форумы чтото серое вещество не забурлило видимо еще время не настало :) 

Dmitry K
Offline
Зарегистрирован: 11.08.2011

помогите разобраться в коде. А именно для начала в кнопках как по нажатию кнопки отправлять код миди

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

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

.

Van
Van аватар
Offline
Зарегистрирован: 04.10.2016

Доброго времени суток всем! Собрал миди контроллер на Arduino Mega 2560 (ATmega8U2). Перепрошил с помощью Flip в arduino_midi. При подключении к компьютеру ведёт себя как любой "plug and play" миди контроллер. Сам находит и устанавливает драйвера. Но по сравнению с другими миди контроллерами имеет ощутимую задержку при нажатии кнопок, примерно в пол секунды. Сначала думал проблема в Windows, но оказалось в OS X та же беда. Но так как я новичок в программировании, думаю что проблема может быть в скетче. Окиньте взглядом, ткните носом пожалуйста.

Van
Van аватар
Offline
Зарегистрирован: 04.10.2016
#include <MIDI.h>
#include <midi_Defs.h>
#include <midi_Message.h>
#include <midi_Namespace.h>
#include <midi_Settings.h>



MIDI_CREATE_DEFAULT_INSTANCE (); 
#include <LCD5110_Graph.h>


LCD5110 lcd(8,9,10,12,11);
extern uint8_t one[];
extern uint8_t two[];
extern uint8_t three[];
extern uint8_t four[];
extern uint8_t five[];
extern uint8_t six[];
extern uint8_t seven[];
extern uint8_t eight[];
extern uint8_t rec[];
extern uint8_t empty[];
extern uint8_t play[];
extern uint8_t sol[];
extern uint8_t all[];
extern uint8_t dub[];
extern uint8_t mut[];
extern uint8_t rst[];
extern uint8_t rev[];

#define encoder0PinA 2
#define encoder0PinB 3

#define note_C 0x3C  // C4
#define note_D 0x3E  // D4
#define note_E 0x40  // E4 Под вопросом
#define note_F 0x41  // F4 
#define note_G 0x43  // G4
#define note_A 0x45  // Исключён
#define note_B 0x47  // B4
#define note_C2 0x48
#define note_D2 0x50
#define note_E2 0x52
#define note_F2 0x53
#define note_G2 0x55

volatile int encoder0Pos = 0;
static boolean rotating=false;

#define switch_C  4  // Prev
#define switch_D  5  // Next
#define switch_E  6  // Под вопросом
#define switch_F  7  // rec
#define switch_G  22  //play
#define switch_A  32  // Исключён
#define switch_B  23  //all
#define switch_C2  24  //sol
#define switch_D2  25  //dub
#define switch_E2  26  //mut
#define switch_F2  27  //rst
#define switch_G2  29  //rev  


int regim=1;
int regim2=1;
int regim3=1;
int regim4=1;
int regim5=1;
int regim6=1;
int regim7=1;
int regim8=1;
int regim9=1;
int regim10=1;
int flag=0;
int flag2 = 0;
int flag3 = 0;
int flag4 = 0;
int flag5 = 0;
int flag6 = 0;
int flag7 = 0;
int flag8 = 0;
int flag9 = 0;
int flag10 = 0;
int buttonState_C = 0;
int buttonState_D = 0;
int buttonState_E = 0;
int buttonState_F = 0;
int buttonState_G = 0;
int buttonState_A = 0;
int buttonState_B = 0;
int buttonState_C2 = 0;
int buttonState_D2 = 0;
int buttonState_E2 = 0;
int buttonState_F2 = 0;
int buttonState_G2 = 0;

int note_C_send_off = false;
int note_C_send_on = false;
int note_D_send_off = false;
int note_D_send_on = false;
int note_E_send_off = false;
int note_E_send_on = false;
int note_F_send_off = false;
int note_F_send_on = false;
int note_G_send_off = false;
int note_G_send_on = false;
int note_A_send_off = false;
int note_A_send_on = false;
int note_B_send_off = false;
int note_B_send_on = false;
int note_C2_send_off = false;
int note_C2_send_on = false;
int note_D2_send_off = false;
int note_D2_send_on = false;
int note_E2_send_off = false;
int note_E2_send_on = false;
int note_F2_send_off = false;
int note_F2_send_on = false;
int note_G2_send_off = false;
int note_G2_send_on = false;
//byte MSB; 
//unsigned int LSB;

void setup()
{
  
  pinMode(switch_C, INPUT);
  pinMode(switch_D, INPUT);
  pinMode(switch_E, INPUT);
  pinMode(switch_F, INPUT);
  pinMode(switch_G, INPUT);
  pinMode(switch_A, INPUT);
  pinMode(switch_B, INPUT);
  pinMode(switch_C2, INPUT);
  pinMode(switch_D2, INPUT);
  pinMode(switch_E2, INPUT);
  pinMode(switch_F2, INPUT);
  pinMode(switch_G2, INPUT);  
  pinMode(encoder0PinA, INPUT); 
  digitalWrite(encoder0PinA, HIGH);       
  pinMode(encoder0PinB, INPUT); 
  digitalWrite(encoder0PinB, HIGH);
  

  attachInterrupt(0, rotEncoder, CHANGE);  
  lcd.InitLCD();
  MIDI.begin(1);
  Serial.begin(31250);
  


  
   
   
   
  
  
}

void rotEncoder(){
  rotating=true; 
}

void loop()
{
  buttonState_C = digitalRead(switch_C);
  buttonState_D = digitalRead(switch_D);
  buttonState_E = digitalRead(switch_E);
  buttonState_F = digitalRead(switch_F);
  buttonState_G = digitalRead(switch_G);
  buttonState_A = digitalRead(switch_A);
  buttonState_B = digitalRead(switch_B);
  buttonState_C2 = digitalRead(switch_C2);
  buttonState_D2 = digitalRead(switch_D2);
  buttonState_E2 = digitalRead(switch_E2);
  buttonState_F2 = digitalRead(switch_F2);
  buttonState_G2 = digitalRead(switch_G2);
 
  if (digitalRead(switch_C)==HIGH&&flag==0)
 {
  regim++;
  flag=1;
if(regim>8)
  {
  regim=1;
  }
}
if(digitalRead(switch_C)==LOW&&flag==1)
{
flag=0;
}
if(regim==1)
{

lcd.drawBitmap(42,0,one,42,48);
lcd.update();  
}
if(regim==2)
{

lcd.drawBitmap(42,0,two,42,48);
lcd.update();
}
if(regim==3)
{

lcd.drawBitmap(42,0,three,42,48);
lcd.update();
}
if(regim==4)
{

lcd.drawBitmap(42,0,four,42,48);
lcd.update();
}
if(regim==5)
{

lcd.drawBitmap(42,0,five,42,48);
lcd.update();
}
if(regim==6)
{

lcd.drawBitmap(42,0,six,42,48);
lcd.update();
}
if(regim==7)
{

lcd.drawBitmap(42,0,seven,42,48);
lcd.update();
} 
if(regim==8)
{

lcd.drawBitmap(42,0,eight,42,48);
lcd.update();
}
if(digitalRead(switch_D)==HIGH&&flag2==0)
  {
  regim--;
  flag2=1;
  if(regim<1)
    {
  regim=8;
  }
}
if(digitalRead(switch_D)==LOW&&flag2==1)
{
flag2=0;
}

  if (digitalRead(switch_F)==HIGH&&flag3==0)
 {
  regim3++;
  flag3=1;
if(regim3>2)
  {
  regim3=1;
  }
}
if (digitalRead(switch_F)==LOW&&flag3==1)
{
flag3=0;
}
if(regim3==1)
{

lcd.drawBitmap(0,0,empty,42,48);
  
}
if(regim3==2)
{

lcd.drawBitmap(0,16,rec,42,16);
  
}
  if (digitalRead(switch_G)==HIGH&&flag4==0)
 {
  regim4++;
  flag4=1;
if(regim4>2)
  {
  regim4=1;
  }
}
if (digitalRead(switch_G)==LOW&&flag4==1)
{
flag4=0;
}
if(regim4==1)
{


  
}
if(regim4==2)
{

lcd.drawBitmap(0,16,play,42,16);

}

  if (digitalRead(switch_B)==HIGH&&flag5==0)
 {
  regim5++;
  flag5=1;
if(regim5>2)
  {
  regim5=1;
  }
}
if (digitalRead(switch_B)==LOW&&flag5==1)
{
flag5=0;
}
if(regim5==1)
{


  
}
if(regim5==2)
{

lcd.drawBitmap(0,0,all,42,16);

}

  if (digitalRead(switch_C2)==HIGH&&flag6==0)
 {
  regim6++;
  flag6=1;
if(regim6>2)
  {
  regim6=1;
  }
}
if (digitalRead(switch_C2)==LOW&&flag6==1)
{
flag6=0;
}
if(regim6==1)
{


 
}
if(regim6==2)
{

lcd.drawBitmap(0,16,sol,42,16);
lcd.update();
}
  if (digitalRead(switch_D2)==HIGH&&flag7==0)
 {
  regim7++;
  flag7=1;
if(regim7>2)
  {
  regim7=1;
  }
}
if (digitalRead(switch_D2)==LOW&&flag7==1)
{
flag7=0;
}
if(regim7==1)
{


  
}
if(regim7==2)
{

lcd.drawBitmap(0,16,dub,42,16);
lcd.update();
}
  if (digitalRead(switch_E2)==HIGH&&flag8==0)
 {
  regim8++;
  flag8=1;
if(regim8>2)
  {
  regim8=1;
  }
}
if (digitalRead(switch_E2)==LOW&&flag8==1)
{
flag8=0;
}
if(regim8==1)
{


 
}
if(regim8==2)
{

lcd.drawBitmap(0,32,mut,42,16);

}
  if (digitalRead(switch_F2)==HIGH&&flag9==0)
 {


lcd.drawBitmap(0,16,rst,42,16);
lcd.update();

}
  if (digitalRead(switch_G2)==HIGH&&flag10==0)
 {
  regim10++;
  flag10=1;
if(regim10>2)
  {
  regim10=1;
  }
}
if (digitalRead(switch_G2)==LOW&&flag10==1)
{
flag10=0;
}
if(regim10==1)
{


 
}
if(regim10==2)
{

lcd.drawBitmap(0,16,rev,42,16);
lcd.update();
   }
   while(rotating) {
    delay(2);
    if (digitalRead(encoder0PinA) == digitalRead(encoder0PinB)) {  
      encoder0Pos = encoder0Pos + 5;
      //encoder0Pos++;
      if(encoder0Pos > 127) encoder0Pos = 127;
    } 
    else {                                   
      encoder0Pos = encoder0Pos - 5;
      //encoder0Pos--;
      if(encoder0Pos < 0) encoder0Pos = 0;
    }
    Serial.println(encoder0Pos,DEC);
    //MSB = encoder0Pos >> 8;    // Старший байт
    //LSB = encoder0Pos & 0xFF;  // Младший байт
    //Serial.println(MSB,BIN);
    //Serial.println(LSB,BIN);
    noteOn(0xB0, 0x01, encoder0Pos);  // Modulation Wheel Controller
    //noteOn(0xE0, MSB, LSB);    // Pitch Bend
    rotating=false; // Reset the flag back to false
    //Serial.println(encoder0Pos);
  }
  
  // Нота C
  if (buttonState_C == HIGH && note_C_send_on == false)  // Нажатие клавиши
  {
    noteOn(0x81, note_C, 0x00);
    note_C_send_on = true;    // Команда Note On послана
    note_C_send_off = false;  // Команда Note Off не послана
    
    
  
  }
  else if (buttonState_C == LOW && note_C_send_off == false)  // Если клавишу отпустили
  {
    noteOn(0x91, note_C, 0x7F);
    note_C_send_on = false;
    note_C_send_off = true;
    encoder0Pos = 0;  // Возвращаем позицию колеса в ноль
  }
  
  
 
  // Нота D
  if (buttonState_D == HIGH && note_D_send_on == false)
  {
    noteOn(0x91, note_D, 0x7F);
    note_D_send_on = true;
    note_D_send_off = false;
 
  }
  else if (buttonState_D == LOW && note_D_send_off == false)
  {
    noteOn(0x81, note_D, 0x00);
    note_D_send_on = false;
    note_D_send_off = true;
    encoder0Pos = 0;
  }
   
  
  // Нота E
  if (buttonState_E == HIGH && note_E_send_on == false)
  {
    noteOn(0x91, note_E, 0x7F);
    note_E_send_on = true;
    note_E_send_off = false;

    

  }
  else if (buttonState_E == LOW && note_E_send_off == false)
  {
    noteOn(0x81, note_E, 0x00);
    note_E_send_on = false;
    note_E_send_off = true;
    encoder0Pos = 0;

  }  
  
  // Нота F
  if (buttonState_F == HIGH && note_F_send_on == false)
  {
    noteOn(0x91, note_F, 0x7F);
    note_F_send_on = true;
    note_F_send_off = false;
  }

  else if (buttonState_F == LOW && note_F_send_off == false)
  {
    noteOn(0x81, note_F, 0x00);
    note_F_send_on = false;
    note_F_send_off = true;
    encoder0Pos = 0;
  }  


  // Нота G
  if (buttonState_G == HIGH && note_G_send_on == false)
  {
    noteOn(0x91, note_G, 0x7F);
    note_G_send_on = true;
    note_G_send_off = false;
  }

  else if (buttonState_G == LOW && note_G_send_off == false)
  {
    noteOn(0x81, note_G, 0x00);
    note_G_send_on = false;
    note_G_send_off = true;
    encoder0Pos = 0;
  }  
  
  // Нота A
  if (buttonState_A == HIGH && note_A_send_on == false)
  {
    noteOn(0x91, note_A, 0x00);
    note_A_send_on = true;
    note_A_send_off = false;
  }

  else if (buttonState_A == LOW && note_A_send_off == false)
  {
    noteOn(0x81, note_A, 0x00);
    note_A_send_on = false;
    note_A_send_off = true;
    encoder0Pos = 0;
  }   
  
  // Нота B
  if (buttonState_B == HIGH && note_B_send_on == false)
  {
    noteOn(0x91, note_B, 0x7F);
    note_B_send_on = true;
    note_B_send_off = false;
    
  }
  else if (buttonState_B == LOW && note_B_send_off == false)
  {
    noteOn(0x81, note_B, 0x00);
    note_B_send_on = false;
    note_B_send_off = true;
    encoder0Pos = 0;


  }     
  if (buttonState_C2 == HIGH && note_C2_send_on == false)  // Нажатие клавиши
  {
    noteOn(0x91, note_C2, 0x7F);
    note_C2_send_on = true;    // Команда Note On послана
    note_C2_send_off = false;  // Команда Note Off не послана 
 
  }
  else if (buttonState_C2 == LOW && note_C2_send_off == false)  // Если клавишу отпустили
  {
    noteOn(0x81, note_C2, 0x00);
    note_C2_send_on = false;
    note_C2_send_off = true;
    encoder0Pos = 0;  // Возвращаем позицию колеса в ноль
  }

    if (buttonState_D2 == HIGH && note_D2_send_on == false)  // Нажатие клавиши
  {
    noteOn(0x91, note_D2, 0x7F);
    note_D2_send_on = true;    // Команда Note On послана
    note_D2_send_off = false;  // Команда Note Off не послана 
 
  }
  else if (buttonState_D2 == LOW && note_D2_send_off == false)  // Если клавишу отпустили
  {
    noteOn(0x81, note_D2, 0x00);
    note_D2_send_on = false;
    note_D2_send_off = true;
    encoder0Pos = 0;  // Возвращаем позицию колеса в ноль
      }

    if (buttonState_E2 == HIGH && note_E2_send_on == false)  // Нажатие клавиши
  {
    noteOn(0x91, note_E2, 0x7F);
    note_E2_send_on = true;    // Команда Note On послана
    note_E2_send_off = false;  // Команда Note Off не послана 
 
  }
  else if (buttonState_E2 == LOW && note_E2_send_off == false)  // Если клавишу отпустили
  {
    noteOn(0x81, note_E2, 0x00);
    note_E2_send_on = false;
    note_E2_send_off = true;
    encoder0Pos = 0;  // Возвращаем позицию колеса в ноль
}
 
    if (buttonState_F2 == HIGH && note_F2_send_on == false)  // Нажатие клавиши
  {
    noteOn(0x91, note_F2, 0x7F);
    note_F2_send_on = true;    // Команда Note On послана
    note_F2_send_off = false;  // Команда Note Off не послана 
 
  }
  else if (buttonState_F2 == LOW && note_F2_send_off == false)  // Если клавишу отпустили
  {
    noteOn(0x81, note_F2, 0x00);
    note_F2_send_on = false;
    note_F2_send_off = true;
    encoder0Pos = 0;  // Возвращаем позицию колеса в ноль
}
    if (buttonState_G2 == HIGH && note_G2_send_on == false)  // Нажатие клавиши
  {
    noteOn(0x91, note_G2, 0x7F);
    note_G2_send_on = true;    // Команда Note On послана
    note_G2_send_off = false;  // Команда Note Off не послана 
 
  }
  else if (buttonState_G2 == LOW && note_G2_send_off == false)  // Если клавишу отпустили
  {
    noteOn(0x81, note_G2, 0x00);
    note_G2_send_on = false;
    note_G2_send_off = true;
    encoder0Pos = 0;  // Возвращаем позицию колеса в ноль
}
}
void noteOn(int cmd, int pitch, int velocity) {
   Serial.write(cmd);
   Serial.write(pitch);
   Serial.write(velocity);
   
}