ムジュラの仮面のようなお面をつくりたい【前編】

## ムジュラの仮面23周年おめでとう
2000年にNINTENDO64のゲームソフトとして発売された「ゼルダの伝説　ムジュラの仮面」。当時小学生だった私は、月が落ちてくるのが怖すぎて、クロックタウンからストーリーを進められませんでした...。それからNintendo Switchで遊べるようになり、大人になっても怖い感情はそのままに全ての仮面とお面を揃えるまで夢中になってプレイしました。

<img height="50%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/986141/ca177bb3-74b7-bce2-a1ed-ade5950c2b90.png">
任天堂公式HPより

## オリジナルお面をつくりたい！
ということで私が考えたお面はその名も、
 **「まっくらのお面」** 
お面をかぶったら辺りが真っ暗になります。工程は以下の通り。
1. お面をかぶる
1. それを検知し通知する
1. 電気を消す
1. 仮面が光る

この記事は前編で、工程1と2を実施します。

## アイテム
- どこかで手に入れたお面
- obniz Board 1Y
- 超音波距離センサ
- LED2つ
- Node.js (ver 20.8.1)
- line/bot-sdk (ver 8.0.1)

<img height="50%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/986141/5f960bf6-f0fa-4e5f-ed72-7b1e35fa78a7.jpeg">



## 開発
### まずは電子工作
<img height="50%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/986141/c5a343a0-746d-1eac-2c28-8b8938304e0d.jpeg">

obnizに超音波距離センサとLEDをつなぎます。超音波距離センサが大きいので、ブレッドボードを使っています。LEDは、理想は目の部分に付けたいのですが今回は動作の確認のため同じブレッドボードに乗せています。

そしてお面にベタンと！
<img height="50%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/986141/10810aa9-00d9-d563-2821-bb2e2c6d0ed5.jpeg">

お面が曲面だしどうやって収納したらよいかわかりませんが、深く考えず一旦これでOKです。

### obnizの操作
obnizを画面の指示に従いWi-Fiに接続します。
超音波センサと物体の距離が200mm未満になるとLEDライトがつくような条件でコーディングしていきます。
<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/986141/33c9b888-195b-1aa0-d98e-103d49ffb889.gif">


<details><summary>実装例</summary>

```js
'use strict';

const Obniz = require('obniz');
const obniz = new Obniz('Obniz_ID'); // Obniz_IDに自分のIDを入れます

obniz.onconnect = async function () {
  // 超音波測距センサを利用する
  const hcsr04 = obniz.wired('HC-SR04', { gnd: 0, echo: 1, trigger: 2, vcc: 3 });
  // LEDの設定
  const led1 = obniz.wired("LED", {anode:8, cathode:9});
  const led2 = obniz.wired("LED", {anode:10, cathode:11});
  // ディスプレイ
  obniz.display.clear();

  // setIntervalで一定間隔で処理
  setInterval(async function () {
    // 距離を取得
    let distance = await hcsr04.measureWait();
    distance = Math.floor(distance);

    // 距離(mm)をターミナルに表示
    console.log(distance + ' mm');
    // obnizディスプレイに表示
    // 一度消してから距離+mmの単位を表示
    obniz.display.clear();
    obniz.display.print(distance + ' mm');

    // 距離が200mm未満かどうかの判定
    if (distance < 200) {
      obniz.display.clear();
      // LEDをつける
      led1.on();
      led2.on();
    } else {
    led1.off();
    led2.off();
    }
  }, 1000); // 1000ミリ秒おきに実行
}
```
</details>

続いて同じ条件でLINE botの方にも通知が来るようにします。
今回はお面ですが仮面をかぶった時の悲鳴が通知されるようにします。
<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/986141/dc73437a-4342-42f3-e751-5286840c4e93.gif">
<details><summary>実装例</summary>

```js
'use strict';

const Obniz = require('obniz');
const obniz = new Obniz('Obniz_ID'); // Obniz_IDに自分のIDを入れます

const line = require('@line/bot-sdk');
const config = {
    channelSecret: process.env.CHANNEL_SECRET || 'CHANNEL_SECRET',
    channelAccessToken: process.env.CHANNEL_ACCESS_TOKEN || 'CHANNEL_ACCESS_TOKEN',
  };
const client = new line.messagingApi.MessagingApiClient(config);

// LINEのメッセージ
const pushMessage = async () => {
    const messages = [{
        type: 'text',
        text: 'うわああああああああああああああああああ'
    }];

    try {
        const res = await client.broadcast({messages}); 
        console.log(res);       
    } catch (error) {
        console.log(error.statusMessage);
    }
}

obniz.onconnect = async function () {
  // 超音波測距センサを利用する
  const hcsr04 = obniz.wired('HC-SR04', { gnd: 0, echo: 1, trigger: 2, vcc: 3 });
  // LEDの設定
  const led1 = obniz.wired("LED", {anode:8, cathode:9});
  const led2 = obniz.wired("LED", {anode:10, cathode:11});
  // ディスプレイ
  obniz.display.clear();
  // setIntervalで一定間隔で処理
  setInterval(async function () {
    // 距離を取得
    let distance = await hcsr04.measureWait();
    distance = Math.floor(distance);
    // 距離(mm)をターミナルに表示
    console.log(distance + ' mm');
    // obnizディスプレイに表示
    // 一度消してから距離+mmの単位を表示
    obniz.display.clear();
    obniz.display.print(distance + ' mm');

    // 距離が200mm未満かどうかの判定
    if (distance < 200) {
      obniz.display.clear();
      // LEDをつける
      led1.on();
      led2.on();
      pushMessage();
    } else {
    led1.off();
    led2.off();
    }
  }, 1000); // 1000ミリ秒おきに実行
}

```
</details>

## 前編終了
お面を装着するとそれを検知するところまではできました。
あとは部屋の電気を消すところと部品をうまく隠せばOKですね。
obnizは今回初めて触りましたが、つまずく部分が少なく非常に使いやすかったです。
 **今回は動作確認のためにLINEとの連携をしましたが、実際に作中に出てくるあのお面もつくれるかも...と思いました！**
それではまた後編をお楽しみに！！