ドラムマシーンを足で演奏することを目指しています。
手で演奏するプロトタイプを作成しました。
・arduino uno
・SparkFun midiシールド
・leapmotion
・node.js
・CASIO キーボード CTK-530
Image may be NSFW.
Clik here to view.
Image may be NSFW.
Clik here to view.
leapmotionとarduinoでシリアル通信
参考サイト:
ArduinoとNode.jsでシリアル通信で文字列を送受信するスクリプト
ArduinoとLeapmotionのシリアル接続
まずはleapmotion側(node.js)
準備物は↑を参照願います。
leap-arduino.js
"use strict"constserialport=require('serialport');// arduinoポート名指定(arduino IDEから取得)varportName='/dev/cu.usbmodem1421';/* jsライブラリ読込 */varLeap=require("leapjs");varfive=require('johnny-five');varyPosi=0;//座標varG_KICK_TIME=newDate();//センサーキック時刻varC_WAITE_TIME=100;//ミリ秒//Leap Motionコントローラー作成varcontroller=newLeap.Controller();//leapmotionと接続開始controller.connect();//手を認識controller.on('hand',function(gesture,e){//y軸取得yPosi=gesture.palmPosition[1];yPosi=parseInt(yPosi);varss=newDate();//前回のarduino送信からの時間比較if(ss.getTime()-G_KICK_TIME.getTime()>=C_WAITE_TIME){//C_WAITE_TIME経過した場合//arduino通信発生時刻G_KICK_TIME=newDate();console.log("ON");//arduinoへ送信する関数write(yPosi);}});constReadline=serialport.parsers.Readline;constparser=newReadline();constspp=newserialport(portName,{baudRate:31250,//midiのボーレートが31250dataBits: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へ送信functionwrite(data){//y軸座標の範囲で値を設定;varsendData;if(data>0&&data<=160){//スネアドラムsendData='a';}elseif(data>160&&data<=200){//ハイハットclosesendData='b';}elseif(data>200&&data<=250){//ハイハットopensendData='c';}else{//上記以外sendData='0';}data=sendData;//送信データ表示console.log('Mac:'+data);//arduinoへ値送信!spp.write(newBuffer.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
intrecieveByte=0;StringbufferStr="";StringokStr="OK";//送信ONフラグconstboolC_ON=true;constboolC_OFF=false;//ノート情報constintC_NOTE_VEROCITY=40;constintC_NOTE_CHANNEL=1;boolbLedState=false;//受信状態 true:on false:offintpitchNo=0;voidsetup(){Serial.begin(31250);//midiのボーレートが31250MIDI.begin();// MIDIインスタンスの初期化}voidloop(){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;//スネア}elseif(String(bufferStr)=="b"){bLedState=C_ON;pitchNo=44;//ハイハットclose}elseif(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からこのセンサーに変更します。
記事は着手次第アップします。