mbed Advent Calendar 2015の14日目の記事です。
注: この記事は technology preview 版のソフトウェアを利用したものになるので、今後変わる可能性があります。
前回の記事でMINARでの定期的な処理の実行ができるようになったので、この記事では割り込み処理を扱います。
スイッチを押すとLEDをON/OFF
公式ドキュメント(https://docs.mbed.com/docs/getting-started-mbed-os/en/latest/Full_Guide/MINAR/)の A single event from an interrupt handler に記載されているコードを試します。
スイッチを押すとLEDをON/OFFするコードは以下のようになります。
#include "mbed-drivers/mbed.h" static DigitalOut led(LED1); static void toggle_led(void) { // LEDの状態を反転する led = !led; } static void switch_pressed(void) { // toggle_ledの実行をキューへ積む minar::Scheduler::postCallback(toggle_led); } void app_start(int, char**) { // SW2の入力をトリガーにしてswitch_pressedを実行 static InterruptIn user_sw(SW2); user_sw.rise(switch_pressed); }
このコードを yotta build
してコードを書き込むと、以下のように動きます。
動作を説明すると
- InterruptInとして指定されたSW2が押されると
switch_pressed
が呼び出される。 switch_pressed
の中でMINARスケジューラーにイベントのキューを積む。- MINARスケジューラーによって
toggle_led
が実行されLEDのON/OFFが反転する。
といった流れになります。
スイッチを押すとLEDが一定時間だけ点灯する
前回の記事で使ったdelay
メソッドと組み合わせることで、押したタイミングでLEDをONして、1秒経ったらOFFにするようなコードを書くこともできます。
先ほどのコードのswitch_pressed
の中にdelay
をつけたLEDを消すイベントを追加すればOKです。
#include "mbed-drivers/mbed.h" using mbed::util::FunctionPointer1; using mbed::util::FunctionPointerBind; using mbed::util::Event; static DigitalOut led(LED1, 1); static void blinky(int i) { led = i; // 1 => off, 0 => on } static void switch_pressed(void) { FunctionPointer1<void, int> ptr_to_blinky(blinky); // 関数へのポインターの生成 FunctionPointerBind<void> bind_of_blinky_on(ptr_to_blinky.bind(0)); // 引数(0)をbind FunctionPointerBind<void> bind_of_blinky_off(ptr_to_blinky.bind(1)); // 引数(1)をbind Event e_on(bind_of_blinky_on); // LEDを光らせるイベントを生成 Event e_off(bind_of_blinky_off); // LEDを消すイベントを生成 // LEDを光らせるイベントをキューへ積む minar::Scheduler::postCallback(e_on); // LEDを消すイベントを1秒後に実行するようにキューへ積む minar::Scheduler::postCallback(e_off).delay(minar::milliseconds(1000)); } void app_start(int, char**) { // SW2の入力をトリガーにしてswitch_pressedを実行 static InterruptIn user_sw(SW2); user_sw.rise(switch_pressed); }
動作する様子は以下のようになります。
1のコードと違い、LEDをコントロールする関数(blinky
)に引数が必要になるため、FunctionPointer1
を使っています。このあたりは前回の記事をご参照ください。
動きとしては
- InterruptInとして指定されたSW2が押されると
switch_pressed
が呼び出される。 switch_pressed
の中でMINARスケジューラーにLEDを点けるイベントと消すイベントのキューを積む。- delayを指定していないイベントが先に発火して、LEDが点く。
- delayをつけたイベントが発火して、LEDが消える。
といった感じになります。
終わりに
mbed OSの新しいスケジューラーMINARの使い方がだいぶわかってきました。
mbed OSはIoTを意識しているようなので、そのうちインターネット上のAPIを使って何かやってみたいところです。
明日はod_1969さんです。よろしくお願いします。