# UDP網路通訊  ## 1. 什麼是 UDP? UDP(User Datagram Protocol)是一種「無連線」的通訊協定,我傳資料時**不用先跟對方握手**,只要把資料包(datagram)丟進網路,對方就有機會收到。因為少了確認、重送等流程,整體延遲低、程式碼簡單,但也少了可靠度保證。 > 我在專題裡需要的是「**越快越好**」的同步,而不是每一包都 100 % 完整,所以 UDP 很適合。 ## 2. 為什麼要用 UDP 來同步舞者? 1. **多人同時收聽**:只要用廣播位址 `255.255.255.255`,一個封包就能讓所有 ESP32 收到。 2. **低延遲**:每次亮燈只佔 4 byte(整數一筆幀號),傳送時間 < 1 ms。 3. **容錯空間大**:若有個別封包掉了,下一幀馬上覆蓋,不會被觀眾看出來。 ## 3. 專案實作流程 ### 3.1 Python 編輯器端:送出廣播 我在 `editor.py` 的最前段先設定廣播 socket,然後寫一個 `UDP()` 函式,把「現在的幀號」包成 4 byte 大端序,再用 UDP 廣播出去。 ```python # editor.py 19–27 broadcast_address = '255.255.255.255' broadcast_port = 12345 sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) def UDP(nowframe): message = struct.pack('>i', nowframe) sock.sendto(message, (broadcast_address, broadcast_port)) ``` 編輯器每當時間軸跳到新幀,就呼叫 `UDP(nowframe)`,瞬間把幀號丟給全場板子。 ### 3.2 ESP32 端:接收並換燈 `translate.py` 會把設定寫進每位舞者的 `dancerX.ino`。在 `loop()` 裡,我們持續偵測 UDP;只要抓到 4 byte 封包,就解碼成整數後呼叫 `playh()` 來切換顏色陣列。 ```cpp // dancerX.ino 143–169 WiFiUDP udp; // 建立 UDP 物件 ... int packetSize = udp.parsePacket(); if (packetSize) { int len = udp.read(incomingPacket, 4); if (len == 4) { int receivedNumber = (incomingPacket[0] << 24) | (incomingPacket[1] << 16) | (incomingPacket[2] << 8) | incomingPacket[3]; playh(receivedNumber); // 依幀號更新 LED } } ``` 因為所有板子都聽同一埠(`12345`),所以只要主持端丟一包,所有舞者在下一幀就會亮同樣的顏色。 ### 3.3 整體時序 1. **時間軸跑到新幀** → PyQt 立刻呼叫 `UDP(nowframe)`。 2. **Wi‑Fi Broadcast**:幀號在 $<1 ext{ ms}$ 內送達所有板子。 3. **ESP32 解析** → `playh()` 替換當前 LED buffer → `FastLED.show()` 實際輸出。 > 在校內網路測試,五位舞者的最大誤差 < 5 ms,肉眼幾乎看不出不同步。 ## 4. 注意事項與優化 * **同一頻段干擾**:若現場有大量 Wi‑Fi 設備,封包掉落機率會變高,可考慮重覆廣播兩次或在舞台側架一台專用分享器。 * **封包大小**:目前只傳整數幀號,未來若要同步音樂時間或多段資料,要注意封包長度別超過 MTU。 * **校時**:如果要做到更精準(<1 ms)可以在進場前先用 NTP 或 PTP 校正各板子的系統時鐘,再讓它們根據本地時間觸發。 ## 5. 結論 利用 UDP 的廣播特性,我們只用一條簡單的函式就把「時間控制中心」連到所有舞者。這種結構省線、低延遲,也符合舞台快速布置的需求,之後換曲目或增加新舞者,只要保持相同埠號即可快速擴充。
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up