Skocz do zawartości

Komunikacja MIDI


patrinio

Pomocna odpowiedź

Cześć!

Ostatnio starałem się zbudować układ, za pomocą którego, mógłbym otrzymywać sygnały MIDI z mojego pianina. Zbudowałem układ według tego poradnika:

Dodam, że układ działa. Jednak nie mam pojęcia, jak napisać program, który umożliwiłby mi odczytywanie każdego klawisza na pianinie i np. przypisania temu klawiszowi jakiejś funkcji. 

Z góry dziękuję za pomoc 😀

Link do komentarza
Share on other sites

@patrinio, witam na forum 😉 Widzę, że to Twoje pierwsze kroki na Forbocie, oto najważniejsze informacje na start:

  • Chcesz przywitać się z innymi członkami naszej społeczności? Skorzystaj z tematu powitania użytkowników.
  • Opis najciekawszych funkcji, które ułatwiają korzystanie z forum znajdziesz w temacie instrukcja korzystania z forum - co warto wiedzieć?
  • Poszczególne posty możesz oceniać (pozytywnie i negatywnie) za pomocą reakcji - ikona serca w prawym dolnym rogu każdej wiadomości.

27 minut temu, patrinio napisał:

Jednak nie mam pojęcia, jak napisać program, który umożliwiłby mi odczytywanie każdego klawisza na pianinie i np. przypisania temu klawiszowi jakiejś funkcji. 

Pytasz o program bezpośrednio na Arduino czy chciałbyś napisać np. program na PC, który będzie sterowany przez Arduino podłączone do piania?

Link do komentarza
Share on other sites

Bezpośrednio na Arduino, używam biblioteki z opisu filmu <MIDI.h>.

Konkretnie, chciałbym aby po naciśnięciu klawisza na pianinie zapali się odpowiadająca mu dioda z paska LED-ów adresowalnych 😉

Arduino będzie przyklejone od dołu pianina i zasilane z kostki 12V.

Link do komentarza
Share on other sites

Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

Produkcja i montaż PCB - wybierz sprawdzone PCBWay!
   • Darmowe płytki dla studentów i projektów non-profit
   • Tylko 5$ za 10 prototypów PCB w 24 godziny
   • Usługa projektowania PCB na zlecenie
   • Montaż PCB od 30$ + bezpłatna dostawa i szablony
   • Darmowe narzędzie do podglądu plików Gerber
Zobacz również » Film z fabryki PCBWay

Mam 2 programy; działający i nie :).

Pierwszy (działający) jedynie wykrywa naciśnięty klawisz:

#include <MIDI.h>  
#define LED 13

//Create an instance of the library with default name, serial port and settings
MIDI_CREATE_DEFAULT_INSTANCE();

void setup() {
  pinMode (LED, OUTPUT); 
  MIDI.begin(MIDI_CHANNEL_OMNI); // Initialize the Midi Library.
  // OMNI sets it to listen to all channels.. MIDI.begin(2) would set it 
  // to respond to notes on channel 2 only.
  MIDI.setHandleNoteOn(MyHandleNoteOn); // This is important!! This command
  // tells the Midi Library which function you want to call when a NOTE ON command
  // is received. In this case it's "MyHandleNoteOn".
  MIDI.setHandleNoteOff(MyHandleNoteOff); // This command tells the Midi Library 
  // to call "MyHandleNoteOff" when a NOTE OFF command is received.
}

void loop() { 
  MIDI.read(); // Continuously check if Midi data has been received.
}

// MyHandleNoteON is the function that will be called by the Midi Library
// when a MIDI NOTE ON message is received.
// It will be passed bytes for Channel, Pitch, and Velocity
void MyHandleNoteOn(byte channel, byte pitch, byte velocity) { 
  digitalWrite(LED,HIGH);  //Turn LED on
}

// MyHandleNoteOFF is the function that will be called by the Midi Library
// when a MIDI NOTE OFF message is received.
// * A NOTE ON message with Velocity = 0 will be treated as a NOTE OFF message *
// It will be passed bytes for Channel, Pitch, and Velocity
void MyHandleNoteOff(byte channel, byte pitch, byte velocity) { 
  digitalWrite(LED,LOW);  //Turn LED off
}

 

I drugi (nie działający), który miał wykrywać i wypisywać wciśnięty klawisz:

#include <MIDI.h>  

#define LED 13    

MIDI_CREATE_DEFAULT_INSTANCE();

void setup() {
  pinMode (LED, OUTPUT); 
  MIDI.begin(MIDI_CHANNEL_OMNI); 
  MIDI.setHandleNoteOn(MyHandleNoteOn); 
  MIDI.setHandleNoteOff(MyHandleNoteOff); 
  
  int velocity = 0;
  int channel = 0;
}

void loop() { 
  MIDI.read(); 
}

//On
void MyHandleNoteOn(byte channel, byte pitch, byte velocity) { 
  digitalWrite(LED,HIGH);  
  int note = 0;
  velocity = 0;
  channel = 0;
  
  if(MIDI.read()){
    //write variable
    note = MIDI.getData1();
    velocity = MIDI.getData2();
    channel = MIDI.getChannel();
    //print variables
    Serial.println(String("Note on: ch=") + channel + String(", note=") + note + String(", velocity") + velocity);
  }
}

//Off
void MyHandleNoteOff(byte channel, byte pitch, byte velocity) { 
  digitalWrite(LED,LOW);  
}

 

Moim problemem w drugim kodzie są jakieś (chyba) zakłócenia w komunikacji (tak mi się wydaje, ale nie jestem pewien). Po włączeniu monitora ciągle wypisuje on znaki zapytania, a po wciśnięciu klawisza na pianinie, nie wypisuje on czysto kodu (nie tak jak powinien, trochę jakby był ustawiony na złej częstotliwości). Nie mam pojęcia jak 'czysto' wyciągnąć naciśniętą nutę.

Link do komentarza
Share on other sites

@patrinio w Twoim drugim programie nie "uruchamiasz" nigdzie komunikacji przez UART. Zabrakło minimum Serial.begin z wybraną prędkością komunikacji. Sprawdź w kursie jak to powinno wyglądać: Kurs Arduino – #3 – UART (komunikacja z PC), zmienne. Daj znać jakie będą efekty, gdy poprawisz program o brakujące ustawienia Seriala 😉

Link do komentarza
Share on other sites

(edytowany)

@Treker po dodaniu "Serial.begin(9600); ",ustawieniu monitora na 9600 i podłączeniu pianina, w dalszym ciągu komunikacja jest zakłócona:

"⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮``⸮⸮⸮ha⸮⸮⸮⸮⸮⸮#a⸮⸮⸮⸮⸮ha⸮⸮⸮qa⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮`h⸮⸮aa⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮"

Coś takiego wyskakuje po naciskaniu tego samego klawisza wielokrotnie + z każdą pętlą, na monitorze,  dopisywany jest znak zapytania.

 Czy możliwe jest to, że ta biblioteka MIDI nie rozumie sygnału MIDI z mojego pianina (YAMAHA Arius YDP-140)?

Edytowano przez patrinio
Link do komentarza
Share on other sites

@Belferek chyba nie o to chodzi, ale dzięki za pomoc ;). Aktualnie udało mi się wywnioskować, że podczas komunikacji MIDI nie da się używać monitora. Element :

void loop() { 
  MIDI.read(); 
}

generuje te tajemnicze znaki zapytania. Postanowiłem zmodyfikować kod:

#include <MIDI.h> 

#define LED 13  

int piB = 0 + 19;           //pitch (begin)
int piE = 88 + 19;          //pitch (end)

MIDI_CREATE_DEFAULT_INSTANCE();

void setup() {
  pinMode (LED, OUTPUT);
  MIDI.begin(MIDI_CHANNEL_OMNI); 
  MIDI.setHandleNoteOn(MyHandleNoteOn); 
  MIDI.setHandleNoteOff(MyHandleNoteOff);
}

void loop() { 
  MIDI.read(); 
}

void MyHandleNoteOn(byte channel, byte pitch, byte velocity) { 
  while (piB <= piE){
    piB++;
    int Pitch = MIDI.getData1();
    int Velocity = MIDI.getData2();
    int Channel = MIDI.getChannel();
    if (Pitch == piB){
      digitalWrite(LED,HIGH);  
    }
  }
  piB = 0;
}

void MyHandleNoteOff(byte channel, byte pitch, byte velocity) { 
  digitalWrite(LED,LOW);  //Turn LED off
}

Z jego pomocą można już wykryć każdy naciśnięty klawisz na pianinie. Tylko mam wątpliwości, czy ten kod będzie równie skuteczny dla większej ilości naciśniętych klawiszy. 

W jaki sposób powinienem teraz wyciągnąć każdy naciśnięty klawisz i zaświecić odpowiednią diodę LED (adresowalną)? I czy te ledy będą dobre?

Dziękuję za pomoc 😉

Link do komentarza
Share on other sites

@patrinio taka taśma powinna być dobra, ale pamiętaj o zadbaniu o odpowiednie zasilanie, bo nie możesz podłączyć jej bezpośrednio pod 5V z Arduino.

1 godzinę temu, patrinio napisał:

W jaki sposób powinienem teraz wyciągnąć każdy naciśnięty klawisz i zaświecić odpowiednią diodę LED (adresowalną)?

Rozpisz sobie warunki dla różnych warto zmiennych Pitch i tyle 🙂

Link do komentarza
Share on other sites

Wszystko zależy od konkretnej taśmy - każda ma inne parametry pracy. Taśmy WS2812B zasila się raczej z 5V i taka jest informacja na aukcji, którą linkowałeś wcześniej. Jeśli podłączysz taką taśmę pod 12V to uszkodzisz diody. Musisz zaopatrzyć się w odpowiedni zasilacz 5V, potrzebujesz około 15W na każdy metr taśmy.

Link do komentarza
Share on other sites

@Treker mam problem (chyba ze strony zasilacza). Po podłączeniu wszystkiego (z użyciem zasilacza) i włączeniu arduino, ledy kompletnie inaczej się zapalają niż powinny. Po podłączeniu ledów, zamiast do zasilacza, do wyjścia arduino 3.3V wszystko działa normalnie.

Podobnie, po podłączeniu paska 8 LED, z użyciem zasilacza i uruchomieniu kodu (poniżej),  w ledach pojawiają się 'zakłócenia'.

Kod:

#include <Adafruit_NeoPixel.h>

Adafruit_NeoPixel x = Adafruit_NeoPixel(8, A0, NEO_GRB + NEO_KHZ800);

int R = 0;
int G = 0;
int B = 0;

int setColors(int noLeds){
    for(int i=0; i<noLeds; i++){
    x.setPixelColor(i, x.Color(R, G, B));
    }
    x.show();

    return 0;
}

void setup() {
  // put your setup code here, to run once:
  x.begin();
  x.show();
  x.setBrightness(50);
}

void loop() {
  // put your main code here, to run repeatedly:
  for(int i=0; i<3; i++){
    for(int i=0; i<255; i++){
      R++;
      setColors(8);
      delay(10);
    }

    if(B!=0){
      for(int i=0; i<255; i++){
        B--;
        setColors(8);
        delay(10);
      }
    }

    for(int i=0; i<255; i++){
      G++;
      setColors(8);
      delay(10);
    }

    for(int i=0; i<255; i++){
      R--;
      setColors(8);
      delay(10);
    }

    for(int i=0; i<255; i++){
      B++;
      setColors(8);
      delay(10);
    }

    for(int i=0; i<255; i++){
      G--;
      setColors(8);
      delay(10);
    }
  }
}

 

'Zakłócenia' w ledach:

https://drive.google.com/open?id=1QA2Wg8q1anRekhdTkNUD7RIxWk9jZTti

Działanie programu (poprawne) po podłączeniu do gniazda 3.3V:

https://drive.google.com/open?id=1CV-jUsaqsalOMdBLTAd84nwKSHKiUk68

Działanie programu (niepoprawne) po podłączeniu do zasilacza:

https://drive.google.com/open?id=1Yyemh7ctmwDty9uMz2tqsFLr7tYMRuwt

Kod programu:

#include <MIDI.h> 
#include <Adafruit_NeoPixel.h>


Adafruit_NeoPixel pStrip = Adafruit_NeoPixel(88, A0, NEO_GRB + NEO_KHZ800);     //sets for LED strip 
                                                          //88 LEDs and A0 pin in arduino

int colorR = 0;             //set amount of red
int colorG = 255;             //set amount of green
int colorB = 0;             //set amount of blue

int pBegin = 21;              //pitch (first)       //in my case 21
int pEnd = 88 + pBegin;       //pitch (last)         //in my case 108
int pNote = 0;                //piano note

MIDI_CREATE_DEFAULT_INSTANCE();

void setup() {
  MIDI.begin(MIDI_CHANNEL_OMNI); 
  MIDI.setHandleNoteOn(MyHandleNoteOn); 
  MIDI.setHandleNoteOff(MyHandleNoteOff);

  pStrip.begin();
  pStrip.show();
  pStrip.setBrightness(50);

  pNote = pBegin;
}

void loop() { 
  MIDI.read(); 
}

void MyHandleNoteOn(byte channel, byte pitch, byte velocity) { 
  while (pNote <= pEnd){
    int Pitch = MIDI.getData1();
    int Velocity = MIDI.getData2();
    int Channel = MIDI.getChannel();
    
    if (Pitch == pNote){          //take the note from pitch
      
      pStrip.setPixelColor(pNote - 21 , pStrip.Color(colorR,colorG,colorB));      //on i-1 LED set white color
      pStrip.show();
    }
    
    pNote++;
  }
  pNote = pBegin;
}

void MyHandleNoteOff(byte channel, byte pitch, byte velocity) {       //if ANY of the notes has been turned off
  while (pNote <= pEnd){
    int Pitch = MIDI.getData1();
    int Velocity = MIDI.getData2();
    int Channel = MIDI.getChannel();
    if (Pitch == pNote){        //take the note from Pitch

      pStrip.setPixelColor(pNote - 21 , pStrip.Color(0,0,0));      //on i-1 LED set 'black' color
      pStrip.show();
    }
    pNote++;
  }
  pNote = pBegin;
}

 

Z góry dziękuję za pomoc.

Link do komentarza
Share on other sites

Dołącz do dyskusji, napisz odpowiedź!

Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!

Anonim
Dołącz do dyskusji! Kliknij i zacznij pisać...

×   Wklejony jako tekst z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Twój link będzie automatycznie osadzony.   Wyświetlać jako link

×   Twoja poprzednia zawartość została przywrócona.   Wyczyść edytor

×   Nie możesz wkleić zdjęć bezpośrednio. Prześlij lub wstaw obrazy z adresu URL.

×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.