Lesson: How to loop

同じ処理を繰り返す方法

overview

サーボモーターを左右に動かしたりなど、
繰り返しながら順番に何かをしたいときはあります。
通常は無限ループを作成してその中で処理を行います。
そのやり方を見てみましょう

obnizで同じ処理を繰り返す方法はいくつかあります

  1. setTimeout, setIntervalを使う
  2. obniz.repeat()を使う
  3. while(true)とobniz.wait()を使う

1. setTimeout, setIntervalを使う

Javascriptの言語にはそもそも同じ処理を繰り返すのに便利な関数があります。

  1. setTimeout・・・指定した時間後に関数を実行
  2. setInterval・・・指定した時間ごとに関数を実行

この2つです。
一定間隔である処理をするのであればsetIntervalが便利です。

setInterval(function(){
  // every second
}, 1000)

このように書くと、// every secondとかかれた場所が1秒ごと(1000ミリ秒ごと)に呼ばれます。
これを使って一定間隔でサーボモーターに手をふるような動きをさせてみましょう。

<!-- HTML Example -->
<html>
<head>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <script src="https://obniz.io/js/jquery-3.2.1.min.js"></script>
  <script src="https://unpkg.com/obniz@1.14.1/obniz.js"></script>
</head>
<body>

<div id="obniz-debug"></div>
<h1>obniz instant html</h1>

<script>
  var obniz = new Obniz("OBNIZ_ID_HERE");
  obniz.onconnect = async function () {
    var servo = obniz.wired("ServoMotor", {gnd:0, vcc:1, signal:2});
    var angle = 0;
    setInterval(async function(){
      servo.angle(angle);
      if (angle == 0) {
        angle=90;
      } else {
        angle=0;
      }
    }, 1000);
  }
</script>​
</body>
</html>

このようになります。
1秒ごとに

servo.angle(angle);
if (angle == 0) {
  angle=90;
} else {
  angle=0;
}

の部分が呼ばれます。
servoにangleで角度を指定します。
その後にangleが0なら90に、angleが0じゃなかったら0にします。
そうすると、次に(1秒後に)またこの関数が呼ばれたときにはサーボモーターは違う角度になります。

2. obniz.repeatを使う

上記setIntervalですと、obnizとの接続が切れてもintervalが止まらない問題があります。
そこで、obnizには接続が切れたら自動的に停止するようにしてあるsetIntervalのような関数が用意してあります。

それがrepeat()です

obniz.repeat(function(){
  // called repeatedly
}, 1000)

repeatに渡した関数は繰り返し実行されます。
その上obnizとの接続が切れたら自動的に止まります。
これをつかうとこのように書けます。

<!-- HTML Example -->
<html>
<head>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <script src="https://obniz.io/js/jquery-3.2.1.min.js"></script>
  <script src="https://unpkg.com/obniz@latest/obniz.js"></script>
</head>
<body>

<div id="obniz-debug"></div>
<h1>obniz instant html</h1>

<script>
  var obniz = new Obniz("OBNIZ_ID_HERE");
  obniz.onconnect = async function () {
    var servo = obniz.wired("ServoMotor", {gnd:0, vcc:1, signal:2});
    var angle = 0;
    obniz.repeat(async function(){
      servo.angle(angle);
      if (angle == 0) {
        angle=90;
      } else {
        angle=0;
      }
    }, 1000);
  }
</script>​
</body>
</html>

3. while(true)とobniz.wait

obnizには一定期間処理を停止する関数が用意されています。

led.on();
await obniz.wait(1000);
led.off();

このように書くことでledを1秒だけonにすることができます。
while(true)の無限ループと組み合わせることで以下のように書くことができます。

<!-- HTML Example -->
<html>
<head>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <script src="https://obniz.io/js/jquery-3.2.1.min.js"></script>
  <script src="https://unpkg.com/obniz@latest/obniz.js"></script>
</head>
<body>

<div id="obniz-debug"></div>
<h1>obniz instant html</h1>

<script>
  var obniz = new Obniz("OBNIZ_ID_HERE");
  obniz.debugprint=true;
  obniz.onconnect = async function () {
    var servo = obniz.wired("ServoMotor", {gnd:0, vcc:1, signal:2});
    while(true){
      servo.angle(0);
      await obniz.wait(1000);
      servo.angle(90);
      await obniz.wait(1000);
    }
  }
</script>​
</body>
</html>

とてもスッキリと書くことが出来ました。
しかしこれもsetIntervalなどと同じく、obnizとの接続が切れた時には
自分からこの無限ループを抜けることが必要になってきます。