C言語でEV3開発(18)
モードの遷移の設計-コマンド通信処理の準備

2021年2月2日

どもです。
今回は、前回紹介したEv3とBluetoothで通信する機能を検証します…。
の前に、準備段階として、Ev3とBluetoothの接続に伴う状態(実行タスク)の制御を検討します。

1.なんで状態の制御?

状態の遷移、といってもそれほど大層なものではなく、単純なタスクの切り替えです。
アプリ起動後に初期化タスクを実施、初期化が正常に完了した場合には、Bluetooth接続待ちタスクを起動する。
その後、Bluetooth接続されたらコマンド通信を開始する。
Bluetooth接続が切れたら、各タスクを終了して再度Bluetooth接続待ち状態に遷移する、という程度のものです。
この状態遷移を図にすると、以下のようになります。
状態遷移図
このようなタスクの遷移/切り替えは、実装上の「実行するタスク毎の役割を明確にする」ためです。

2.モード遷移の実装

各モードでの実施内容、およびモード遷移の実装のソースコードを以下に示します。
まずは、各モードでの実施内容を示します。

/**
 *  @brief  モード1でのメインタスク
 *          各種初期化を行い、その後モード2に遷移させる。
 */
void task_mode1(intptr_t unused) {
    init_led_color();
    init_debug_uart();
    debug_clear();
    
    set_led_color_off();
    
    //各種バッファー初期化
    init_bt();
    init_cmd();

    //各種初期化処理完了→モード2に遷移
    ModeTransitionToMode2();
}

/**
 *  @brief  モード2でのメインタスク
 *          Bluetoothでの接続を待ち、接続された後に、モード3へ遷移する。
 */
void task_mode2(intptr_t unused) {

    debug_clear();
    debug_write_msg((const char*)"APP_MOD = 2", 0);
    debug_write_msg((const char *)"BLUETOOTH:DISCONN", 1);
    
    set_led_color_orange();
    wait_btconnect();
    set_led_color_off();
    
    debug_clear();
    debug_write_msg((const char*)"APP_MOD = 2", 0);
    debug_write_msg((const char *)"BLUETOOTH:CONNECT", 1);
    
    //Bluetooth接続完了→モード3に遷移
    ModeTransitionToMode3();
}

/**
 *  @brief  モード3でのメインタスク
 */
void task_mode3(intptr_t unused) {

    debug_clear();

    dly_tsk(TASK_MODE3_INTERVAL);//WAIT状態に遷移:他のタスクを実行する。
    
    debug_clear();
    CheckCanContinueMode3();

    mode_task_count = 0;

    //一定時間ごとに、LCDへのデバッグ表示を更新する。
    while (can_continue_mode3) {
        mode_task_count++;


        debug_device_info();
        //LCDの更新周期:50msec(仮設定)
        dly_tsk(TASK_MODE3_INTERVAL);//WAIT状態に遷移:他のタスクを実行する。

        port_check_connectoin(); 
        CheckCanContinueMode3();
    }

    debug_clear();
    //Bluetooth接続解除
    ModeTransitionToMode4();
}

/**
 *  @brief  モード4でのメインタスク。
 *          実行中の定周期処理を停止し、再度モード1に遷移する。
 */
void task_mode4(intptr_t unused) {
    debug_clear();
    debug_mode();

    set_led_color_red();

    dly_tsk(50);

    while (true == bt_task_running) {
        stop_bt_task();
        //データの更新を確認する。
        debug_mode();
        dly_tsk(50);
    }

    ModeTransitionToMode1();
}

所々、意味の無いコードが出てきますが、今はモード遷移の処理「ModeTransitionToModeX」に注目してください。
また、モード3の関数「task_mode3」で呼び出している「debug_device_info」ですが、コレはEv3のLCDに実行中の情報を表示するための処理です。
次に、実際にモードの遷移を行う「ModeTransitionToModeX」の実装です。

/**
 *  @brief  モード1へ、モードを遷移させる。
 */
void ModeTransitionToMode1(void) {
    cur_mode = 1;
    act_tsk(MODE_1_TASK);
    
    IsMode1Running = true;
    IsMode2Running = false;
    IsMode3Running = false;
    IsMode4Running = false;
}

/**
 *  @brief  モード2へ、モードを遷移させる。
 */
void ModeTransitionToMode2(void) {
    cur_mode = 2;

    act_tsk(MODE_2_TASK);
    
    IsMode1Running = false;
    IsMode2Running = true;
    IsMode3Running = false;
    IsMode4Running = false;
}

/**
 *  @brief  モード3へ、モードを遷移させる。
 */
void ModeTransitionToMode3(void) {
    cur_mode = 3;
    can_continue_mode3 = true;

    act_tsk(MODE_3_TASK);

    IsMode1Running = false;
    IsMode2Running = false;
    IsMode3Running = true;
    IsMode4Running = false;
}

/**
 *  @brief  モード3を継続可能か否かの判定
 */
void CheckCanContinueMode3(void) {
    if (is_connect_bt) {
        can_continue_mode3 = true;
    } else {
        can_continue_mode3 = false;
    }
}

/**
 *  @brief  モード4へ、モードを遷移させる。
 */
void ModeTransitionToMode4() {
    cur_mode = 4;

    act_tsk(MODE_4_TASK);

    IsMode1Running = false;
    IsMode2Running = false;
    IsMode3Running = false;
    IsMode4Running = true;
}

モードの遷移は、実際にはTOPPERS HRP2 のAPI「act_tsk」を使用してタスクを起動して実現しています。なお、各関数の中で行っているフラグは、デバッグ用の変数です。

3.実際の動き

上記アプリを実機上で動かした際の動画が、以下です。

最初は、「APP_MOD = 2」「BLUETOOTH:DISCONN」と表示されていますが、Bluetoothと接続されると、コレが「BLT_TSK_CNT = xxxxx」、「CMD_HDL_CNT = xxxxx」、「MOD_TSK_CNT = xxxxx」と表示されます。コレは、各タスクの実行回数です。今回のアプリでは、「MOD_TSK_CNT」が増えています。コレは、モード3のタスクが実行された回数を示します。
Bluetooth接続を解除すると、再度「APP_MOD = 2」「BLUETOOTH:DISCONN」の表示に戻ります。これで接続待ち状態に遷移しています。
このように、Bluetooth接続状態の変更に伴う状態の変化を制御します。

4.まとめ

さて。
今回のエントリーは、ここまでにします。
次回は、モード3の中でコマンド通信を行っている様子を紹介します。

ex.追加(2017/07/06)

今回のエントリーで紹介したソースコードとそれに付随する開発環境を、コチラからダウンロードできるようにしました。