現在我們已經完成 LED 輸出、實體按鈕、按下判斷、去彈跳與燈號狀態管理,第一階段的 MCU 現場控制功能已經到位,今天進行整合驗收,確認完成 MCU 現場控制器 1.0。
注意 : 本次驗收要確認四件事,開機時燈號有明確狀態、每次按下只切換一次、接點彈跳不會輕易造成重複動作,以及沒有啟動上層服務時,MCU 仍能獨立完成現場控制,驗收時不要一邊修改程式一邊測試,若中途發現異常,應先記錄發生條件與結果,避免修改後無法確認問題究竟來自程式、接線或操作方式。
const int LED_PIN = 2;
const int BTN_PIN = 9;
// MCU 保存唯一可信的號誌輸出狀態。
bool ledState = false;
bool lastBtn = HIGH;
void toggle_led() {
ledState = !ledState;
digitalWrite(LED_PIN, ledState ? HIGH : LOW);
}
void setup() {
pinMode(LED_PIN, OUTPUT);
pinMode(BTN_PIN, INPUT_PULLUP);
// 硬體輸出依 ledState 初始化,不另外保存第二份狀態。
digitalWrite(LED_PIN, ledState ? HIGH : LOW);
}
void loop() {
bool btn = digitalRead(BTN_PIN);
if (lastBtn == HIGH && btn == LOW) {
toggle_led();
delay(50);
}
lastBtn = btn;
}
這份程式已將每個角色分開,setup() 負責設定腳位與初始輸出,loop() 負責持續讀取 D9,lastBtn 用來辨認按下瞬間,delay(50) 降低接點彈跳,而 ledState 與 toggle_led() 則統一管理 D2 LED。
先不要按下 D9,執行 App 後觀察 D2,因為 ledState 的初始值是 false,LED 應保持熄滅,這表示程式狀態與硬體輸出在開機時一致。
接著按一次讓 LED 亮起,再重新啟動 App,LED 應重新回到熄滅狀態,因為程式再次從 ledState = false 開始,這項測試可確認初始狀態不是碰巧留下的硬體結果,而是由 MCU 主動建立。
先正常短按五次,每次都要完整按下再放開,LED 應依序在亮與滅之間切換,一次操作只產生一次結果。
再將按鈕持續按住兩秒,LED 只能在剛按下時切換一次,不能持續閃爍,放開時也不應改變狀態,這可確認程式能分辨按下瞬間與持續按住。
最後混合快速輕按、一般按壓與稍長按住,觀察是否仍能維持一次操作對應一次切換,若偶爾出現異常,應先檢查按鈕方向、D9 與 GND 接線及接點是否鬆動,不要立刻以增加延遲掩蓋問題。
本階段尚未啟動 Python,也沒有瀏覽器管理畫面,但實體按鈕仍能直接由 MCU 讀取並切換 LED,這表示現場控制不依賴 MPU、網路或遠端服務。
保留這條本地控制路徑很重要,未來加入上層功能後,即使 Python 尚未啟動或網路暫時中斷,現場人員仍可在控制箱旁完成基本操作。
整合驗收的合格標準不是「大多數時候能亮」,而是每項操作都有可預期結果,開機、短按、長按、放開與重新啟動都應符合規則,只有完成這些測試,第一階段才算真正結束,也才能放心把新的上層功能接進來,並建立可靠穩定的控制基礎。
第10天終於完成第一階段 Edge Box 1.0 驗收,接下來要啟動 UNO Q 的另一個大腦 MPU,讓 Python 開始處理訊息與上層服務。
下一篇|UNO Q 另一個大腦新登場