Table of Contents
Toggle導言:ESP-NOW 是什麼?為什麼這麼強大?
如果你曾經使用過 ESP32,就會知道它支援 Wi-Fi 和藍牙,但你是否知道它還有一項超方便的「隱藏技能」——ESP-NOW?
這是一種由 Espressif(樂鑫) 開發的點對點無線傳輸協定,可以讓多個 ESP32 裝置彼此直接傳遞資料,不需要 Wi-Fi AP 或路由器!
想像一下,你可以讓幾台 ESP32 在沒有網路的地方彼此交換資料,例如感測器、遙控器、無線節點網路……這就是 ESP-NOW 的魅力所在。
ESP-NOW 是如何運作的?
ESP-NOW 是基於 2.4GHz 頻段 的通訊協定,使用與 Wi-Fi 相同的射頻硬體,但資料封包更簡潔輕量。
它透過裝置的 MAC Address(媒體存取控制位址) 來識別彼此,因此在網路架構上屬於「點對點(Peer-to-Peer)」。
每個節點可以:
- 同時與多達 20 個裝置通訊
- 不需 Wi-Fi 連線即可傳輸資料
- 支援雙向通訊與加密模式
ESP-NOW 單向通信
首先介紹單向傳輸
- 一塊 ESP32 開發板向另一塊 ESP32 開發板發送數據
這種配置非常容易實現,非常適合將資料從一塊板發送到另一塊板,例如感測器讀數或控制 GPIO 的開啟和關閉命令。
準備開始前:你需要的設備
- 兩塊 ESP32 開發板
- USB 傳輸線
- Arduino IDE
優良廠商推薦:
提示:
確保你安裝了 Arduino IDE 的 ESP32 核心模組,並在「工具 → 開發板」中選擇 ESP32 Dev Module。
Arduino IDE設定教學,請參考之前教學"ESP32的創新與應用:引領未來技術趨勢"
聯盟行銷揭露: AIoT Brian參與了聯盟行銷計劃,該計劃旨在透過連結到蝦皮 和其他網站來賺取佣金。我們可能會因向這些公司推薦流量和業務而獲得報酬。
建立第一個 ESP-NOW 傳送端與接收端
步驟 1:取得接收端 MAC Address
提醒:上傳程式後,按ESP32控制板USB埠旁的EN鈕,它就會出現在”序列埠監控視窗”,記得先把這MAC Address抄寫下來,待會要填入程式中
#include
#include
void readMacAddress(){
uint8_t baseMac[6];
esp_err_t ret = esp_wifi_get_mac(WIFI_IF_STA, baseMac);
if (ret == ESP_OK) {
Serial.printf("%02x:%02x:%02x:%02x:%02x:%02x\n",
baseMac[0], baseMac[1], baseMac[2],
baseMac[3], baseMac[4], baseMac[5]);
} else {
Serial.println("Failed to read MAC address");
}
}
void setup(){
Serial.begin(115200);
WiFi.mode(WIFI_STA);
WiFi.STA.begin();
Serial.print("[DEFAULT] ESP32 Board MAC Address: ");
readMacAddress();
}
void loop(){
}
ESP-NOW 單向點對點通信
為了幫助您開始使用 ESP-NOW 無線通信,我們將建立一個簡單的項目,示範如何從一個 ESP32 向另一個 ESP32 發送訊息。其中一個 ESP32 將作為“發送方”,另一個 ESP32 將作為“接收方”。
為了更好地理解,我們將 ESP32 #1 稱為“發送者”,將 ESP32 #2 稱為“接收者”。
ESP32 #1 發送者程式 (ESP-NOW)
#include
#include
// 填入接收者的MAC Address
uint8_t broadcastAddress[] = { 0x44, 0x17, 0x93, 0xec, 0xac, 0x74 };
// 建立一個矩陣資料,做為傳輸資料
typedef struct struct_message {
char a[32];
int b;
float c;
bool d;
} struct_message;
// 建立矩陣資料為"mydata"
struct_message myData;
esp_now_peer_info_t peerInfo;
// 當資料傳輸後回應訊息是否"成功"或"失敗"
void OnDataSent(const wifi_tx_info_t *tx_info, esp_now_send_status_t status) {
Serial.print("Last Packet Send Status: ");
Serial.println(status == ESP_NOW_SEND_SUCCESS ? "傳輸成功" : "傳輸失敗");
}
void setup() {
// 序列埠鮑率
Serial.begin(115200);
// 將裝置設定為 Wi-Fi站
WiFi.mode(WIFI_STA);
// 切始化ESP-NOW
if (esp_now_init() != ESP_OK) {
Serial.println("Error initializing ESP-NOW");
return;
}
// 成功初始化 ESP-NOW 後,註冊傳送訊息時呼叫的回呼函數
esp_now_register_send_cb(OnDataSent);
// 與另一個 ESP-NOW 裝置配對以發送資料
memcpy(peerInfo.peer_addr, broadcastAddress, 6);
peerInfo.channel = 0;
peerInfo.encrypt = false;
// 加入接收端訊息
if (esp_now_add_peer(&peerInfo) != ESP_OK) {
Serial.println("連結端失敗");
return;
}
}
void loop() {
// 每2秒傳輸一條訊息
strcpy(myData.a, "這是字元");
myData.b = random(1, 20);
myData.c = 1.2;
myData.d = false;
// 透過ESP-NOW傳輸訊息
esp_err_t result = esp_now_send(broadcastAddress, (uint8_t *)&myData, sizeof(myData));
//檢查訊息是否發送成功
if (result == ESP_OK) {
Serial.println("傳送訊息成功");
} else {
Serial.println("傳送訊息失敗");
}
delay(2000);
}
ESP32 #2 接收者程式(ESP-NOW)
#include
#include
// 接收傳送方的矩陣資料,這對應格式必須相同
typedef struct struct_message {
char a[32];
int b;
float c;
bool d;
} struct_message;
// 矩陣資料稱為"myData"
struct_message myData;
// 收到資料時會執行的回呼函數
void OnDataRecv(const uint8_t * mac, const uint8_t *incomingData, int len) {
memcpy(&myData, incomingData, sizeof(myData));
Serial.print("Bytes received: ");
Serial.println(len);
Serial.print("Char: ");
Serial.println(myData.a);
Serial.print("Int: ");
Serial.println(myData.b);
Serial.print("Float: ");
Serial.println(myData.c);
Serial.print("Bool: ");
Serial.println(myData.d);
Serial.println();
}
void setup() {
// 序列埠鮑率
Serial.begin(115200);
// 將裝置設定為Wi-Fi站
WiFi.mode(WIFI_STA);
// 與另一個 ESP-NOW 裝置配對
if (esp_now_init() != ESP_OK) {
Serial.println("Error initializing ESP-NOW");
return;
}
// 接收到訊息時呼叫的回呼函數
esp_now_register_recv_cb(esp_now_recv_cb_t(OnDataRecv));
}
void loop() {
}
實戰應用案例:無線感測網
假設你有 5 個溫濕度節點,每個節點透過 ESP-NOW 將資料傳給一台主控 ESP32,再由主控上傳至雲端伺服器。
這種架構常見於溫室監測、智慧農業或倉儲管理中。
結語
ESP-NOW 是 ESP32 的「隱藏武器」,能讓你在無網環境下實現高效、低延遲的無線通訊。
無論是遠端感測、無線控制還是 IoT 節點網,ESP-NOW 都能讓你的專案更靈活、更節能!
常見問答 (FAQ)
Q1:ESP-NOW 可以穿牆傳輸嗎?
可以,但距離會受牆體材質影響,建議使用外接天線版本。
Q2:ESP32-S2 / S3 支援 ESP-NOW 嗎?
是的,Espressif 官方已在 SDK 中提供支援。
Q3:ESP-NOW 可以和 ESP8266 通訊嗎?
可以,但需確保韌體版本相容,並使用相同通道。
Q4:ESP-NOW 傳輸距離多遠?
在空曠環境約 150 公尺,視天線與功率而定。
Q5:能否與手機直接通訊?
不行,ESP-NOW 為 ESP 專用協定,手機不支援此模式。
參考資料
RANDOM NERD TUTORIALS教學網站之Getting Started with ESP-NOW: https://randomnerdtutorials.com/esp-now-esp32-arduino-ide/
