これでいわく付き物件も大丈夫⁈　obnizを使って幽霊検知器を作りました（いい歳して恥ずかしげもなく堂々と･･･）。

## こんな感じでできあがりました！
いかついロボットみたいな感じがしますが、実物は 4cm×4cm×3cm で結構コンパクトにできあがっています。左横の筒は菓子箱から手製しました。何に使うかは後ほどで。
![obniz幽霊検知器3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2887131/9a5a449c-a619-b096-59db-c5bb8167e1c7.jpeg)
《材料》
　・obnize Board 1Y
　・抵抗内蔵5mmLED 5V 赤色640nm OSR6LU5B64A-5V
　・Ｃｄｓセル 5mmタイプ（光センサー）
　・圧電スピーカー（圧電サウンダ）（13mm）PKM13EPYH4000-A0
　・超音波距離センサー HC-SR04
　・ミニブレッドボード BB-601（白）
　・ブレッドボード・ジャンパーワイヤ（オス－オス） 10cmセット
　・カーボン抵抗（炭素皮膜抵抗） 1/2　１／２Ｗ３３０Ω
《環境》
　・Node-RED（Heroku）
　・Javascript
動かすとこんな風になります。右下の動画をご覧ください。

https://youtube.com/shorts/JoF176JMKL8?feature=share

## 機能概要
超音波距離センサーの前に何かが現れると反応して赤色LEDを光らせて警告のブザーを鳴らします。幽霊は基本昼間は出ませんので（何事にも例外はありますが）、光センサーで明るいうちは何かを検知してもスルーするようにしています。
余談ですが、obnize Board 1Y にはワイヤーの差込口が12個あり、その内の11個を使った作品です。

## Node-REDのフロー
![obniz工作のフロー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2887131/519438d6-812a-c970-cf8f-b251e53d3528.png)
`1)距離センサーによる判定について`
・取得した距離は整数まるめをしています。
・msg.payload はデバッグ出力用に使いたかったので、msg.kyori を定義しました。
・距離センサーは動画撮影の都合で50mm以内に入れば検知する設定です。
```Javascript:
msg.payload = await obnizParts.hcsr04.measureWait();

obniz.display.clear(); // クリア
obniz.display.print('Ready');

// 距離を取得
let distance = msg.payload;
// そのままだと小数点以下の桁数がやたら多いので整数に丸めてもよい
distance = Math.floor(distance);

msg.payload = (distance + ' mm');
msg.kyori = distance;

// obnizディスプレイに表示
// 一度消してから距離+mmの単位を表示
obniz.display.clear();
obniz.display.print(distance + ' mm');
// 距離がある程度未満かどうかの判定
if (distance < 50) { // 50mm = 5cm 以下の場合
    // obnizディスプレイに近接していることを表示
    obniz.display.clear();
    obniz.display.print('Too close!!');
}

return msg;
```
`2)光センサーによる判定について`
・上記と同じく、別に msg.hikari を定義しました。
```Javascript:
var voltage = await obniz.ad1.getWait();

obniz.display.print(voltage)
msg.hikari = voltage;
msg.payload = (msg.kyori + ' mm　' + msg.hikari + ' v');
//obniz.display.clear();
//obniz.display.print(msg.kyori + ' mm　' + msg.hikari + ' v');

return msg;
```
・初期設定は同じフロー内の全てのノードに共通のため、必要な機器は全て定義を行いました。

```Javascript:

obniz.display.clear(); // 画面を消去

obniz.io0.output(true); //io0を5vに
obniz.io2.output(false); //io2をGNDに

obnizParts.hcsr04 = obniz.wired("HC-SR04",{ gnd:4, echo:5, trigger:6, vcc:7 });
obniz.display.clear(); // 画面を消去
obnizParts.led = obniz.wired('LED', { anode:10, cathode:11 });
obniz.display.clear(); // 画面を消去
obnizParts.Speaker = obniz.wired("Speaker",{ signal:8, gnd:9 });
```
`3)検知した場合の対応について`
・実は else節が不要というか無駄です。ここでは止めることができません。
```Javascript:
// 条件を満たす間は光って鳴らす
if (msg.kyori < 50 && msg.hikari < 0.2 ) { 
    obnizParts.led.on();
    obnizParts.Speaker.play(1000); // 1000Hz で音を鳴らす
} else {
    obnizParts.led.off();
    obnizParts.Speaker.stop(); // 音をとめる
}

return msg;
```
`4)ソースコード`
```
[{"id":"6daf22566dbff7e1","type":"debug","z":"dbc7e1d46cad4881","name":"はよ逃げや！","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":880,"y":340,"wires":[]},{"id":"ca35fa0d18c1db56","type":"obniz-function","z":"dbc7e1d46cad4881","obniz":"6256c18fc41720c2","name":"幽霊発見処理","code":"// 条件を満たす間は光って鳴らす\nif (msg.kyori < 50 && msg.hikari < 0.2 ) { \n    obnizParts.led.on();\n    obnizParts.Speaker.play(1000); // 1000Hz で音を鳴らす\n} else {\n    obnizParts.led.off();\n    obnizParts.Speaker.stop(); // 音をとめる\n}\n\nreturn msg;","x":720,"y":260,"wires":[["6daf22566dbff7e1"]]},{"id":"0118fd503cba285c","type":"switch","z":"dbc7e1d46cad4881","name":"昼夜判定","property":"hikari","propertyType":"msg","rules":[{"t":"gte","v":"0.2","vt":"str"},{"t":"else"}],"checkall":"true","repair":false,"outputs":2,"x":580,"y":200,"wires":[["b61e81c7232a640a"],["ca35fa0d18c1db56"]]},{"id":"82343e51fdaf90d1","type":"obniz-function","z":"dbc7e1d46cad4881","obniz":"6256c18fc41720c2","name":"光センサー入力","code":"var voltage = await obniz.ad1.getWait();\n\nobniz.display.print(voltage)\nmsg.hikari = voltage;\nmsg.payload = (msg.kyori + ' mm　' + msg.hikari + ' v');\n//obniz.display.clear();\n//obniz.display.print(msg.kyori + ' mm　' + msg.hikari + ' v');\n\nreturn msg;","x":480,"y":120,"wires":[["0118fd503cba285c"]]},{"id":"b61e81c7232a640a","type":"debug","z":"dbc7e1d46cad4881","name":"昼は大丈夫","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":770,"y":200,"wires":[]},{"id":"affa1a865e09065c","type":"switch","z":"dbc7e1d46cad4881","name":"何かいる判定","property":"kyori","propertyType":"msg","rules":[{"t":"gte","v":"50","vt":"str"},{"t":"else"}],"checkall":"true","repair":false,"outputs":2,"x":320,"y":40,"wires":[["e4a4791ff9ee095b"],["82343e51fdaf90d1"]]},{"id":"263a0fe195df1ce5","type":"obniz-repeat","z":"dbc7e1d46cad4881","obniz":"6256c18fc41720c2","name":"距離センサー入力","interval":"500","code":"msg.payload = await obnizParts.hcsr04.measureWait();\n\nobniz.display.clear(); // クリア\nobniz.display.print('Ready');\n\n// 距離を取得\nlet distance = msg.payload;\n// そのままだと小数点以下の桁数がやたら多いので整数に丸めてもよい\ndistance = Math.floor(distance);\n\nmsg.payload = (distance + ' mm');\nmsg.kyori = distance;\n\n// obnizディスプレイに表示\n// 一度消してから距離+mmの単位を表示\nobniz.display.clear();\nobniz.display.print(distance + ' mm');\n// 距離がある程度未満かどうかの判定\nif (distance < 50) { // 50mm = 5cm 以下の場合\n    // obnizディスプレイに近接していることを表示\n    obniz.display.clear();\n    obniz.display.print('Too close!!');\n}\n\nreturn msg;","x":110,"y":40,"wires":[["affa1a865e09065c"]]},{"id":"e4a4791ff9ee095b","type":"debug","z":"dbc7e1d46cad4881","name":"何もいない","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":530,"y":40,"wires":[]},{"id":"6256c18fc41720c2","type":"obniz","obnizId":"","deviceType":"obnizboard1y","name":"","accessToken":"","code":"obniz.display.clear(); // 画面を消去\r\nobnizParts.LM60 = obniz.wired(\"LM60\",{ gnd: 0, output: 1, vcc: 2 }); // 温度センサー"}]
```
こちらは終了処理のもの
```
[{"id":"b6a1b411e3204b56","type":"debug","z":"dbc7e1d46cad4881","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":630,"y":460,"wires":[]},{"id":"501e93e647302770","type":"obniz-function","z":"dbc7e1d46cad4881","obniz":"6256c18fc41720c2","name":"","code":"msg.payload = \"finish\";\nawait obniz.wait(1000); \nobniz.close();\n\nreturn msg;","x":440,"y":460,"wires":[["b6a1b411e3204b56"]]},{"id":"6009d847648ee60e","type":"inject","z":"dbc7e1d46cad4881","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":240,"y":460,"wires":[["501e93e647302770"]]},{"id":"6256c18fc41720c2","type":"obniz","obnizId":"","deviceType":"obnizboard1y","name":"","accessToken":"","code":"obniz.display.clear(); // 画面を消去\r\nobnizParts.LM60 = obniz.wired(\"LM60\",{ gnd: 0, output: 1, vcc: 2 }); // 温度センサー"}]
```
## 最後に
素直に防犯対策の空き巣検知器としてもよかったのですが、まぁその辺は私の性格ということで。実は、検知してLEDを点灯してブザーを鳴らした後にLINEメッセージをスマホに送りたかったのです。空き巣検知器なら必須の機能ですね。幽霊検知器でも別の部屋で寝ている家族に助けに来てほしいので必要です。今後のバージョンアップです。今回は複数のセンサー入力が使えるとわかったのが収穫でした。