iT邦幫忙

2026 iThome 鐵人賽

DAY 5
0

點亮 LED 只是第一步,接下來更重要的問題是:當現場按鈕與遠端命令都能操作這盞燈時,誰來記住它現在究竟是亮還是滅?接下來要為號誌燈建立統一的狀態管理方式,讓所有操作都使用同一個控制入口,避免各自下指令而造成狀態混亂。

用布林值保存亮滅狀態

LED_PIN 下方加入 bool ledState = false;bool 是只有 truefalse 兩種結果的資料型態,適合表示開啟或關閉,這裡將 true 視為 LED 亮起,false 視為 LED 熄滅。

const int LED_PIN = 2;

bool ledState = false;

變數建立後,程式便有一個固定位置記錄目前狀態,不必從分散的 digitalWrite() 指令猜測 LED 應該亮或滅,後續其他操作也能先修改 ledState,再依它的內容更新硬體輸出。

變數名稱使用 ledState,其中 LED 表示控制對象,State 表示狀態,閱讀程式時可以直接理解它保存 LED 的亮滅結果,初始值設為 false,代表 MCU 啟動時先以關閉狀態開始。

注意:布林值本身不會自動控制腳位,它只保存程式對目前狀態的判斷,真正讓 LED 改變的是後面的 digitalWrite(),因此狀態資料與硬體輸出必須一起更新,若只改 ledState 而沒有重新寫入 D2,程式記錄與實體燈號便可能不一致,因此需要特別注意。

建立共用切換函式

接著建立 toggle_led(),函式內先使用 ! 將布林值反轉,再透過三元運算子決定輸出 HIGH 或 LOW。

void toggle_led() {
  ledState = !ledState;
  digitalWrite(LED_PIN, ledState ? HIGH : LOW);
}

ledState 原本是 false,執行 !ledState 後會變成 true,下一次呼叫時又會由 true 變回 false,因此每執行一次函式,狀態就會切換一次。

ledState ? HIGH : LOW 是三元運算子,問號前方是判斷條件,條件為 true 時採用 HIGH,條件為 false 時採用 LOW,這行程式會讓 D2 的實際輸出與 ledState 保持相同意義。

將反轉狀態與更新輸出放在同一個函式後,其他程式便不需要分別修改變數與腳位,而是只要呼叫 toggle_led(),兩項工作便會依固定順序完成,這樣能減少狀態已改變但硬體尚未更新的情況。

共用函式也讓後續使用更單純,函式外部不必知道 LED 現在是亮或滅,也不必自己決定 HIGH 或 LOW,只需要提出切換要求,剩下的狀態反轉與腳位更新便都由 toggle_led() 一起搞定。

完整 MCU 程式

sketch/sketch.ino 改成以下內容,其他檔案保持 Day 4 的版本。

const int LED_PIN = 2;

bool ledState = false;

void toggle_led() {
  ledState = !ledState;
  digitalWrite(LED_PIN, ledState ? HIGH : LOW);
}

void setup() {
  pinMode(LED_PIN, OUTPUT);
  digitalWrite(LED_PIN, LOW);
  toggle_led();
}

void loop() {
}

說明setup() 先將 D2 設為輸出,再以 LOW 關閉 LED,此時硬體狀態與 ledState = false 一致,接著呼叫 toggle_led(),變數會切換為 true,D2 也會輸出 HIGH,因此程式啟動後 LED 應持續亮起。

先寫入 LOW 再呼叫函式,是為了讓 MCU 啟動時有明確的初始輸出,並用同一個切換流程完成第一次亮燈,loop() 目前仍保持空白,目前只需驗證狀態與函式呼叫。

執行與驗證

儲存後按下 App Lab 的 Run,等待建置與部署完成,D2 LED 應在程式啟動後亮起,這表示 ledState 已由 false 變為 true,三元運算子也依狀態將 D2 設為 HIGH。

驗證成功後,也可在 setup() 中再加入一次 toggle_led(); 做短暫驗證,連續呼叫兩次後,狀態會由 false 變成 true,再變回 false,LED 最後應熄滅,確認結果後再恢復本篇只有一次呼叫的版本。

若 LED 結果與預期不同,先檢查 ledState 的初始值、反轉符號 !、三元運算子的 HIGH 與 LOW 順序,以及 toggle_led() 是否真的在 setup() 中被呼叫。

本篇完成內容

  • 使用 bool ledState 保存 LED 狀態。
  • 使用 ! 在 true 與 false 之間反轉。
  • 使用三元運算子依狀態輸出 HIGH 或 LOW。
  • 建立所有操作共用的 toggle_led() 函式。

現在號誌燈的狀態已有統一的管理方式,但目前還只能靠程式操作,無法滿足現場需求,接下來要為它加上實體按鈕,讓現場操作人員能直接操作。

下一篇|為 Edge Box 加上實體按鈕


上一篇
Day 4|接上第一個號誌輸出
系列文
一塊板子,兩個腦袋:Arduino UNO Q 30 天實戰5
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言