Lチカは止めたら消灯するでしょと思われた方、AWS IoT EduKit のLチカは違うんです。はい、いつ止めてもLEDが点灯したままになります。
AWS IoT EduKit のLチカは、M5Stack Core2 ESP32 IoT Development Kit for AWS の左右にあるLEDを交互に点灯させることによって、点滅が実現されています。このため、点滅を止めると、片側のLEDがつきっぱなしになるというわけです。
AWS IoT EduKitの説明では、「点滅を一時停止する(pause the blinking)」といっているだけですので、決して間違ってはいません。いつとめても片側のLEDがつきっぱなしでも、Lチカは止まっているのですから。でも、何かが違います。
なので、一時停止時に両側のLEDが消灯するように直してみました!
AWS IoT EduKit の Lチカの動き
AWS IoT EduKit の Lチカは、
- サブスクライブしているMQTTトピックを受信すると、左右にあるLEDを交互に点灯
- もう一度トピックを受信すると、一時停止
- 1.に戻る
のように動きます。交互に点灯しているのを一時停止するだけですので、片側のLEDはつきっぱなしになります。これを、タスクの処理で表すと、
-
LED点滅タスクで、
- サスペンド
- 両側のLEDを消灯(※)
- 左右のLEDを交互に点灯(これを永久に続ける)
-
MQTTタスクで、サブスクライブしているMQTTトピックを受信した時、
- LED点滅タスクがサスペンドしている時、LED点滅タスクをレジューム
- それ以外の時、LED点滅タスクをサスペンド
となります(※印の処理が必要なのかは謎です)。タスクの起床から見たい方は、AWS Iot EduKit Lチカの処理 をご覧いただければと思います。
一時停止時に両側のLEDが消灯するようにするには
MQTTタスクでLED点滅タスクをサスペンドするのをやめて、LED点滅タスクで消灯してからサスペンドするようにします。
MQTTタスクでは、サブスクライブしているMQTTトピックを受信したときに、iot_subscribe_callback_handler() がコールされます。LEDが点滅している時に、LED点滅タスクをサスペンドするのではなく、通知を送信するだけにします。
--- 変更前
+++ 変更後
@@ -117,7 +117,7 @@ void iot_subscribe_callback_handler(AWS_IoT_Client *pClient, char *topicName, ui
if (blinkState == eSuspended){
vTaskResume(xBlink);
} else{
- vTaskSuspend(xBlink);
+ xTaskNotifyGive(xBlink);
}
}
}
LED点滅タスクでは、その処理関数 blink_task() で通知を受け取ったら、消灯して自分でサスペンドするようにします。
--- 変更前
+++ 変更後
@@ -35,6 +35,12 @@ void blink_task(void *arg) {
Core2ForAWS_Sk6812_Show();
while (1) {
+ if (ulTaskNotifyTake(pdTRUE, 0)) {
+ // Clear LED and suspend blinking
+ Core2ForAWS_Sk6812_Clear();
+ Core2ForAWS_Sk6812_Show();
+ vTaskSuspend( NULL );
+ }
Core2ForAWS_Sk6812_SetSideColor(SK6812_SIDE_LEFT, 0x000000);
Core2ForAWS_Sk6812_SetSideColor(SK6812_SIDE_RIGHT, 0xffffff);
Core2ForAWS_Sk6812_Show();
変更前のソースは、https://github.com/m5stack/Core2-for-AWS-IoT-EduKit/blob/master/Blinky-Hello-World/main にあります(2021年4月6日の更新版にて)。
まとめ
ということで、AWS IoT EduKit のLチカを消灯できるようにしてみました。結果は単純なのですが、ESP-IDF やら FreeRTOS やらを調べて、ここまでが結構長かったです。おかげで、取っ付きづらかった AWS IoT EduKit のソースコードに少し慣れてきました。LEDがつきっぱなしで、同じように困っていた方の参考になればうれしいです。