【IchigoJam web】7セグ8の字ぐるぐる

「7セグ8の字ぐるぐる」とは、以下のように、7セグメントLEDを8の字を描くようにぐるぐると点灯させることである。

![7セグ8の字ぐるぐる](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99656/cc27d298-03f2-cd78-a370-b9a87beb34e9.gif)

(あれ、実際の8の字の書き順とは逆回りか…でも今回はこの仕様でいきます)
(と思ったら、[銀行などでこの書き方をする場合もある](https://ameblo.jp/akamaru-soroban/entry-11989456836.html)…？)

# IchigoJam web の7セグメントLED

[IchigoJam web](https://fukuno.jig.jp/app/IchigoJam/) では、右上に7セグメントLEDを模した表示があり、以下のポートを指定した `OUT` 命令で操作できる。

![IchigoJam web の7セグメントLED](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99656/abb5dd2c-84bb-27e0-50f6-c65650848cd7.png)

# WAIT命令とTICK()関数の時間の単位

IchigoJam web においては、`TICK()` 関数や `WAIT` 命令で用いられる時間の単位が通常 (1/60秒 =「1」) とは異なり、これらの機能を用いたプログラムの動作に影響があることが知られている。
そこで、実際にどのくらい遅いのかを調べてみた。

プログラム

```
BEEP:WAIT20:BEEP:WAIT40:BEEP
```

を実行すると、`BEEP` により3回音が鳴る。
そして、「2つ目の音が鳴り始めてから3つ目の音が鳴り始めるまでの時間」から「1つ目の音が鳴り始めてから2つ目の音が鳴り始めるまでの時間」を引くと、`BEEP` の実行にかかる時間と「20」分の `WAIT` にかかる時間が消え、40 - 20 = 「20」分の `WAIT` にかかる時間が求まることが期待できる。

得られた音を録音し、増幅すると、以下の結果が得られた。

![観測結果](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99656/25ab6e0f-97af-f100-5a31-8e6b41334b5c.png)

|音|鳴り始めた時刻|
|---|---|
|1つ目|1.112秒|
|2つ目|2.626秒|
|3つ目|5.421秒|

「2つ目の音が鳴り始めてから3つ目の音が鳴り始めるまでの時間」は 2.795秒
「1つ目の音が鳴り始めてから2つ目の音が鳴り始めるまでの時間」は 1.514秒
それらの差は 1.281秒
20で割って、「1」に相当する時間は**約0.064秒 (1/15.625秒)** であることがわかった。

これは、なんと通常 (「1」= 1/60秒) より3.84倍も遅いことになる。
にもかかわらず、[1秒の TICK() 値を返すとされている](https://github.com/fu-sen/IchigoJam-BASIC/blob/master/VER.txt) `VER(4)` は `60` を返すのである。**嘘つき。**
いや、これは `TICK()` のことであって、`WAIT` はたまたま似た単位を使っているだけで関係ないか…？
と思って

```
CLT:WAIT60:?TICK()
```

を実行すると、「45」と表示された。

```
CLT:WAIT120:?TICK()
```

を実行すると、「90」と表示された。

**いやむしろ `TICK()` の時間の単位のほうがもっと遅いんかい！！**

IchigoJam web の `TICK()` で用いられている時間の単位の「1」は、`WAIT` で用いられている時間の単位の「1」の4/3倍の長さのようである。
すなわち、通常 (「1」=1/60秒) の5.12倍の遅さ、「1」= 約1/11.7秒のようである。

実際に、

```
10 CLT
20 IF TICK()<60 GOTO 20
```

を実行してみると、実行が終わるまでに5秒強かかった。

にもかかわらず、1秒の TICK() 値を返すとされている `VER(4)` は `60` を返すのである。**嘘つき！！！！！**

もちろん、`VIDEO` 命令によるクロックダウンの設定もしていない。

…それとも、公式？の以下のリファレンスにはこの機能 (`VER(4)` が1秒の TICK() 値を返す) は載っていないから、この動作は保証されていないっていうことなのかな…？

* [IchigoJam BASIC リファレンス ver 1.4](https://ichigojam.net/IchigoJam-1.4.html)
* [IchigoJam BASIC 1.4 コマンド一覧](https://fukuno.jig.jp/app/csv/ichigojam-cmd.html#VER)

# 7セグ8の字ぐるぐる

本題に戻ろう。
他の環境で試した結果より、だいたい1秒に10回くらいのペースで切り替えたい。
通常 (「1」= 1/60秒) であれば、`WAIT 6` であろう。
これを IchigoJam web の `WAIT` で用いられる時間の単位に変換すると 6÷3.84=1.5625 となる。
ichigoJam web では他の処理も**遅い**ことを考慮すると、`WAIT 1` くらいでよさそうか。

点灯させる位置の決定は、テーブルを用意して引くのが簡単である。
というわけで、プログラムを書いてみた。

```
10 LET[0],1,2,7,5,4,3,7,6
20 P=0
30 OUT [P],1
40 WAIT 1
50 OUT [P],0
60 P=(P+1)%8
70 GOTO 30
```

[実行する](https://fukuno.jig.jp/app/IchigoJam/#10%20LET%5B0%5D%2C1%2C2%2C7%2C5%2C4%2C3%2C7%2C6%0A20%20P%3D0%0A30%20OUT%20%5BP%5D%2C1%0A40%20WAIT%201%0A50%20OUT%20%5BP%5D%2C0%0A60%20P%3D(P%2B1)%258%0A70%20GOTO%2030%0ARUN%0A)

うーん…なんかチラつく気がする。
やっぱり IchigoJam web の実行が**遅い**からかな…？
点灯と消灯を1個の命令で行うようにしてみよう。

```
10 LET[0],1,2,7,5,4,3,7,6
20 P=0
30 OUT 0,1<<([P]-1)
40 WAIT 1
50 P=(P+1)%8
60 GOTO 30
```

[実行する](https://fukuno.jig.jp/app/IchigoJam/#10%20LET%5B0%5D%2C1%2C2%2C7%2C5%2C4%2C3%2C7%2C6%0A20%20P%3D0%0A30%20OUT%200%2C1%3C%3C(%5BP%5D-1)%0A40%20WAIT%201%0A50%20P%3D(P%2B1)%258%0A60%20GOTO%2030%0ARUN%0A)

うん、いい感じになった。