Arduinoを使った自動ピアノ演奏装置を作成する

# 目的
Arduino+ソレノイド+ピアノを使えば自動ピアノ演奏装置ができるのではと
思い立ち作成しました。

最終的に下記のように自動で曲を再生できました。

<blockquote class="twitter-tweet" data-lang="en"><p lang="ja" dir="ltr">家にあるarduino MIDIシールドとソレノイドを繋げました。<br><br>ミッキーマウスマーチ自動演奏 <a href="https://t.co/1wMPee5Yml">pic.twitter.com/1wMPee5Yml</a></p>&mdash; st (@st17890027) <a href="https://twitter.com/st17890027/status/1125571691545890816?ref_src=twsrc%5Etfw">May 7, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> 

# 準備
Arduino Uno
Arduino Midiシールド
Midi USB
ソレノイドコイル 6個
トランジスタ(ソレノイドコイル スイッチON/OFF用)

過去に利用したものを再利用します。
[Arduino+MIDIシールドでMIDI信号通信する](https://qiita.com/seigot/items/82979e972fd6b4318e93)
[Arduinoで２つのTone信号を同時に再生する](https://qiita.com/seigot/items/2121998f4a76c0acba3f)
[Arduinoを用いてソレノイドを動かす](https://qiita.com/seigot/items/ae8b6f9c5299c194eaab)

PC側にMidiPlayerをインストールします
ピアノは[CASIOのピアノ](https://www.amazon.co.jp/gp/product/B003KZBFIS/ref=ppx_yo_dt_b_asin_title_o02_s00?ie=UTF8&psc=1)をamazonで購入しました

# 接続図

簡単な図
<img width="160" alt="スクリーンショット 2019-06-22 19.32.05.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/344880/d30242ad-b056-dfb1-efc5-186834c12f5e.png">

接続後の図
<img width="160" alt="スクリーンショット 2019-06-22 19.32.19.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/344880/d64ce750-c1f5-bd08-c695-29baaf711400.png">


# コード
Arduino+MIDIシールド側のソースコードです。

```ruby:sample.ino
#include <MIDI.h>

// MIDI IN Channel
const int MIDI_CH = 1;

// Tones
const int CH_CNT = 2;
int intervals[CH_CNT] = {0,0};
int intervals_PIN[CH_CNT] = {0,0};

MIDI_CREATE_DEFAULT_INSTANCE();

const word noteFreq[] = {
  0,  9,  9, 10,  10, 11,   12,  12, 13, 14, 15, 15,
  16,  17, 18, 19,  21, 22,  23,  25, 26, 28, 29, 31,
  33,  35, 37,  39,  41, 44,  46, 49, 52, 55, 58, 62,
  65, 69, 73, 78,  82, 87,  93, 98, 104,  110,  117,  124,
  131, 139, 147, 156, 165, 175, 185,  196,  208,  220,  233,  247,
  262, 277, 294, 311, 330, 349, 370,  392,  415,  440,  466,  494,
  523, 554, 587, 622, 659, 699, 740,  784,  831,  880,  932,  988,
  1047, 1109, 1175, 1245, 1319, 1397, 1480, 1568, 1661, 1760, 1865, 1976,
  2093, 2218, 2349, 2489, 2637, 2794, 2960, 3136, 3322, 3520, 3729, 3951,
  4186, 4435, 4699, 4978, 5274, 5587, 5920, 6272, 6645, 7040, 7459, 7902,
  8372, 8870, 9397, 9956, 10548,11175,  11840,  12544
};

#define PIN_A 44
#define PIN_B 45
#define PIN_C 46
#define PIN_D 47
#define PIN_E 48
#define PIN_F 49

void setup()
{
 
  MIDI.begin();
  pinMode(PIN_A, OUTPUT);
  pinMode(PIN_B, OUTPUT);
  pinMode(PIN_C, OUTPUT);
  pinMode(PIN_D, OUTPUT);
  pinMode(PIN_E, OUTPUT);
  pinMode(PIN_F, OUTPUT);

  delay(500);
  digitalWrite(PIN_A, HIGH);
  delay(100);
  digitalWrite(PIN_A, LOW);
  delay(100);
  digitalWrite(PIN_B, HIGH);
  delay(100);
  digitalWrite(PIN_B, LOW);
  delay(100);
  digitalWrite(PIN_C, HIGH);
  delay(100);
  digitalWrite(PIN_C, LOW);
  delay(100);
  digitalWrite(PIN_D, HIGH);
  delay(100);
  digitalWrite(PIN_D, LOW);
  delay(100);
  digitalWrite(PIN_E, HIGH);
  delay(100);
  digitalWrite(PIN_E, LOW);
  delay(100);
  digitalWrite(PIN_F, HIGH);
  delay(100);
  digitalWrite(PIN_F, LOW);
}

void loop()
{
  uint8_t data1, data2;
  if (MIDI.read()) {
    MIDI.setInputChannel(MIDI_CH);

    switch (MIDI.getType()) {
      case midi::NoteOn:
        data1 = MIDI.getData1();    // note no
        data2 = MIDI.getData2();    // velocity
        if (data2 > 0){
          for (int i = 0; i < CH_CNT; i++){
            if (intervals[i] == 0){
              intervals[i] = data1;
              //tones[i].play(noteFreq[data1]);
              
              if (data1 == 67) { //ど
                digitalWrite(PIN_A, HIGH);
                //delay(100);
                //digitalWrite(PIN_A, LOW);
                intervals_PIN[i] = PIN_A;
              }
              if (data1 == 69) { //れ
                digitalWrite(PIN_B, HIGH);
                //delay(100);
                //digitalWrite(PIN_B, LOW);
                intervals_PIN[i] = PIN_B;
              }
              if (data1 == 71) { //み
                digitalWrite(PIN_C, HIGH);
                //delay(100);
                //digitalWrite(PIN_C, LOW);
                intervals_PIN[i] = PIN_C;
              }
              if (data1 == 72) { //ファ
                digitalWrite(PIN_D, HIGH);
                //delay(100);
                //digitalWrite(PIN_D, LOW);
                intervals_PIN[i] = PIN_D;
              }
              if (data1 == 74) { //そ
                digitalWrite(PIN_E, HIGH);
                //delay(100);
                //digitalWrite(PIN_E, LOW);
                intervals_PIN[i] = PIN_E;
              }
              if (data1 == 76) { //ら
                digitalWrite(PIN_F, HIGH);
                //delay(100);
                //digitalWrite(PIN_F, LOW);
                intervals_PIN[i] = PIN_F;
              }
             
              break;
            }
          }
        }
        break;

      case midi::NoteOff:
        data1 = MIDI.getData1();  // note no
        for (int i = 0; i < CH_CNT; i++){
          if (intervals[i] == data1){
            intervals[i] = 0;
            digitalWrite(intervals_PIN[i], LOW);
            delay(50);
            
           break;
          }
        }
        break;
    }
  }
}
```

# テスト
ミッキーマウスマーチが再生できればOK


# FAQ
MIDIデータ毎にMIDI信号とソレノイドの対応が変わることがあると思いますのでデバッグの際は注意

# 参考
[Arduino+MIDIシールドでMIDI信号通信する](https://qiita.com/seigot/items/82979e972fd6b4318e93)
[Arduinoで２つのTone信号を同時に再生する](https://qiita.com/seigot/items/2121998f4a76c0acba3f)
[Arduinoを用いてソレノイドを動かす](https://qiita.com/seigot/items/ae8b6f9c5299c194eaab)