アオカケスの鳥かご

日々の出来事を綴っていきたい

ラズパイで計算中にLチカさせたかった

pythonでのLチカや諸々の計算(処理)は検索すればたくさん出てきますが、計算中にLチカさせているような記事は見かけません。

とある仕事の中で、計算中にLEDを点滅させ、計算の結果で点灯させるLEDの色を変えるといった処理を行う必要がありました。
最初に書いたように、頑張って調べても中々良い方法が見つからなかったため、ゴリ押しで実装しました。

条件

  1. いつ終わるか分からない計算(処理)
  2. 計算中は常にLEDを点滅
  3. 計算が終わったら数秒間LEDを点灯
  4. python3

プログラムの実行イメージはこんな感じです。

f:id:aokakes:20190320213530p:plain

使えるかもしれないと思った技術たち

そもそもどのようなワードで検索すればいいのか分からない状態から調べ始め、最終的に以下のような技術を使えば上記の条件を満たすようなプログラムを実装できるかもしれないと考え、検証しました。

  • multiprocessingやJoblibを使った並列処理
  • asyncioによる非同期処理

検索ワードとしては、「並列処理」、「並行処理」、「非同期処理」、「fire and forget」、「コールバック」などでしょうか。

今回は上記の手法では条件を満たすことができませんでしたが、私が知識不足なだけで本当はできるのかもしれません。

multiprocessingやJoblibを使った並列処理

並列処理は1つの強大な敵に対して大人数で攻撃するようなイメージでしょうか。
f:id:aokakes:20190320212217p:plain

例えば、処理しなければならないデータが合計で100万個あったとき、並列処理はみんなで100万個のデータを全て処理し終わってから先に進みます。
そのため、並列処理ではデータを処理している最中にLEDを点滅させるような別の処理を行うことができません。

データを処理する前にLEDを点滅させればいいじゃないかと思う方もいるかもしれませんが、LEDを点滅させるには以下のようなプログラムを書かなければなりません。

while True:
    GPIO.output(pin, True)
    sleep(0.05)
    GPIO.output(pin, False)
    sleep(0.05)

処理するデータ総数は変動し、処理にかかる時間は分からないためfor文などで回数を指定することはできません。そもそも処理中にLチカできていないので条件を満たしていません。

asyncioによる非同期処理

非同期処理は途中の雑魚をほかの人に任せて自分はボスを倒しに行くようなイメージでしょうか。

これを知ったときは「これでいける!」と思いましたが、そう簡単にはいきませんでした。
asyncioでさきほどのコードのような関数を実行すればうまいこと動きそうなものですが、関数の中で無限ループさせるとなると思い通りには動きませんでした。

実装

計算用とLチカ用の2つプログラムを用意し、計算用のプログラムの中でLチカ用のプログラムを実行させるようにしました。
また、既に実行させたLチカ用プログラムに対して外部から色を変えるような命令をすることはできないため、LEDの状態を記述したファイルも用意することにしました。

LEDを光らせるたびにこのファイルを参照することで、LEDを点滅させ続けるのか、点灯させるのかなどを決定します。


プログラムはgithubにて。
https://github.com/fulutori/Lchika-anytime

とりあえずフィボナッチ数列を計算させている間にLチカさせてみました。
LEDを1回光らせるたびに外部のファイルを見に行くのはとても頭が悪いように見えてしかたありません。

とはいえ、今回はゴリ押してでも理想の動きをするようなプログラムを作りたかったのでしょうがない...


実行させるとこんな感じになります(配線汚いですが)。

まとめ

ゴリ押しましたが一応実装できたのでよしとします。

ゴリ押しではありますが別の機会に流用できそうな気がしないでもないですし、こんな方法もあるぐらいに捉えてもらえればと思います。