感圧センサーを使いこなす
今回、感圧センサーを押すと、LINE Notifyに通知を出すことに挑戦しました。
動作は以下の通りです。
LINE Notifyとも連携。#protoout #デジタルヘルス学会 #deployorlose pic.twitter.com/VgQDacZG9x
— 北城雅照|プログラミングにはまったサーフィン好きの整形外科医 (@teru3_kitashiro) January 3, 2021
今後作っていきたいプロサーファーの世界を体験できるVRデバイスの肝となる部分の1つに感圧センサーがあり、今回その部分について学ぶべく、作成してみました。
感圧センサーに関しては下記の記事を参考にしました。
obnizでぬいぐるみとの握手をトリガーに
LINE Notifyとの連携は、僕の下記の記事を参考にしてください。
近すぎると小池都知事が『密です。』と連呼するデバイスを作ったら腹筋が崩壊したので、皆さんにも試して欲しい。
デバイス作り
今回用意したもの
- ブレッドボード
- Obniz
- 圧力センサーFSR406
- ジャンパワイヤ x2
作成したコード
コードのポイントは以下の通りです。
① 200ms(つまり0.2秒)ごとに感圧センサーの値を調べるループを回す
② 前回ループとの値の差=変化量を保存(値が小さいので勝手に *10 してます)
③ 前回ループまでの過去5ループ(つまり1秒分)の変化量の平均値=平均変化量を出す
④ 過去1秒の平均変化量と今回の変化量を比較して、閾値(今回は5N)を超えたらアクション発動
(アクション発動中8ループは検知しない)
'use strcit';
const axios = require('axios'); // axiosの呼び出しを追加
const qs = require('querystring'); // 送信するデータの整形
const Obniz = require('obniz');
const obniz = new Obniz('Obniz_ID'); // Obniz_IDに自分のIDを入れます
const LINE_TOKEN = 'LINE notifyのアクセストークンを入力'; // 先程取得したアクセストークンを入れます
const PRESSED_THOREHOLD = 5.0;
let pressVals = [];
let passCount = 5;
let passFlag = false;
obniz.onconnect = async () => {
obniz.display.clear();
obniz.display.print('Hello obniz!');
let pressure = obniz.wired("FSR40X", {pin0:9, pin1:10});
let rawPress = 0;
let changeDiffAbs = 0;
const config = {
url: 'https://notify-api.line.me/api/notify',
method: 'post',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': `Bearer ${LINE_TOKEN}`
},
data: qs.stringify({
message: `Take off!!!`,
})
};
obniz.repeat(async () => {
rawPress = await pressure.getWait();
changeDiffAbs = await calChangeDiffAbs(pressVals, rawPress);
if(passFlag){
await passCount--;
if(passCount <= 0){
passCount = 5;
passFlag = false;
}
obniz.display.clear();
obniz.display.print("Let's paddling.");
return;
}
if(changeDiffAbs < PRESSED_THOREHOLD || Number.isNaN(changeDiffAbs)){
obniz.display.clear();
obniz.display.print("Let's paddling.");
return;
}
//await ここでアクションを起こす関数を発動!!!!!!
obniz.display.clear();
obniz.display.print('Take off!!');
try {
// configの設定を元に送信
const response = await axios.request(config);
// データ送信が成功するとレスポンスが来る
console.log('レスポンスを受信しました:' + response.data);
console.log('POSTに成功しました!');
//await obniz.wait(10000);
} catch (error) {
// ネットワークに接続できてない、サーバーが落ちてる、URLが違うなど様々なエラー
console.log('POSTに失敗しました……');
console.error(error);
}
passFlag = true;
}, 200);
}
async function arrangeArray(arr, val){
const ARR_LIMIT_NUM = 5;
await arr.push(val);
if(arr.length > ARR_LIMIT_NUM){
await arr.shift();
}
}
async function calPrevChangeAve(arr){
let prevChanges = [];
for(let i=0; i<arr.length-1; i++){
await prevChanges.push((arr[i+1]-arr[i])/100 * 10);
}
let denoNum = prevChanges.length;
let total = await prevChanges.reduce((sum, data) => {return sum + data}, 0);
return total / denoNum;
}
async function calChangeDiffAbs(arr, val){
let prevVal = arr[arr.length-1];
let currentChange = (prevVal - val)/100 * 10;
let prevChangeAve = await calPrevChangeAve(arr);
let diff = await Math.abs(prevChangeAve - currentChange);
await arrangeArray(arr, val);
return diff;
}