最近加速度センサの値に応じた音を再生する仕組みを作り続けてます。
窓を開けたときに歓喜の歌が流れる仕組みを作りました。名付けて「換気の歌」です。 pic.twitter.com/x8ku2DN2Ul
— 君塚史高 (@ki_230) 2020年6月21日
加速度が「しきい値を超えた際のイベントをキャッチ」するのであれば、MESHをつかって、さささっと作ってしまうのですが、
シェーカーを振ってる間だけ壮大なBGMが流れる仕組みを作りました。名付けて「フルオーケストラ」です。
— 君塚史高 (@ki_230) 2020年7月10日
全力で振らないと頭出しされるので、フルで聴くためには2分46秒頑張る必要があります。
心なしか、完成した完全栄養食が、いつもより神々しく感じました。 pic.twitter.com/QabfzyQufI
このように「しきい値を超え続けている際に、しきい値を下回るまで音を流す」という処理を書きたい場合は、M5StickC(obniz)をつかっています。
おそらく、MESHでもできないことはないと思うんですが、工夫するよりも愚直にプログラムを書いた方が早いという判断です。
以前、M5StickCに内蔵された加速度センサへのアクセス方法は記事にまとめましたが、今回は、「振り始めた時」と「振り終わった時」にコールバックを実行するプログラムを作ってみます。
JavaScript
const Obniz = require('obniz'); const m5 = new Obniz.M5StickC('XXXXXXXX'); // ObnizIDに差し替える const CACHE_LENGTH = 8; // 平均値に採用する加速度の数(8なら過去8回分の計測値の平均値を取る) const START_ACCELERATION = 2; // しきい値 const INTERVAL = 200; // 加速度をチェックする間隔 // 加速度収納用の配列 const qax = []; const qay = []; const qaz = []; let moveFlag = false; let i = 0; m5.onconnect = async () => { await m5.setupIMUWait(); setInterval(async () => { const acc = await m5.accelerationWait(); handleDeviceMotion( acc, () => { // 振り始めのコールバック console.log('start!'); }, () => { // 振り終わりのコールバック console.log('end!'); }); }, INTERVAL); }; function handleDeviceMotion(acc, moveCallback = () => {}, stopCallback = () => {}) { qax[i] = acc.x; qay[i] = acc.y; qaz[i] = acc.z; if (qax.length > CACHE_LENGTH - 1) { if (ave(qax) + ave(qay) + ave(qaz) > START_ACCELERATION) { if (!moveFlag) { moveFlag = true; moveCallback(); } } else { if (moveFlag) { moveFlag = false; stopCallback(); } } } i = ++i % CACHE_LENGTH; function ave(arr) { let length = arr.length; let i = length; let sum = 0; while (i--) { sum += Math.abs(arr[i]); } return sum / length; } }
ぱぱぱっと書いたコードなので雑ですが、撮影には耐えうるコードになったかなと思います。