使用 Arduino 讓 ESP32 透過 UDP 收發訊息,進而控制 LED 明滅

春麗 S.T.E.M.
6 min readJan 2, 2024

--

目錄
1. 前情提要
2. Arduino
3. 成果

⦿ 前情提要
⦿ Arduino
⦿ 成果

前情提要

前一篇文章中,使用 CocoaAsyncSocket 這個套件完成了 iOS 上的 UDP Communication,UDP 是 Connectionless 的,只要透過相同內網的設備綁定 Port,接著發送廣播訊息,其他也綁定這個 Port 的設備就能夠與之交流。

雖然尚未撰寫 TCP Communication 在 iOS 上的實現,不過已經透過下面兩篇文章的應用,做到 TCP Client(iOS)與 TCP Server(ESP32)的交流,iOS 能夠操控 ESP32 的 LED 燈,參考如下:

這篇文章試著用 UDP 廣播的方式來操控 ESP32 吧!

回目錄

繼續閱讀|回目錄

Arduino

在 TCP Communication 中,ESP 充當的是 Server,所以 Client 要知道 Server 的 IP,也要綁定 Server 特定的 Port,Server 要做到的就是監聽這個特定的 Port 有沒有 Client 連接,以及連接中有沒有傳送訊息過來。

而 UDP 就相對單純,我們先加入如下:

#include <WiFi.h>
#include <WiFiUdp.h>

#define LED_PIN 2

const char* ssid = "yourSSID";
const char* password = "yourPassword";
unsigned int localUdpPort = 8088;

WiFiUDP udp;

void setup() {
Serial.begin(115200);
pinMode(LED_PIN, OUTPUT); // 設置 LED 引腳為輸出模式

WiFi.begin(ssid, password); // 連接到 WiFi

while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Connecting to WiFi...");
}

udp.begin(localUdpPort); // 啟動 UDP
Serial.printf("Listening at IP %s, UDP port %d\n", WiFi.localIP().toString().c_str(), localUdpPort);
}

setup 的地方,設定 Baud引腳,接著連接 Wi-Fi,然後 UDP 監聽特定 Port,並把 IP 跟 Port 印出來。

loop 的地方,加入如下:

  int packetSize = udp.parsePacket();
if (packetSize) {
char incomingPacket[255];
int len = udp.read(incomingPacket, 255);
if (len > 0) {
incomingPacket[len] = 0;
}

Serial.printf("Received packet: %s\n", incomingPacket);

if (strcmp(incomingPacket, "ON") == 0) {
digitalWrite(LED_PIN, HIGH); // 打開 LED
} else if (strcmp(incomingPacket, "OFF") == 0) {
digitalWrite(LED_PIN, LOW); // 關閉 LED
}

udp.beginPacket(udp.remoteIP(), udp.remotePort());
udp.write((uint8_t*)"ACK", strlen("ACK")); // 回傳 ACK
udp.endPacket();
}

有收到 UDP 通訊傳來的封包,就去解析這個封包,以 incomingPacket 為 Buffer 讀取出來,如果傳來的是連續訊息,並且在 254 個字元以內,就適時分段再印出來,即是最多只取 254 位。

之前 TCP Server 的處理方式是,如果超越 12 位字元就截斷,如下:

        if (len < 12) {
data[len] = '\0'; // 小於 12,就在 len 處換行
} else {
data[12] = '\0'; // 大於 12,就在 12 處換行
}

但在 UDP 裡並沒有這樣做,因為這邊要的不是連續字元(字串),只需要 ON 跟 OFF,所以如果 incomingPacket 接收到的字元位數大於等於 255 就會造成錯誤。

接著,去比對傳來的字元,在特定字元(ON、OFF)去對 LED 燈操作,用 digitalWrite 對 GPIO 做到打開與關上。

最後,將傳訊過來的 IP 跟 Port 印出來,再把 ACK 傳回去表示收到,至此,程式碼的部份已完成,下面來看看成果。

回目錄

繼續閱讀|回目錄

成果

下面兩張圖是在 LED 打開的時候,透過 UDP 廣播 OFF,順利將 ESP32 的 LED 關上。

再看到 iOS 的部份。

當綁定 8088 Port,將 ON 傳出去,根據前一篇文章,::ffff 跟 192.168.23.57 是本機接收到自己廣播出去的訊息,不過 192.168.23.220 則是 ESP32 接收訊息後的回傳。

在 ON 或 OFF 都會接收到 ACK,表示正常運作,完成了!

這次就分享到這,感謝您的閱讀。

回目錄

繼續閱讀|回目錄

Reference:

--

--

春麗 S.T.E.M.
春麗 S.T.E.M.

Written by 春麗 S.T.E.M.

Do not go gentle into that good night, Old age should burn and rave at close of day; Rage, rage, against the dying of the light.

No responses yet