組み込み開発

状態遷移の超入門(INIT/IDLE/RUN/ERROR)

シリーズ:基礎シリーズ(組み込み開発)
この記事の役割:プログラムを INIT/IDLE/RUN/ERROR の「状態」に分けて考え、ログで「今どの状態か」を追えるようにします。

はじめに

組み込みのプログラムでよくある悩みがこれです。

  • 「動かない。今どこで止まってる?」
  • 「if が増えて、何が起きてるか分からない」
  • 「ログを見ても、何を見ればいいか分からない」

この解決に効くのが “状態(state)” です。
このページでは、プログラムを次の状態に分けて考え、ログで「今どの状態か」を追えるようにします。

  • 初期化中(INIT):起動直後の準備をしている
  • 待機中(IDLE):安全に止まって、開始を待っている
  • 処理中(RUN):実際の処理が動いている
  • エラー状態(ERROR):異常を検出して安全側に倒している

先に結論(※ここは読み飛ばしてOK)

  • 状態=「いま何をしている最中か」を表すラベル
  • まずはじめは 4つだけの状態INIT / IDLE / RUN / ERRORで十分
  • ログに出す状態遷移の情報は次の2種類だけで足りる
    • state=INIT みたいに 状態名を出す
    • INIT -> IDLE みたいに 遷移した瞬間を出す
  • エラーの細かい分類や番号設計は、今は不要(後で増やせる)

1. 状態遷移とは

状態遷移は、プログラムが「いまど何をしているのか」を表す状態を持ち、条件などをきっかけに状態を切り替えて動く仕組みです。
この記事では 初期化中/待機中/処理中/エラー の4つの状態に分けて扱います。

2. 「状態」がない(状態で整理していない)場合

状態で整理していないプログラムは、判断はできても 全部が同じ場所に混ざりやすいです。
例えば掃除ロボットに「進め」と命令が来たとき、

  • 壁は?
  • 段差は?
  • バッテリーが低下?
  • いま初期化中?
  • すでに掃除中?
  • エラー中?

…といった条件が、あちこちに増えていきます。
結果として 、
「いまどの状態で止まっているのか」 が分かりにくくなり、「ここ通った」「次ここ通った」 みたいな 経過ログ(通過ログ)をあちこちに追加して、状態(段階)を推測することになりがちです。

3. 「状態」がある(状態で整理している)場合

状態を使うと、プログラムはまず 「いま何をしているか」 を表す 状態(動作モード) を1つ持ちます。
この動作モードが 状態 です。
そして 壁/段差/バッテリー のような情報は、その状態の中で判断に使う“条件” になります。

ポイントは次の通りです。

  • 状態がない(整理していない) と、いつでも全部を気にしてしまう
    (壁は?段差は?バッテリーは?初期化中?掃除中?エラー中?と毎回確認しなければならない)
  • 状態があると、「今の状態で見る条件」が決まる
    → だから整理しやすい

この記事では、状態を次の4つに分けます。

初期化中(INIT)

起動直後の準備をする状態です。
ここで主に見るのは、“起動できるか”の条件です。

  • 例:バッテリーが極端に低い/センサが読めない → エラーへ(INIT→ERROR)
  • 例:初期化が全部完了した → 待機中へ(INIT→IDLE)

✅ この段階では、壁や段差のような「動作中の条件」は基本的に気にしません。

待機中(IDLE)

開始命令を待つ状態です(安全に止まっている状態)。
ここで主に見るのは、“開始してよいか”の条件です。

  • 例:開始命令が来た → 処理中へ(IDLE→RUN)
  • 例:バッテリーが低いので開始しない → IDLEのまま(または運用でERRORへ)

✅ 「いま初期化中?」とか「すでに掃除中?」は、状態が決まっているので迷いません(今はIDLEです)。

処理中(RUN)

実際に動作する状態です。
ここで主に見るのが、あなたが挙げた 壁/段差/バッテリー低下です。

  • 例:壁を検知 → RUNのまま方向転換(状態は変えない)
  • 例:段差を検知(危険)→ エラーへ(RUN→ERROR)
  • 例:バッテリーが低下 → 待機へ戻る(RUN→IDLE)(または運用でERRORへ)

✅ ここで「すでに掃除中?」という迷いが消えます。今がRUNなら掃除中です。

エラー(ERROR)

危険なので止める状態です(安全側に倒す)。
この状態では基本的に 動作しないことが目的です。

  • 例:復帰操作がされた → 待機へ(ERROR→IDLE)

✅ 「エラー中?」は状態で明確になります。エラー中なら、壁や段差より先に“止める”が優先です。

こうしておくと、デバッグするときも
「いまはどの状態か?」→「その状態の処理だけ見る」
の順で整理できます。状態が分かれば、見るべき条件も絞れます。

4. ログは「状態」と「遷移の瞬間」だけでいい

状態遷移を使う目的は、「いま何が起きているか」をログで追えるようにすることです。
ただし、最初からログをたくさん出す必要はありません。

まずは次の2種類だけで十分です。

  • 今の状態が分かるログ
    例:state=IDLEstate=RUN
  • 状態が変わった瞬間のログ
    例:INIT -> IDLERUN -> ERROR

これだけ出せれば、少なくとも次が判断できます。

  • 初期化(INIT)は終わったのか
  • 待機(IDLE)まで来ているのか
  • 処理(RUN)に入れているのか
  • どこでERRORに入ったのか

「動かない」ときに、まず見るのはこの2つだけでOKです。

5. エラーは「細かく決めない」でOK(今回はここまで)

この記事の目的は 状態遷移を導入して、ログで追えるようにすることです。
エラーコードの番号の意味や分類ルールまで決め始めると、話が大きくなりすぎます。

今回は最小で、次の考え方だけ持っておけばOKです。

  • ERROR は「異常が起きたので安全側に倒す状態」
  • (必要なら)0=正常、0以外=異常 程度で十分

細かい原因の切り分け(どの異常なのか)は、別の記事で紹介します。

まとめ

  • 状態遷移は、プログラムを「初期化中/待機中/処理中/エラー」のような状態(動作モード)に分けて管理する考え方
  • 状態で整理すると、「いま見るべき条件」が絞れるので、コードもログも追いやすくなる
  • ログは最初は 状態遷移した瞬間の2種類だけで十分
  • エラーの細かい番号設計は、今回はやらなくてOK(必要になったら増やす)

次に読む

  • E0-06 状態遷移とエラー判別(INIT/IDLE/RUN/ERROR)
    実際に状態とログをコードに入れて、「動かないときに原因を追う」形にします。
  • (関連)UARTログ入門
    ログの出し方/見方を固めると、状態遷移の効果が一気に出ます。

-組み込み開発