obnizで、”連続測定した距離の差分”　を利用してできること　～体の揺れを測定～

距離センサーを利用して何ができるか考えていた時に、
「背もたれを2度と使わせないセンサー」
https://twitter.com/yusei2629/status/1404791349795299332?s=20
の記事を見て、距離センサーの有用性を感じ、
”連続測定した距離の差分”が体の揺れを測定できるのではないかと考え、居眠り防止などに応用が利くかもしれないと思い、幾つか作ってみました。

下準備
①　obnizスターターキットの用意
②　obnizの端子にパーツを接続
　　　LED信号：gnd:0, green:1, yellow:2, red:3
　　　距離センサー：gnd:4, echo:5, trigger:6, vcc:7
　　　ブザー：signal:9, vcc:10, gnd:11

　※LED信号とブザーは隣り合わせで無理やり入れている感じになります。
　　壊れないように注意してください。

実行
　obniz HTMLエディタを開き、以下のコードを入力。


```html
//【obniz 動きが小さくなったら知らせる】ver.1
//動かないとブザーが鳴る。
<html>
  <head>
    <script src="https://unpkg.com/obniz@3.x/obniz.js"></script>
  </head>
  <body>
    <script>
      var obniz = new Obniz("OBNIZ_ID_HERE"); // ここに自身のobniz IDを入力する

      obniz.onconnect = async function () { 
        var speaker = obniz.wired("Keyestudio_Buzzer", {signal:9, vcc:10, gnd:11});
        var hcsr04 = obniz.wired("HC-SR04", {gnd:4, echo:5, trigger:6, vcc:7});
        var light = obniz.wired("Keyestudio_TrafficLight", {gnd:0, green:1, yellow:2, red:3});

        let i =0;
        while(true){
          i++;

          if (i > 3600) {
            speaker.stop();
            break;
          }

            light.single("green"); // green ⇒1回目の距離測定
            await obniz.wait(100);
            light.green.off();
          const d1 = await hcsr04.measureWait(); // awaitを利用
            await obniz.wait(5000);

            light.single("yellow"); // yellow ⇒2回目の距離測定
            await obniz.wait(100);
            light.yellow.off();
          const d2 = await hcsr04.measureWait(); // awaitを利用
            await obniz.wait(5000);

          const distance = d1-d2  //1回目と2回目の距離の差分
          console.log(distance);

          if (distance < 20 && distance > -20 ) { // -20～20mm
            speaker.play(261.626) // 261.626 Hz；「次のド」
            await obniz.wait(200);
            speaker.stop();
            continue;
          } else if (distance < 30 && distance > -30 ) { // -30～-20mm、20～30mm
            speaker.play(130.813) // 130.813 Hz；「ド」
            await obniz.wait(200);
            speaker.stop();
            continue;
          } else { // -30m以下、30mm以上
            await obniz.wait(10);
            speaker.stop();
            continue;
          }
        }
      }
    </script>
  </body>
</html>
```


```html
//【obniz 動きが小さくなったら知らせる】ver.2
//動かないとブザーが鳴る。
<html>
  <head>
    <script src="https://unpkg.com/obniz@3.x/obniz.js"></script>
  </head>
  <body>
    <script>
      var obniz = new Obniz("OBNIZ_ID_HERE"); // ここに自身のobniz IDを入力する

      obniz.onconnect = async function () { 
        var speaker = obniz.wired("Keyestudio_Buzzer", {signal:9, vcc:10, gnd:11});
        var hcsr04 = obniz.wired("HC-SR04", {gnd:4, echo:5, trigger:6, vcc:7});
        var light = obniz.wired("Keyestudio_TrafficLight", {gnd:0, green:1, yellow:2, red:3});

        let i =0;
        while(true){
          i++;

          if (i > 3600) {
            speaker.stop();
            break;
          }
            // 1回目の距離測定
            light.single("green"); // green
          const d1 = await hcsr04.measureWait(); // awaitを利用
            await obniz.wait(100);
            light.green.off();
            await obniz.wait(2000);

            // 2回目の距離測定
          const d2 = await hcsr04.measureWait(); // awaitを利用
          await obniz.wait(2000);

            // 3回目の距離測定
          const d3 = await hcsr04.measureWait(); // awaitを利用

          const v1 = d1-d2  //1回目と2回目の距離の差分
          console.log("v1 " + v1 + " mm");
          const v2 = d2-d3  //2回目と3回目の距離の差分
          console.log("v2 " + v2 + " mm");
          const v3 = d1-d3  //1回目と3回目の距離の差分
          console.log("v3 " + v3 + " mm");

          if (v1 < 1 && v1 > -1 ) { // -1～1mm
            if (v2 < 1 && v2 > -1 ) { // -1～1mm
              if (v3 < 1 && v3 > -1 ) { // -1～1mm
                speaker.play(261.626) // 261.626 Hz；「次のド」
                light.single("red"); // red
                await obniz.wait(200);
                speaker.stop();
                light.red.off();
                continue;
              }else if (v3 < 5 && v3 > -5 ) { // -1～-5mm、1～5mm
                speaker.play(130.813) // 130.813 Hz；「ド」
                light.single("yellow"); // yellow
                await obniz.wait(200);
                speaker.stop();
                light.yellow.off();
                continue;
              }else{
                continue;
              }
            }else if (v2 < 5 && v2 > -5 ) { // -1～-5mm、1～5mm
              if (v3 < 5 && v3 > -5 ) { // -1～-5mm、1～5mm
                speaker.play(130.813) // 130.813 Hz；「ド」
                light.single("yellow"); // yellow
                await obniz.wait(200);
                speaker.stop();
                light.yellow.off();
                continue;
              }else {
                continue;
              }
            }else{
              continue;
            }

          } else if (v1 < 5 && v1 > -5 ) { // -1～-5mm、1～5mm
            if (v2 < 5 && v2 > -5 ) { // -1～-5mm、1～5mm
              if (v3 < 5 && v3 > -5 ) { // -1～-5mm、1～5mm
                speaker.play(130.813) // 130.813 Hz；「ド」
                light.single("yellow"); // yellow
                await obniz.wait(200);
                speaker.stop();
                light.yellow.off();
                continue;
              }else {
                continue;
              }
            }else {
              continue;
            }
            
          } else { // -30m以下、30mm以上
            await obniz.wait(10);
            speaker.stop();
            continue;
          }
        }
      }
    </script>
  </body>
</html>
```

```html
//【obniz 動きが大きくなったら（動いたら）知らせるコード】
//上2つとは逆に動くとブザーが鳴る。
<html>
  <head>
    <script src="https://unpkg.com/obniz@3.x/obniz.js"></script>
  </head>
  <body>
    <script>
      var obniz = new Obniz("OBNIZ_ID_HERE"); // ここに自身のobniz IDを入力する

      obniz.onconnect = async function () { 
        var speaker = obniz.wired("Keyestudio_Buzzer", {signal:9, vcc:10, gnd:11});
        var hcsr04 = obniz.wired("HC-SR04", {gnd:4, echo:5, trigger:6, vcc:7});
        var light = obniz.wired("Keyestudio_TrafficLight", {gnd:0, green:1, yellow:2, red:3});

        let i =0;
        while(true){
          i++;

          if (i > 3600) {
            speaker.stop();
            break;
          }

            light.single("green"); // green ⇒1回目の距離測定
            await obniz.wait(100);
            light.green.off();
          const d1 = await hcsr04.measureWait(); // awaitを利用
            await obniz.wait(1000);

            light.single("yellow"); // yellow ⇒2回目の距離測定
            await obniz.wait(100);
            light.yellow.off();
          const d2 = await hcsr04.measureWait(); // awaitを利用
            await obniz.wait(1000);

          const v1 = d1-d2  //1回目と2回目の距離の差分
          console.log(v1);

          if (v1 > 50 || v1 < -50 ) { // -50mm以下、50mm以上
            speaker.play(130.813) // 130.813 Hz；「ド」
            await obniz.wait(200);
            speaker.stop();
            continue;
          } else if (v1 > 30 || v1 < -30 ) { // -30～-50mm、30～50mm
            speaker.play(261.626) // 261.626 Hz；「次のド」
            await obniz.wait(200);
            speaker.stop();
            continue;
          } else { // -30以上、30mm以下
            await obniz.wait(10);
            speaker.stop();
            continue;
          }
        }
      }
    </script>
  </body>
</html>
```

https://twitter.com/21HideK/status/1451401421870403591

工夫を要した箇所
　①何も動かしていない状態でも、それぞれの測定誤差は0～5mm程度生じる。
　　体の揺れの幅の程度をどの程度にするか、試行錯誤した。

　②ver.2では、連続する2秒間のそれぞれの誤差、4秒間の誤差を測定し、何れかの誤差が
　　大きいときを検出するようにした。

⇒実際に、どの程度の誤差を良い程度とするかは、今後も検討を要する。
　洋服だとしわにより距離が正確には測りづらい。平らな薄い板を測定する体の箇所に
　張り付けることにより、より正確に測定ができる。

応用できるもの
　動きが小さくなったら（動かなかったら）知らせるものは「居眠り防止」等に
　動きが大きくなったら（動いたら）知らせるものは「姿勢保持の体操」「座禅」
　「動いてはいけないゲーム等に　応用できるかもしれない。

　その他、体の揺れが大きくなる疾患（失調、不随意運動など）、体の揺れが小さくなる疾患（パーキンソン病など）の数値化ができ、診断の補助とすることができるかもしれない。