arduino + leapmotion でmidi ドラム Play!

ドラムマシーンを足で演奏することを目指しています。
手で演奏するプロトタイプを作成しました。
>・arduino uno
>・SparkFun midiシールド
>・leapmotion
>・node.js
>・CASIO キーボード CTK-530

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/534084/1bdc08c1-cdd2-76ec-cffd-d98675ae1979.jpeg"  width=50% />
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/534084/d4af66ef-2143-1f16-7b09-6c89613c69b4.jpeg"  width=50% />

<h2>leapmotionとarduinoでシリアル通信</h2>
参考サイト:
<a href="https://qiita.com/sifue/items/69d8a6f56671588ce1ba" target="_blank" >ArduinoとNode.jsでシリアル通信で文字列を送受信するスクリプト</a>
<a href="http://sssignal.web.fc2.com/column/column17.html" target="_blank" >ArduinoとLeapmotionのシリアル接続</a>

まずはleapmotion側(node.js)
準備物は↑を参照願います。

```leap-arduino.js
"use strict"
const serialport = require('serialport');
// arduinoポート名指定(arduino IDEから取得)
var portName = '/dev/cu.usbmodem1421';
/* jsライブラリ読込 */
var Leap = require("leapjs");
var five = require('johnny-five');
var yPosi = 0; //座標
var G_KICK_TIME = new Date();//センサーキック時刻
var C_WAITE_TIME = 100; //ミリ秒
//Leap Motionコントローラー作成
var controller = new Leap.Controller();
//leapmotionと接続開始
controller.connect();
//手を認識
controller.on('hand', function (gesture,e) {
  //y軸取得
  yPosi = gesture.palmPosition[1];
  yPosi = parseInt(yPosi);
  var ss = new Date();
  //前回のarduino送信からの時間比較
  if(ss.getTime() - G_KICK_TIME.getTime() >= C_WAITE_TIME  ){
    //C_WAITE_TIME経過した場合
    //arduino通信発生時刻
    G_KICK_TIME = new Date();
    console.log("ON");
    //arduinoへ送信する関数
    write(yPosi);
  }
});
const Readline = serialport.parsers.Readline;
const parser = new Readline();
const spp = new serialport(portName,{
    baudRate: 31250,//midiのボーレートが31250
    dataBits: 8,
    parity: 'none',
    stopBits: 1,
    flowControl: false,
    parser: parser
});
//シリアル通信開始
spp.on('open', function () {
  console.log('Serial open.');
});
//arduinoから受信した場合の処理(今回は未使用)
//spp.on('data', function (data) {
//  //console.log('spp.on-data:' + data);
//});
//arduinoへ送信
function write(data) {
  //y軸座標の範囲で値を設定;
  var sendData;
  if (data > 0 && data <= 160){
    //スネアドラム
    sendData = 'a';
  } else if (data > 160 && data <= 200){
    //ハイハットclose
    sendData = 'b';
  } else if (data > 200 && data <= 250){
    //ハイハットopen
    sendData = 'c';
  } else {
    //上記以外
    sendData = '0';
  }
  data = sendData;
  //送信データ表示
  console.log('Mac:' + data);
  //arduinoへ値送信!
  spp.write(new Buffer.from(data), function(err, results) {
    if(err) {
      //エラーメッセージ表示
      console.log('Err: ' + err);
    }
  });
}
```
続いてarduino側です。
参考サイト
<a href="https://qiita.com/yudai220/items/3bde9461f282d56d1ac2" target="_blank" >Arduino MIDI Library の使い方</a>

手をかざすとC_WAITE_TIMEの間隔でCASIOキーボードのドラムを鳴らします。

```c
//MIDIライブラリ使用のためのヘッダファイル読み込み
#include <MIDI.h> 
// MIDIクラスのインスタンスとして"MIDI"を生成する。
MIDI_CREATE_DEFAULT_INSTANCE(); 
#define LED 13
int recieveByte = 0;
String bufferStr = "";
String okStr = "OK";
//送信ONフラグ
const bool C_ON = true;
const bool C_OFF = false;
//ノート情報
const int C_NOTE_VEROCITY = 40;
const int C_NOTE_CHANNEL = 1; 

bool bLedState = false; //受信状態 true:on false:off
int pitchNo = 0; 

void setup() {
  Serial.begin(31250);   //midiのボーレートが31250
  MIDI.begin();          // MIDIインスタンスの初期化
}
void loop() {
  bufferStr = ""; 
  while (Serial.available() > 0) {
    recieveByte = Serial.read();
    if (recieveByte == (int)'\n') break;
    bufferStr.concat((char)recieveByte);
  }
  
  //受信信号実行中の場合無視して次へ 
  if(bLedState == C_OFF){
    //受信データによりCASIOキーボードへMIDI送信
    if (bufferStr.length() > 0) {        
        if (bufferStr == "a") {
            bLedState = C_ON;
            pitchNo = 38;//スネア
        } else if (String(bufferStr) == "b") {
            bLedState = C_ON;
            pitchNo = 44;//ハイハットclose
        } else if (String(bufferStr) == "c") {
            bLedState = C_ON;
            pitchNo = 46;//ハイハットopen
        } else {
          bLedState = C_OFF;
          pitchNo = 36;//バスドラ
        }
        //ノートオン(pitch, velocity, channel)
        MIDI.sendNoteOn(pitchNo, C_NOTE_VEROCITY, C_NOTE_CHANNEL);
        //待機後信号受付状態にする
        bLedState = C_OFF;
        MIDI.sendNoteOff(pitchNo, C_NOTE_VEROCITY, C_NOTE_CHANNEL);       
    }
  }
}
```

MIDIのボーレートの既定値が31250のため、シリアル通信もそれに合わせています。

そうしないとarduino側で受信データが文字化けしてしまいます。
これでハマりました。

スイッチサイエンスで距離計測センサーを購入したので、届き次第leapmotionからこのセンサーに変更します。

記事は着手次第アップします。