0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

micro:bitAdvent Calendar 2021

Day 18

run_everyデコレータについて

Last updated at Posted at 2021-12-18

run_everyデコレータ

新しいPythonエディタのαリリースで使える最新の MicroPython (執筆時点では 2.0.0-2021-10-25)ですが、 run_forever デコレータが使えます。

デコレータとは、関数の前につける修飾で、関数の処理の前後に処理を付け加えるものです。

たとえば次のように使います。

from microbit import display, Image, run_every

small = False

@run_every(s=1)
def heartbeat():
    global small
    if small:
        display.show(Image.HEART_SMALL)
    else:
        display.show(Image.HEART)
    small = not small

大きなハートと小さなハードが1秒おきに切り替わります。

IMG_5577.gif

while ループと何が違うか

動きをみていれば、これは s=1 で指定した秒の間隔で関数 beart の呼び出しを繰り返すものと察しがつくでしょう。

繰り返すだけであれば while ループでもできます。

from microbit import display, Image, sleep

small = False

while True:
    if small:
        display.show(Image.HEART_SMALL)
    else:
        display.show(Image.HEART)
    small = not small
    sleep(1000)

では、なぜこんなデコレータが用意されたのでしょうか。

run_everyデコレータは、MakeCodeの「ループ」にあるeveryブロックと同じ働きをします(これはまだ日本語化されてませんね)。なぜかループに分類されていますが、everyブロックが他のループブロックと違っているのは「バックグラウンド」で繰り返すことです。

スクリーンショット 2021-12-04 12.33.35.jpg

「バッググラウンド」で実行するとは、メインの処理とは独立に動作することです。つまり、メインの処理とは並行に動かせます。さらには複数のeveryブロックを並行に動かせます。run_everyデコレータは同じことが行えるので、MicroPython でも処理を並行で動かせるようになったのです。

次のもので試してみると、1秒おきに "func_1" が表示され、2秒おきに "func_2" が表示されます。

from microbit import run_every, running_time

@run_every(s=1)
def func_1():
    print(running_time(), "func_1")

@run_every(s=2)
def func_2():
    print(running_time(), "func_2")

MakeCode の「ずっと」と同じことがMicroPythonでもできる

MakeCode に「ずっと」という無限ループに相当するブロックがあり、MicroPythom では「while True」に例えられるたりしてますが、これも単なる無限ループと異なるのは」バックグラウンド」で実行されることです。

スクリーンショット 2021-12-04 12.34.58.jpg

ちょっと調べると「ずっと」内の処理を一回実行するごとに 20ms のスリープが入ることになっているようで、実際に試してもそのようになっていました。なので「ずっと」をMicroPythonで実現するには次のようにすればよいわけです。

@run_every(ms=20)
def 適当な関数名():
    何か処理

run_every の引数

run_everyデコレータには以下の引数を指定できます。組み合わせて使うこともできます。

引数名 説明 デフォルト
days 日単位で実行間隔を指定 0
h 時単位で実行間隔を指定 0
min 分単位で実行間隔を指定 0
s 秒単位で実行間隔を指定 0
ms ミリ秒単位で実行間隔を指定 0

ちなみに、なにも指定しないと実行間隔が0になり、バックグラウンドでCPU使いまくりで制御がメイン戻ってこず、何もできなくなります。対処方法としてはMicroPythonファームウェアを再インストールするしかなさそうです。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?