超音波センサーで近点距離を計測し、老眼か判定するLINE Bot×IoTの作成

##概要
以前、老眼とモスキート音による加齢性難聴をチェックするLINE Bot×Iotを作成しました。
[老眼と加齢性難聴のチェックができるLINE Bot×Iotの作成](https://qiita.com/doikatsuyuki/items/fb14483b69a3d3202bed)

前回は近点距離（人差し指の指紋が一番鮮明に見える距離）は実際にメジャーで計測してLINEに数値を入力していましたが、今回は、超音波センサーで近点距離を自動計測しました。機能も老眼判定のみに絞ったBotをobnizと組み合わせて作成しました。
##実装
LINE BOtとobnizの連携。近点（人差し指の指紋が一番鮮明に見える）でLINEに入力すると自分が老眼かどうかが分かるBOT。
##概念図
node.js expressでLINE bot APIとobnizを連携しました。
![rougann.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/453374/c6992a6f-b0c9-466c-9301-ca0b66cd5bb1.jpeg)
##作成方法
**1.obnizの準備**
obnizをPCと接続します。 
[obniz公式サイト](https://obniz.io/ja/) 
[Node.jsのダウンロード](https://nodejs.org/ja/download/) 

obnizを使えるようにWifiに接続し、画面上にQRコードと8桁の数字が表れるようにします。

超音波センサーを準備し、obnizのio0・io1・i02にさします。 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/453374/15a7abd9-f313-d4cf-45c6-535462087939.png)
今回は、超音波距離センサー　ＨＣ－ＳＲ０４ [101-60-142 / 20-019-100-A]を使用しました。


[超音波センサーのドキュメント](https://obniz.io/ja/sdk/parts/HC-SR04/README.md )


**2. Botアカウントを作成する**

**3. Node.jsでBot開発**

**4. ngrokでトンネリング**

上記の2～4を以下の参考記事の通りに行います。
[1時間でLINE BOTを作るハンズオン (資料+レポート) in Node学園祭2017 ](https://qiita.com/n0bisuke/items/ceaa09ef8898bee8369d)

**5.obnizとの連携**

コードを以下のように書き換えます。

```js
'use strict';

const express = require('express');
const line = require('@line/bot-sdk');
const PORT = process.env.PORT || 3000;

const config = {
    channelSecret: '自分のchannelSecretを入力',
    channelAccessToken: '自分のchannelAccessTokenを入力'
};

// Obnizの準備
var Obniz = require("obniz");
var obniz = new Obniz("自分のObniz ID を入力");  // Obniz ID を入力
//超音波センサー
var hcsr04;//全体に使えるようにするスコープ
obniz.onconnect = async function () {
  hcsr04 = obniz.wired("HC-SR04", { gnd: 0, echo: 1, trigger: 2, vcc: 3 });
  
  
}

console.log("hcsr04 sample!");


const app = express();

app.get('/', (req, res) => res.send('Hello LINE BOT!(GET)')); //ブラウザ確認用(無くても問題ない)
app.post('/webhook', line.middleware(config), (req, res) => {
  console.log(req.body.events);
  
  //ここのif分はdeveloper consoleの"接続確認"用なので削除して問題ないです。
  if(req.body.events[0].replyToken === '00000000000000000000000000000000' && req.body.events[1].replyToken === 'ffffffffffffffffffffffffffffffff'){
    res.send('Hello LINE BOT!(POST)');
    console.log('疎通確認用');
    return; 
  }
  
  Promise
      .all(req.body.events.map(handleEvent))
      .then((result) => res.json(result));
});


    
const client = new line.Client(config);

function handleEvent(event) {
  if (event.type !== 'message' || event.message.type !== 'text') {
    return Promise.resolve(null);
  }

  // LINE botのプログラム
// 聞いてくる間はHTTP APIで取得するように取得待ちが生じる
getDistance(event.source.userId);

return client.replyMessage(event.replyToken, {
  type: 'text',
  text: 'ちょっとまってね。いま距離調べてる。'
});
}

const getDistance = async (userId) => {

  // 処理が待てるmeasureWaitのほうを使う
  let res;
  const dis_mm = await hcsr04.measureWait();
  const dis_cm = dis_mm / 10;
  const distance = dis_cm.toFixed(); 
  
  if (distance>=80) {
    res =" 近点距離は" + distance + "cm です。ピント調整力は61歳以上相当です。老眼の可能性が高いです。老眼度数は3以上と思われます。";
  }else if (distance >= 60){
    res = "近点距離は" + distance + "cm です。ピント調整力は56～60歳相当です。老眼の可能性が高いです。老眼度数は2.5程度と思われます。。";
  }else if (distance >= 50){
    res = "近点距離は" + distance + "cm です。ピント調整力は51～55歳相当です。老眼の可能性が高いです。老眼度数は2程度と思われます。";
  }else if(distance >= 40){
    res = "近点距離は" + distance + "cm です。ピント調整力は46～50歳相当です。老眼の可能性が高いです。老眼度数は1.5程度と思われます。";
     }else if(distance >= 30){
    res = "近点距離は" + distance + "cm です。ピント調整力は41～45歳相当です。老眼の可能性が高いです。老眼度数は1程度と思われます。";
  } else if(distance<30) {
    res = "近点距離は" + distance + "cm です。ピント調整力は40歳未満相当です。老眼の可能性は低いです。";
  }else {
    res = "指先にピントが合い、人差し指の指紋がはっきりと見えたところでLINEに何かメッセージを送ってください。";
  }

  
  await client.pushMessage(userId, {
      type: 'text',
      text: res,
  });
}


app.listen(PORT);
console.log(`Server running at ${PORT}`);

```
##動作確認
ちゃんと動いています。
<img width="375" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/453374/970f12ee-bc2f-9970-83d2-a810b36bb076.png">

##考察
超音波センサーは対象が柔らかいと正確に距離を測定できないということだったので心配でしたが、メジャーで計測して比較すると誤差は数㎝ほどでした。スマートフォンのカメラで距離が取得できるとUIがずっと良くなるので何か方法はないか調べてみたいと思います。