obnizで反射神経を鍛えておばあちゃんの健康寿命を延ばす

## 昨年末90歳の大叔母が寝たきりになってしまいました
原因は**転倒による大腿骨骨折**でした。
高齢者にとって**足の骨折は命取り**。寝たきりになると、認知症が進行するケースが多いと病院で聞かされました。以前は一人暮らしをするほど元気でしたが、施設に入所することが決まりました。

すると今度は**80歳のおばあちゃんも転倒により骨折**。転んだ時にうまく手をつけず、腕の骨が折れてしまいました。

腕の骨だったのが不幸中の幸いでしたが、おばあちゃんもいつ足の骨を折るかわかりません。老化による骨の劣化までは止められませんが、せめて転んだ時にすぐに手をつけるよう、**おばあちゃんの反射神経を鍛えて健康寿命を延ばすことはできないか。**

そんな思いで作ったプロダクトが**こちら:information_desk_person:**

## 反射神経鍛える君
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">反射神経鍛える君<a href="https://twitter.com/hashtag/protoout?src=hash&amp;ref_src=twsrc%5Etfw">#protoout</a> <a href="https://twitter.com/hashtag/obniz?src=hash&amp;ref_src=twsrc%5Etfw">#obniz</a> <a href="https://t.co/VrPH784hDM">pic.twitter.com/VrPH784hDM</a></p>&mdash; 新米SEちーろってぃ@新婚💍 (@chiiirotty) <a href="https://twitter.com/chiiirotty/status/1653049196008857600?ref_src=twsrc%5Etfw">May 1, 2023</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

## 使ったもの
今回は**ユーザの使用感を見てプロダクトの改善を図りたい**と考えているので、簡単にIoTプロトタイプを作ることができる**obniz**を使用しました。
使用したパーツは[スピーカー](https://docs.obniz.com/ja/sdk/parts/Speaker/README.md)と[LED信号](https://docs.obniz.com/ja/guides/obniz-starter-kit/use-parts/led-traffic-ligth)です。
<img width="400" alt="S__38354948.jpg]" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2958610/fd5772ef-5a61-7192-aab2-a43b547c9e35.jpeg">

プログラミングはローコードツールの**Node-RED**(Railwayでデプロイ)を使用しています。

## 実装！
Node-REDにて以下のようなフローを作成しました。インポートして利用できるJSONも併せて載せておきます！

### フロー図
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2958610/5b3a3359-1f28-587f-4bea-261bcd4e2bc3.png)

### JSON
```JSON:JSON
[{"id":"b89aa97ba32885de","type":"tab","label":"フロー 1","disabled":false,"info":"","env":[]},{"id":"cb1d6d3a.017e1","type":"debug","z":"b89aa97ba32885de","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":490,"y":320,"wires":[]},{"id":"11a346f0.5a4c19","type":"obniz-function","z":"b89aa97ba32885de","obniz":"","name":"","code":"function beep_finish() {\n    obnizParts.Speaker.play(1661);\n    obniz.wait(100);\n    obnizParts.Speaker.play(1397);\n    obniz.wait(100);\n    obnizParts.Speaker.play(1661);\n    obniz.wait(100);\n    obnizParts.Speaker.play(1397);\n    obniz.wait(100);\n    obnizParts.Speaker.play(1661);\n    obniz.wait(100);\n    obnizParts.Speaker.play(1397);\n    obniz.wait(100);\n    obnizParts.Speaker.stop();\n}\n\nmsg.payload = \"finish\"; \nbeep_finish();\nawait obniz.wait(1000); \nobniz.close();\n\nreturn msg;","x":320,"y":320,"wires":[["cb1d6d3a.017e1"]]},{"id":"76e43759.3dff68","type":"inject","z":"b89aa97ba32885de","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":140,"y":320,"wires":[["11a346f0.5a4c19"]]},{"id":"5fa9057f.f2e0ac","type":"obniz-repeat","z":"b89aa97ba32885de","obniz":"","name":"スピーカーを鳴らす処理","interval":"500","code":"msg.payload = await obniz.switch.getWait();\nvar color = flow.get('light_color');\n\nfunction beep_ok() {\n    obnizParts.Speaker.play(1760);\n    obniz.wait(100);\n    obnizParts.Speaker.play(1397);\n    obniz.wait(200);\n    obnizParts.Speaker.stop();\n    obniz.display.clear();\n    obniz.display.print('OK');\n}\n\nfunction beep_ng() {\n    obnizParts.Speaker.play(554);\n    obniz.wait(400);\n    obnizParts.Speaker.stop();\n    obniz.display.clear();\n    obniz.display.print('NG');\n}\n    \nif (msg.payload == 'left' && color == 'green') {\n    beep_ok();\n} else if (msg.payload == 'push' && color == 'yellow') {\n    beep_ok();\n} else if (msg.payload == 'right' && color == 'red') {\n    beep_ok();\n} else {\n    beep_ng();\n}\n\nreturn msg;","x":130,"y":100,"wires":[["a9f13b125adf7385"]]},{"id":"ebafa559.00b978","type":"obniz-function","z":"b89aa97ba32885de","obniz":"","name":"緑を0.5秒光らせる","code":"obnizParts.Keyestudio_TrafficLight.green.on();\r\nobniz.wait(500);\r\nobnizParts.Keyestudio_TrafficLight.green.off();\r\nreturn msg;","x":630,"y":160,"wires":[["7e05459ad3fd30f2"]]},{"id":"a9f13b125adf7385","type":"function","z":"b89aa97ba32885de","name":"0～2の乱数生成","func":"msg.num = Math.floor(Math.random() * 3);\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":200,"y":200,"wires":[["0edca2863cfb8b09"]]},{"id":"0edca2863cfb8b09","type":"switch","z":"b89aa97ba32885de","name":"0：緑、1：黄色、2：赤","property":"num","propertyType":"msg","rules":[{"t":"eq","v":"0","vt":"num"},{"t":"eq","v":"1","vt":"num"},{"t":"eq","v":"2","vt":"num"}],"checkall":"true","repair":false,"outputs":3,"x":410,"y":200,"wires":[["ebafa559.00b978"],["056a6b688ad59698"],["4924219050bcb73a"]]},{"id":"056a6b688ad59698","type":"obniz-function","z":"b89aa97ba32885de","obniz":"","name":"黄を0.5秒光らせる","code":"obnizParts.Keyestudio_TrafficLight.yellow.on();\r\nobniz.wait(500);\r\nobnizParts.Keyestudio_TrafficLight.yellow.off();\r\nflow.light_color = 'yellow';\r\nreturn msg;","x":630,"y":200,"wires":[["f1482d093f396868"]]},{"id":"4924219050bcb73a","type":"obniz-function","z":"b89aa97ba32885de","obniz":"","name":"赤を0.5秒光らせる","code":"obnizParts.Keyestudio_TrafficLight.red.on();\r\nobniz.wait(500);\r\nobnizParts.Keyestudio_TrafficLight.red.off();\r\nflow.light_color = 'red';\r\nreturn msg;","x":630,"y":240,"wires":[["fc7f328505e1a928"]]},{"id":"7e05459ad3fd30f2","type":"change","z":"b89aa97ba32885de","name":"light_color変数代入(緑)","rules":[{"t":"set","p":"light_color","pt":"flow","to":"green","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":840,"y":160,"wires":[[]]},{"id":"f1482d093f396868","type":"change","z":"b89aa97ba32885de","name":"light_color変数代入(黄)","rules":[{"t":"set","p":"light_color","pt":"flow","to":"yellow","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":840,"y":200,"wires":[[]]},{"id":"fc7f328505e1a928","type":"change","z":"b89aa97ba32885de","name":"light_color変数代入(赤)","rules":[{"t":"set","p":"light_color","pt":"flow","to":"red","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":840,"y":240,"wires":[[]]},{"id":"decfb1e918d894a0","type":"comment","z":"b89aa97ba32885de","name":"↓ノードを停止させる処理","info":"","x":170,"y":280,"wires":[]}]
```
### ルール
以下の操作をしたときを「**正解**」とし、「**ピンポン！**」音を鳴らします。
- **緑信号**が光ったときにobnizのスイッチを**左**に倒す
- **黄信号**が光ったときにobnizのスイッチを**押す**
- **赤信号**が光ったときにobnizのスイッチを**右**に倒す

それ以外の操作は「**不正解**」とし、「**ブー**」音を鳴らします。

### ロジック
1. **0**、**1**、**2**をランダムに生成
2. **0だったら緑**、**1だったら黄**、**2だったら赤**の信号を光らせ、光った信号の色を**light_color**フロー変数に保持させる
3. 以下の場合「**ピンポン！**」音を鳴らし、それ以外は「**ブー**」音を鳴らす
    - light_color変数が**green**のとき、スイッチが**左**に倒されている
    - light_color変数が**yellow**のとき、スイッチが**押されている**
    - light_color変数が**red**のとき、スイッチが**右**に倒されている

:::note info
obnizのスイッチの値を受け取る処理は**obniz-repeat**ノードで行う必要があったため、本来フローの最後にあるべき**ロジック3**の処理をフロー冒頭の**スピーカーを鳴らす処理**内で行っています。
:::

<details><summary>スピーカーを鳴らす処理のコードはこちら:information_desk_person:</summary>

```JavaScript:JavaScript
msg.payload = await obniz.switch.getWait();
var color = flow.get('light_color');

function beep_ok() {
    obnizParts.Speaker.play(1760);
    obniz.wait(100);
    obnizParts.Speaker.play(1397);
    obniz.wait(200);
    obnizParts.Speaker.stop();
    obniz.display.clear();
    obniz.display.print('OK');
}

function beep_ng() {
    obnizParts.Speaker.play(554);
    obniz.wait(400);
    obnizParts.Speaker.stop();
    obniz.display.clear();
    obniz.display.print('NG');
}
    
if (msg.payload == 'left' && color == 'green') {
    beep_ok();
} else if (msg.payload == 'push' && color == 'yellow') {
    beep_ok();
} else if (msg.payload == 'right' && color == 'red') {
    beep_ok();
} else {
    beep_ng();
}

return msg;
```
</details>

## おばあちゃんの反射神経は鍛えられるのか！？
今回は実際に御年80歳のおばあちゃんに**反射神経鍛える君**を使ってもらいます:older_woman:
<img width="400" alt="S__38313987.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2958610/7c753116-2a84-37ee-295f-4d180e541db5.jpeg">

おばあちゃんの反射神経が鍛えられたかどうかは、[棒落とし(反射神経)テスト](https://www.police.pref.osaka.lg.jp/material/files/group/2/try_1.pdf)(大阪府警察HP)の結果で確認します。
**反射神経鍛える君**を使う前と後で結果が向上すれば、**反射神経鍛える君**のトレーニング効果を実証できたといえるでしょう！

## 実験！
### 1. 棒落としテスト(挑戦前)
3回挑戦したうち、2回は失敗してしまいました。
成功した1回の**23cm**を挑戦前の記録とします。
<img width="300" alt="S__38313991.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2958610/222ed853-d9a1-fe88-7d72-2a868896e682.jpeg">

### 2. **反射神経鍛える君**に挑戦:older_woman:
数回に分けて5分間ほど挑戦してもらいました。
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">おばあちゃん(80歳)の挑戦👵<a href="https://twitter.com/hashtag/protoout?src=hash&amp;ref_src=twsrc%5Etfw">#protoout</a> <a href="https://twitter.com/hashtag/obniz?src=hash&amp;ref_src=twsrc%5Etfw">#obniz</a> <a href="https://twitter.com/hashtag/%E5%8F%8D%E5%B0%84%E7%A5%9E%E7%B5%8C%E9%8D%9B%E3%81%88%E3%82%8B%E5%90%9B?src=hash&amp;ref_src=twsrc%5Etfw">#反射神経鍛える君</a> <a href="https://t.co/uLt3fk5oHi">pic.twitter.com/uLt3fk5oHi</a></p>&mdash; 新米SEちーろってぃ@新婚💍 (@chiiirotty) <a href="https://twitter.com/chiiirotty/status/1653275644472741889?ref_src=twsrc%5Etfw">May 2, 2023</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

### 3. 棒落としテスト(挑戦後)
3回のうち**2回成功**！記録も**8cm**と、挑戦前の23cmから**15cm向上**しました:raised_hands:
<img width="300" alt="S__38313989.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2958610/339ec3e2-299a-620b-ad96-1e55a7b6f90b.jpeg">

実験の結果より、**反射神経鍛える君**には一定程度**反射神経を鍛える効果**があることがわかりました:clap:

## 被験者(おばあちゃん)の感想
:older_woman:「**結構面白かった**」とのことでした！
プロダクトのサービス向上のため、改善点のフィードバックをいただきました！

### ①:older_woman:「スイッチが動かしにくかった」
高齢者になると手が乾燥するため、**obnizのスイッチが滑って動かしにくかった**ようです。スイッチ部分に**高齢者が動かしやすくなる工夫**をする必要がありそうです。

### ②:older_woman:「ゲームの結果によって脳年齢がわかるとよい」
**スコアが出て自分の成長がわかると良いのではないか**とのことでした。
**正解数に応じてスコアを出す**機能は検討しましたが、うまく実装することができませんでした。ゲーム性があれば楽しく続けてもらえると思うので、引き続き実現できる方法がないか調査を進めます！

### ユーザ:older_woman:の生の声を聞く
プロトタイプを作り、ターゲットとするユーザに使ってもらうことで、**作っているときには気が付かなかったユーザのニーズを知ることができました。**
今後も机上のアイデアだけでものづくりをするのではなく、**ユーザの生の声を聞く姿勢**を大切にしたいと思います！