ラジコンをリッチメニューから遠隔操作する。自動ブレーキ付き

#やったこと
前回作成した[【obniz×LINE Messaging API】音と光を使い侵入防止システムを製作する](https://qiita.com/Toshiki0324/items/6ac09efe6ac6ed0102e6)の時に使用したタッパを乗せて走らせてみました。

#できたもの
LINEのリッチメニューから操作でき、10㎝以内に障害物があると自動で停止します。
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">obniz×LINEBOTを使用して操作するラジコンを製作しました。自動ブレーキを搭載しています。<a href="https://t.co/E6R6lLIpXR">https://t.co/E6R6lLIpXR</a><a href="https://twitter.com/hashtag/obniz?src=hash&amp;ref_src=twsrc%5Etfw">#obniz</a> <a href="https://t.co/Vbud1nzxXd">pic.twitter.com/Vbud1nzxXd</a></p>&mdash; Toshiki (@Hirasawa1987) <a href="https://twitter.com/Hirasawa1987/status/1288467978913067008?ref_src=twsrc%5Etfw">July 29, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>


#構成


##全体像
今回製作したシステムの全体像です。
[![Image from Gyazo](https://i.gyazo.com/ae176898cce2d7c17d7a9cf0a017e016.png)](https://gyazo.com/ae176898cce2d7c17d7a9cf0a017e016)

##配線図
obnizの配線図です。
![Untitled Sketch2_ブレッドボード.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206019/20fad979-4e03-b2e7-ad05-535542c934aa.png)


##使用部品
- obniz Board 1Y
    - https://obniz.io/ja/products/obnizboard1y/
    - 6,300円(税抜)

- シャープ測距モジュール　ＧＰ２Ｙ０Ａ２１ＹＫ
    - http://akizukidenshi.com/catalog/g/gI-02551/
    - 450円(税込)
- 2輪ロボットスマートカー
    - https://www.amazon.co.jp/gp/product/B07DPLCQN8/
    - 1,699円(税込)
- 100均のタッパー
- USB タイプCのUSB2.0ケーブル(家にあったものを使用) 
- モバイルバッテリー(家にあったものを使用)

##環境
- node.js　v14.5.0
- @line/bot-sdk 7.0.0
- express 4.17.1
- obniz 3.7.0

#コード
```index.js
'use strict';

// obniz呼び出し
const Obniz = require('obniz');
const obniz = new Obniz('××××-××××'); // Obniz_IDに自分のIDを入れます
const line = require("@line/bot-sdk");
const express = require("express");
const PORT = process.env.PORT || 3030;

const config = {
  channelSecret: '{チャネルシークレット}',
  channelAccessToken: '{アクセストークン}'
};
const userId = '{ユーザーid}';


const app = express();
obniz.onconnect = async function () {
  obniz.display.clear();
  obniz.display.print('obniz meets LINE Bot!');
// モーターを呼び出す
  const motorRight = obniz.wired("DCMotor", { forward: 1, back: 0 });
  const motorLeft = obniz.wired("DCMotor", { forward: 8, back: 11 });
    // 距離センサーを呼び出す
  const GP2Y0 = obniz.wired("GP2Y0A21YK0F", {vcc:4, gnd:5, signal:6 });
  setInterval(async function () {
app.post('/webhook', line.middleware(config), (req, res) => {
    console.log(req.body.events);
    Promise
      .all(req.body.events.map(handleEvent))
      .then((result) => res.json(result));
});

const client = new line.Client(config);

function forward_command() {
    motorLeft.forward();
    motorRight.forward();
  }
  function stop_command() {
    motorLeft.stop();
    motorRight.stop();
  }
  function reverse_command() {
    motorLeft.reverse();
    motorRight.reverse();
  }
  function turning() {
    motorLeft.forward();
    motorRight.reverse();
  }

  const distance = await GP2Y0.getWait();
  console.log(distance + ' mm');

  function handleEvent(event) {
    if (event.type !== 'message' || event.message.type !== 'text') {
      return Promise.resolve(null);
    }
    switch(event.message.text) {
      case '前進':
        client.replyMessage(event.replyToken, {
          type: 'text',
          text: '前進します'
        });
        forward_command();
      break;

      case '停止':
        client.replyMessage(event.replyToken, {
          type: 'text',
          text: '停止しました'
        });
        stop_command();
        break;

        case '後退':
          client.replyMessage(event.replyToken, {
            type: 'text',
            text: '後退します'
          });
          reverse_command();
          break;

        case 'ダンス':
          client.replyMessage(event.replyToken, {
            type: 'text',
            text: '踊ります'
          });
          turning();
          break;
      }


  }


  if(distance < 100){
    // setTimeout(function () {
    //   client.pushMessage(userId, {
    //   type: 'text',
    //   text: '障害物を検知しました',
    //   });
    // },1000);
    stop_command();
  }
}, 1000);
}
app.listen(PORT);
console.log(`Server running at ${PORT}`);
```
#参考にした記事
LINEmessagingAPIの基礎部分で参考にしました。
[1時間でLINE BOTを作るハンズオン (資料+レポート) in Node学園祭2017 #nodefest](https://qiita.com/n0bisuke/items/ceaa09ef8898bee8369d)


#終わりに
[公式サイト](https://blog.obniz.io/en/example/)のラジコン類はスマートに動いていて次回の目標となります、できるかどうかはわかりませんが、次に作るときはカメラで画像認識を使用して走行させてみたいと思います。今回購入したキットは、格安品でまっすぐ進むよう調整するのが大変でした。