iT邦幫忙

2026 iThome 鐵人賽

DAY 15
0

https://ithelp.ithome.com.tw/upload/images/20260824/20058745f76cgVaLyA.png

MPU 已經能要求 MCU 切換燈號,今天要讓 MCU 把真正結果回報給 Python。

回報必須放在共同切換入口

實體按鈕與 MPU 命令都會進入 toggle_led(),因此狀態回報也應放在這個函式內,無論切換由哪個來源觸發,只要 ledState 與 D2 輸出完成更新,接著就會送出相同的回報。

若只在 on_toggle_led() 中回報,遠端命令雖然有結果,現場按鈕卻不會通知 MPU,兩條操作路徑便再次產生不同規則。

MCU 在切換後送出 led_status

將 Day 14 的 toggle_led() 改成以下內容,其餘按鈕、下降緣與 Bridge 登記維持不變。

void toggle_led() {
  ledState = !ledState;
  digitalWrite(LED_PIN, ledState ? HIGH : LOW);
  Bridge.call("led_status", ledState);  // 本日新增
}

這裡的 "led_status" 是上行事件名稱,第二個參數 ledState 是要傳給 MPU 的布林值,更新順序是先反轉狀態、寫入 D2,最後才回報結果。

toggle_led() 仍是唯一切換入口,MCU 不必分辨命令來自 D9 或 MPU,兩種來源完成後都會回傳同一份真實狀態。

回報放在 digitalWrite() 之後也有明確意義,送出的值代表 MCU 已完成本次狀態更新,而不是尚未執行的命令內容,上層收到結果後才能把它當作硬體真實狀態,這與 Python 自己先把畫面反轉有本質差異。

Python 登記狀態接收函式

Python 端先實作最小的 on_led_status(),暫時直接印出布林值,再使用 Bridge.provide() 登記等待 MCU 呼叫。

from arduino.app_utils import App, Bridge

service_name = "Intersection Edge Service"
service_ready = True

def on_led_status(state: bool):
    print("MCU 回報狀態:", state)  # 本日新增

def on_toggle_led(client_id, data):
    Bridge.call("toggle_led")
    print("已要求 MCU 切換 LED")

Bridge.provide("led_status", on_led_status)  # 本日新增

print("Service ready:", service_name)
on_toggle_led(None, None)

App.run()

Bridge.provide("led_status", on_led_status) 必須使用與 MCU 完全相同的名稱,當 MCU 呼叫 "led_status" 時,Bridge 會執行 Python 的 on_led_status(),並把布林值放入 state。

登記動作要放在啟動測試呼叫之前,否則 MCU 很快完成切換並送回狀態時,Python 端可能還沒有準備好接收入口,本日程式先登記、再測試、最後進入 App.run(),執行順序正好對應這項需求。

驗證下行後能返回結果

按下 Run 後,Python 會先送出一次測試切換,D2 LED 改變狀態,接著 Console 應收到 True 或 False,這表示命令已從 MPU 抵達 MCU,執行完成後又將結果送回 MPU。

輸出的布林值應與實體 LED 相符,亮起時收到 True,熄滅時收到 False,MPU 不需要自行反轉一份狀態,也不應根據上一個畫面結果猜測本次動作是否成功。

可連續重新執行 App 兩次觀察結果,每次啟動測試都只要求切換一次,因此 Console 與 LED 應交替出現兩種狀態,若 LED 有變化但收到的值相反,應檢查 ledState 更新與 digitalWrite() 是否仍使用同一份資料。

現場按鈕也會主動回報

服務保持運行時按下 D9,LED 每次切換後,Python Console 也應出現新的布林值,這證明回報不是遠端命令的專用功能,而是 MCU 所有狀態變更的共同出口。

如果 LED 有切換卻沒有輸出,先檢查兩端事件名稱是否一致,再確認 Python 是否已在測試命令前執行 Bridge.provide(),避免回報抵達時接收函式尚未登記。

檢查一次切換只回報一次

每次 toggle_led() 只應產生一筆 led_status,啟動測試一次、D9 短按一次,Console 都各新增一行即可,若同一次操作出現兩筆相同或相反結果,應檢查是否在其他位置重複呼叫 Bridge.call(),回報功能只保留在共同切換入口,才能讓事件數量與實際硬體動作一一對應。

本篇完成內容

  • MCU 在完成輸出後回報 ledState。
  • Python 以 Bridge.provide() 登記 led_status。
  • 完成 MPU 到 MCU 再返回 MPU 的基本路徑。
  • 現場按鈕與 MPU 命令都會回報真正狀態。

現在 MCU 已會把真正狀態回報給 Python,但 True 與 False 對管理畫面不夠直覺,下一篇要把硬體狀態整理成 ON/OFF 這種可讀資料。

下一篇|將硬體狀態轉成可讀資訊


上一篇
Day 14|搭建 MPU 到 MCU 的第一座橋樑
下一篇
Day 16|將硬體狀態轉成可讀資訊
系列文
一塊板子,兩個腦袋:Arduino UNO Q 30 天實戰 共 30 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言