2
1

More than 3 years have passed since last update.

arduino + leapmotion でmidi ドラム Play!

Last updated at Posted at 2020-03-22

ドラムマシーンを足で演奏することを目指しています。
手で演奏するプロトタイプを作成しました。

・arduino uno
・SparkFun midiシールド
・leapmotion
・node.js
・CASIO キーボード CTK-530


leapmotionとarduinoでシリアル通信

参考サイト:
ArduinoとNode.jsでシリアル通信で文字列を送受信するスクリプト
ArduinoとLeapmotionのシリアル接続

まずは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側です。
参考サイト
Arduino MIDI Library の使い方

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

//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からこのセンサーに変更します。

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

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1