M5 Fader Unitでリモコン操作して遊ぶ

前回はFader Unitの入出力を確認しました。

hollyhockberry.hatenablog.com

ちょうどIR Unitがあったのでシーリングライトの調光をしてみたいと思います。

f:id:hollyhockberry:20211024183532j:plain

リモコン操作

我が家のPC部屋で使用している照明はNECの調光付きLED照明で、こんなリモコンで操作します。

f:id:hollyhockberry:20211025205029j:plain

照明のモードは

  • 消灯
  • 明るさ1
  • 明るさ2
  • 明るさ3
  • 明るさ4
  • 明るさ5 (全灯)

で(モード名は私が適当につけました)、下記の遷移をします。

f:id:hollyhockberry:20211024193556p:plain

消灯が絡む遷移だけ特別な遷移となっていてややこしいので、フェーダーの位置に合わせて明るさ5〜明るさ1を調光することとします。

リモコンコード

赤外線リモコンの送受信には IRremoteESP8266というライブラリを利用します。名前がESP8266ですがESP32にも対応しています。

github.com

IR Unitは発光受光どちらもできるのでExamplesのIRrecvDumpV2を参考にしてリモコンから実際のコードを解析すればOKです。

ちなみに、「明」ボタンは Codeが0x41B65DA2、「暗」ボタンは Codeが 0x41B6DD22で、どちらもProtocolがNECですね。

色々実験したところ、コード送出してから照明の処理が完了するまでに70msec程度のウエイトが必要でした。
70msecのウエイトを挟んでコードを連続して送出してみましたが、問題なさそうですね。 M5StickCPlus: IR Unit sample · GitHub

フェーダー値読み取りとリモコン送信

リモコンコード送出から処理完了まで約70msecの時間がかかりますが、人間によるフェーダー操作はそんなことはお構いなしに行われます。

例えば、明るさ1の状態でフェーダーの値が最大だった場合「明」のコードを4回送る必要がありますが、ウエイトだけで280msecもかかります。
その間フェーダーの値は読むことができないし他の処理もできません。

操作感をよくするために、フェーダーの値に照明を追従する処理を別タスクで処理してみます。

リモコンコード送信タスクのやるべきことは、フェーダー読み取りのタスク(ArduinoのloopTask)から指示された照明の明るさと現在の明るさが異なる場合、必要な回数「明」ボタンか「暗」ボタンのリモコンコードを送出することです。他にやることはないので、この処理をループします。

なお、タスク毎にメモリ空間が切り替わるわけではないので、グローバルな変数へのアクセスが可能です。
照明の明るさ指示はグローバルな変数で共有することにします。(同一のファイルに実装したのでstaticな変数で実装しました)
読み取りと書き込みがどちらかのタスクでしか発生しないのでそれほどシビアに考えなくても良さそうですが、念のためセマフォ排他制御を行います。
文章で書くとなんのこっちゃ?ですがコードだとスッキリ理解できるんじゃないかと思います。

補足

わざわざ別タスクで実装しましたが、実験した例では表示も無くフェーダー値を読んで値を更新しているだけなのでそれほど意味のない感じになってしまいました。

この程度であれば、

常に最新のフェーダー値を読んで、現在の明るさと異なっていればコード送出. 

を繰り返してあげるだけでよさそうですね。

シンプルな実装で実現する場合のコードも載せておきます。シングルタスクですが、先程の例と全く同じ動きになります。