2011年5月8日日曜日

ArduinoでMIDI Libraryを使い、MIDI INをするメモ

ArduinoでMIDIシールドMIDI Libraryを使い、MIDI入力する時のメモです。
MIDI OUTの例はネット上で結構見つかったのですが、MIDI INの例があまりなかったので例を記します。

実験用ハードウェアはこちらです。Arduino UnoとMIDIシールド、表示デバイスに2行16桁のLCDをつけてあります。

MIDIから入ってきた信号をLCDに表示するだけの単純な機能ですが、MIDI入力を扱う上で基本的な実験が出来ると思います。
MIDIのチャンネルは1~16chまでありますが、A0のボリュームで選択します。

LCDの表示の意味は、写真のとおりです。
NoteOn・・・鍵盤を押した時のデータです。ノートNoは音階、ベロシティは音量を示します
NoteOff・・・鍵盤を話した時のデータです。
音色番号・・・楽器の音色の種類です。数値は0~127です。
音程・・・音階の間の音程を表現するときに使います。数値は -8192 ~ +8191です。

詳しい解説は、こちら 詳説MIDI規格
MIDI信号には、他にもたくさんのメッセージが送れますが、簡単な楽器を作るにはとりあえずこれだけで十分でしょう。


このプログラムにはMIDI Libraryが必要です。Arduinoインストールフォルダのlibrariesフォルダに展開しソフトを再起動することで使用できます。また、サンプルプログラムでは、MIDI Library v3.0で動作確認をしています。

参考ページ : ISHの物置小屋

これを適当に改良して新しい楽器を作っちゃえばいーじゃないっ!

#include <LiquidCrystal.h>
#include <MIDI.h>

//ピン設定
#define D7 4
#define D6 5
#define D5 6
#define D4 7
#define Enb 8
#define RW 9
#define RS 10

#define analogPin 0

//初期化===========================================================
int Ch = 0;
LiquidCrystal lcd(RS,RW,Enb,D4,D5,D6,D7);

void setup()
{
  MIDI.begin();

  //LCD
  lcd.clear();
  lcd.begin(16, 2);
}

void loop()
{
 //チャンネル選択
 int beforCh = Ch;
 Ch = analogRead(analogPin);
 Ch = (Ch / 64 ) + 1;
 if(beforCh != Ch){
    lcd.setCursor(0,0);
   lcd.print(Ch,OCT);
  lcd.print(" ");
 }

 uint8_t data1,data2;
 if (MIDI.read()) {
  MIDI.setInputChannel(Ch); //読み込むチャンネルを設定

    switch(MIDI.getType()) {
   case NoteOn:  //鍵盤を押す
    data1 = MIDI.getData1(); // ノートNo.(音階)
    data2 = MIDI.getData2(); // ベロシティ(音の強さ)

    lcd.setCursor(3,0);
    lcd.print(data1,HEX);
    lcd.setCursor(6,0);
    lcd.print(data2,HEX);
   break;
   case NoteOff:  //鍵盤を離す
    data1 = MIDI.getData1(); // ノートNo.(音階)
    data2 = MIDI.getData2(); // ベロシティ(音の強さ)

    lcd.setCursor(9,0);
    lcd.print(data1,HEX);
    lcd.setCursor(12,0);
    lcd.print(data2,HEX);
   break;
   case ProgramChange: //音色の切り替え
    data1 = MIDI.getData1(); //プログラムNo.(音色)

    lcd.setCursor(0,1);
    lcd.print(data1,HEX);
   break;
   case PitchBend:  //音程(ピッチ)
    data1 = MIDI.getData1(); // MSB
    data2 = MIDI.getData2(); // LSB
    
    int Pitch = data2;
    Pitch = Pitch * 128 + data1 - 8192;
    
    lcd.setCursor(3,1);
    lcd.print(Pitch);
    lcd.print("    ");
   break;

  }
 }
}