加入星計(jì)劃,您可以享受以下權(quán)益:

  • 創(chuàng)作內(nèi)容快速變現(xiàn)
  • 行業(yè)影響力擴(kuò)散
  • 作品版權(quán)保護(hù)
  • 300W+ 專業(yè)用戶
  • 1.5W+ 優(yōu)質(zhì)創(chuàng)作者
  • 5000+ 長期合作伙伴
立即加入
  • 正文
    • 氣象站項(xiàng)目預(yù)覽
    • ESP-NOW概述
    • ESP-NOW的優(yōu)勢
    • ESP-NOW通信
    • 硬件
    • 軟件
  • 推薦器件
  • 相關(guān)推薦
  • 電子產(chǎn)業(yè)圖譜
申請入駐 產(chǎn)業(yè)圖譜

老宇哥帶你玩轉(zhuǎn) ESP32:14 親自動(dòng)手做一個(gè)雙向通訊的無線遙控器(一)

09/21 15:44
5.3萬
閱讀需 19 分鐘
加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點(diǎn)資訊討論

今天我們來玩兒ESP-NOW。

相信每個(gè)玩電子的童鞋對無線通信都非常感興趣,從孩童時(shí)期的無線遙控賽車,到學(xué)生時(shí)期的收音機(jī),到長大后接觸的各種無線控制的家電,手機(jī)等電子產(chǎn)品,無線通信讓我們可以像神話小說中的某些絕技,可以做到隔空控制,每個(gè)人都都希望將那個(gè)遙控器掌握在自己手中。

無線遙控的本質(zhì)就是發(fā)射端發(fā)射某個(gè)頻率的電磁波出去,接收端接收并解碼這個(gè)信號。我們經(jīng)常接觸的空調(diào),電視,風(fēng)扇等遙控器很多都是紅外的,頻率大多是38Khz;窗簾,車庫門等大多是315MHz或者433MHz;國外有868MHz、915MHz等;低于1Ghz的泛稱為Sub 1Ghz,不同國家有不同的免費(fèi)頻率段;燈,手機(jī)等大多是用2.4Ghz的,2.4G這個(gè)頻段用的比較多,這個(gè)頻段在全球是免費(fèi)使用的,我們熟知的WiFi、藍(lán)牙、Zigbee的都是2.4Ghz的;當(dāng)然還有NBIOT,2G,4G,5G,長波,中波,短波等很多頻率的設(shè)備。理論來說,在相同功率下,低頻能獲得更好的傳送距離,高頻有更好的抗干擾性能,不同領(lǐng)域根據(jù)自身特性選擇最合適的通信頻率。

氣象站項(xiàng)目預(yù)覽

ESP-NOW概述

ESP-NOW 是由 Espressif 開發(fā)的一種協(xié)議,它使多個(gè)設(shè)備能夠在不使用 Wi-Fi 的情況下相互通信。該協(xié)議類似于無線鼠標(biāo)中用的2.4GHz無線連接。因此,設(shè)備之間的配對需要在它們通信之前進(jìn)行。配對完成后,連接是安全且點(diǎn)對點(diǎn)的,無需握手,也就是他不像TCP/IP等是長連接的,換句話說,它是無連接的,如果其中一個(gè)板子突然斷電,重新啟動(dòng)后,會(huì)自動(dòng)匹配它的連接設(shè)備繼續(xù)通信。

不同于傳統(tǒng)的OSI模型,ESP-NOW去掉了其中一些層,只保留最基本的傳輸層,減少了網(wǎng)絡(luò)擁堵造成的丟包延遲,實(shí)現(xiàn)快速響應(yīng)。簡單來說,ESP-NOW 是一種快速通信協(xié)議,可用于在 ESP32 板之間交換短消息(單次最多 250 字節(jié))。

ESP-NOW的優(yōu)勢

  • 快速響應(yīng):開機(jī)后,設(shè)備無需任何無線連接即可直接傳輸數(shù)據(jù)和控制其他配對設(shè)備,響應(yīng)速度以毫秒為單位;
  • 遠(yuǎn)距離通信:ESP-NOW 支持遠(yuǎn)距離通信,板載天線戶外空曠距離能達(dá)到200米+
  • 多跳控制:ESP-NOW可以實(shí)現(xiàn)設(shè)備的多跳控制,可通過單播、廣播和群控方式控制數(shù)百臺設(shè)備;
  • 新配網(wǎng)方式:提供了除 Wi-Fi 和藍(lán)牙之外的新方式,通過藍(lán)牙為第一臺設(shè)備配置網(wǎng)絡(luò),其他設(shè)備不需要配置SSID/密碼等信息,第一臺連接到網(wǎng)絡(luò)的設(shè)備可以直接將這些信息發(fā)送給其他設(shè)備
  • 升級:可用于固件升級或者大量數(shù)據(jù)升級的場景;
  • 調(diào)試:在一些高溫高壓等不太方便的場合,可以接收多個(gè)設(shè)備的數(shù)據(jù),快速診斷設(shè)備故障。
  • 低成本:可與WiFi,藍(lán)牙等共存
  • 安全:ESP-NOW 采用 CCMP 方法保護(hù)供應(yīng)商特定動(dòng)作幀的安全,具體可參考 IEEE Std. 802.11-2012。

ESP-NOW通信

單向通信

一個(gè)從機(jī)向一個(gè)主機(jī)發(fā)送數(shù)據(jù)

這種情況適用于一個(gè)設(shè)備向另一個(gè)設(shè)備單向發(fā)送數(shù)據(jù),比如一個(gè)從機(jī)采集傳感器數(shù)據(jù)或?qū)?a class="article-link" target="_blank" href="/tag/%E5%BC%80%E5%85%B3/">開關(guān)量發(fā)送到主機(jī)。

一個(gè)主機(jī)向多個(gè)從機(jī)發(fā)送數(shù)據(jù)

一個(gè)從機(jī)從多個(gè)主機(jī)接收數(shù)據(jù)

雙向通信

主機(jī)與從機(jī)互相通信

多個(gè)設(shè)備之間互相通信

ESP-NOW非常適合組建一個(gè)小型網(wǎng)絡(luò),可以讓多個(gè)ESP32之間交換數(shù)據(jù)。

硬件

基本演示不需要加入其它外設(shè),板子接上串口助手觀察就好了。

軟件

獲取板子的MAC地址

ESP-NOW是通過MAC地址做為不同設(shè)備的唯一識別的,就像不同設(shè)備的ID碼一樣,當(dāng)然我們可以通過掃描配對的方式去自動(dòng)配對,這里為了方便展示程序原理,我們就先采用最基本的方式,先通過下面的代碼獲取主機(jī)設(shè)備的MAC地址。

#include?"WiFi.h"
?
void?setup(){
??Serial.begin(115200);
??WiFi.mode(WIFI_MODE_STA);
??Serial.println(WiFi.macAddress());
}
?
void?loop(){

}

獲取到主機(jī)的MAC地址后,我們記下來。

初始化ESP-NOW

初始化ESP-NOW,在這個(gè)函數(shù)調(diào)用之前必須初始化WiFi。

esp_now_init();

添加配對設(shè)備

調(diào)用此函數(shù)配對設(shè)備,將MAC地址,通道,加密信息等進(jìn)行配置。

esp_now_add_peer();

發(fā)送數(shù)據(jù)

向配對設(shè)備發(fā)送數(shù)據(jù)

esp_now_send();

發(fā)送數(shù)據(jù)回調(diào)函數(shù)

注冊一個(gè)發(fā)送數(shù)據(jù)時(shí)調(diào)用的函數(shù),此函數(shù)會(huì)返回是否發(fā)送成功的消息。

esp_now_register_send_cb();

接收數(shù)據(jù)回調(diào)函數(shù)

注冊一個(gè)接收到數(shù)據(jù)時(shí)調(diào)用的函數(shù)。

esp_now_register_rcv_cb();

還有其它一些函數(shù),我們用到的時(shí)候再講。

完整發(fā)送程序

我們將之前打印的MAC地址保存下來,替換到broadcastAddress數(shù)組中。代碼中,首先定義了一個(gè)結(jié)構(gòu)體,包含幾種不同類型的數(shù)據(jù)變量,這個(gè)就是我們要發(fā)送的數(shù)據(jù),在setup()中先設(shè)置WiFi工作在STA模式,然后調(diào)用esp_now_init()初始化,將配對設(shè)備的信息進(jìn)行添加,簡單配置一下發(fā)送回調(diào)函數(shù),打印是否發(fā)送成功,主函數(shù)中,每2秒發(fā)送一次數(shù)據(jù)。esp_now_send返回是否發(fā)送出去,回調(diào)函數(shù)中展示是否成功發(fā)送給接收方。

#include?<esp_now.h>
#include?<WiFi.h>

//?REPLACE?WITH?YOUR?RECEIVER?MAC?Address
uint8_t?broadcastAddress[]?=?{0x8C,?0xCE,?0x4E,?0xA6,?0x73,?0x74};

//?Structure?example?to?send?data
//?Must?match?the?receiver?structure
typedef?struct?struct_message?{
??char?a[32];
??int?b;
??float?c;
??bool?d;
}?struct_message;

//?Create?a?struct_message?called?myData
struct_message?myData;

esp_now_peer_info_t?peerInfo;

//?callback?when?data?is?sent
void?OnDataSent(const?uint8_t?*mac_addr,?esp_now_send_status_t?status)?{
??Serial.print("rnLast?Packet?Send?Status:t");
??Serial.println(status?==?ESP_NOW_SEND_SUCCESS???"Delivery?Success"?:?"Delivery?Fail");
}
?
void?setup()?{
??//?Init?Serial?Monitor
??Serial.begin(115200);
?
??//?Set?device?as?a?Wi-Fi?Station
??WiFi.mode(WIFI_STA);

??//?Init?ESP-NOW
??if?(esp_now_init()?!=?ESP_OK)?{
????Serial.println("Error?initializing?ESP-NOW");
????return;
??}

??//?Once?ESPNow?is?successfully?Init,?we?will?register?for?Send?CB?to
??//?get?the?status?of?Trasnmitted?packet
??esp_now_register_send_cb(OnDataSent);
??
??//?Register?peer
??memcpy(peerInfo.peer_addr,?broadcastAddress,?6);
??peerInfo.channel?=?0;??
??peerInfo.encrypt?=?false;
??
??//?Add?peer????????
??if?(esp_now_add_peer(&peerInfo)?!=?ESP_OK){
????Serial.println("Failed?to?add?peer");
????return;
??}
}
?
void?loop()?{
??//?Set?values?to?send
??strcpy(myData.a,?"THIS?IS?A?CHAR");
??myData.b?=?random(1,20);
??myData.c?=?1.2;
??myData.d?=?false;
??
??//?Send?message?via?ESP-NOW
??esp_err_t?result?=?esp_now_send(broadcastAddress,?(uint8_t?*)?&myData,?sizeof(myData));
???
??if?(result?==?ESP_OK)?{
????Serial.println("Sent?with?success");
??}
??else?{
????Serial.println("Error?sending?the?data");
??}
??delay(2000);
}

完整接收程序

接收跟發(fā)送差不多,也是要定義一個(gè)跟發(fā)送方一樣的數(shù)據(jù)結(jié)構(gòu)體,用于保存接收到的數(shù)據(jù),創(chuàng)建一個(gè)接收回調(diào)函數(shù),當(dāng)接收到數(shù)據(jù)時(shí),調(diào)用此函數(shù),將數(shù)據(jù)保存到一個(gè)結(jié)構(gòu)體變量中,然后打印出來。

#include?<esp_now.h>
#include?<WiFi.h>

//?Structure?example?to?receive?data
//?Must?match?the?sender?structure
typedef?struct?struct_message?{
????char?a[32];
????int?b;
????float?c;
????bool?d;
}?struct_message;

//?Create?a?struct_message?called?myData
struct_message?myData;

//?callback?function?that?will?be?executed?when?data?is?received
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()?{
??//?Initialize?Serial?Monitor
??Serial.begin(115200);
??
??//?Set?device?as?a?Wi-Fi?Station
??WiFi.mode(WIFI_STA);

??//?Init?ESP-NOW
??if?(esp_now_init()?!=?ESP_OK)?{
????Serial.println("Error?initializing?ESP-NOW");
????return;
??}
??
??//?Once?ESPNow?is?successfully?Init,?we?will?register?for?recv?CB?to
??//?get?recv?packer?info
??esp_now_register_recv_cb(OnDataRecv);
}
?
void?loop()?{

}

將上面的發(fā)送與接收程序燒錄到兩塊板,就實(shí)現(xiàn)了數(shù)據(jù)的單向傳輸,我們看下接收方的串口打印數(shù)據(jù):

這是最簡單的一個(gè)案例,大家對ESP-NOW先有一個(gè)簡單的理解,關(guān)于ESP-NOW的管理設(shè)備,刪除設(shè)備,掃描從設(shè)備,自動(dòng)配對等,下一期再講,布置個(gè)作業(yè),大家可以在發(fā)送端添加一個(gè)按鈕,接收端添加一個(gè)LED等,就可以實(shí)現(xiàn)一個(gè)遙控器的Demo了,快去嘗試一下吧。

下一節(jié),我們會(huì)實(shí)際做一個(gè)小項(xiàng)目,增加以下功能:

  • 多個(gè)主機(jī),多個(gè)從機(jī);從機(jī)按鍵長按觸發(fā)下進(jìn)入廣播模式,釋放出WIFI信號,主機(jī)在上電的時(shí)候,會(huì)掃描到WIFI信號并自動(dòng)配對;配對完成之后,主機(jī)從機(jī)都會(huì)將MAC地址自動(dòng)寫入存儲(chǔ)空間,下次啟動(dòng)就不用重新配對;兩個(gè)從機(jī)可以通過按鍵控制主機(jī)上的兩個(gè)LED燈,主機(jī)也可以同時(shí)控制兩個(gè)從機(jī)上的LED燈;兩個(gè)從機(jī)分別采集溫度濕度氣壓數(shù)據(jù),傳給主機(jī);主機(jī)將數(shù)據(jù)在本地顯示屏顯示出來,同時(shí)在連接WiFi之后,可以通過Web端實(shí)時(shí)查看傳感器數(shù)據(jù);指示燈顯示連接狀態(tài)。

感謝大家,關(guān)于ESP32的學(xué)習(xí),希望大家Enjoy!

參考資料:

1、https://docs.espressif.com/projects/esp-idf/zh_CN/latest/esp32/api-reference/network/esp_now.html

2、https://randomnerdtutorials.com/esp-now-esp32-arduino-ide/

3、https://github.com/espressif/esp-now

推薦器件

更多器件
器件型號 數(shù)量 器件廠商 器件描述 數(shù)據(jù)手冊 ECAD模型 風(fēng)險(xiǎn)等級 參考價(jià)格 更多信息
EL4581CSZ 1 Intersil Corporation Sync Separator, 50% Slice, S-H, Filter; SOIC8; Temp Range: -40&deg; to 85&deg;C
$7.2 查看
ISL59601IRZ-T7 1 Intersil Corporation MegaQ&trade;: An Automatic Composite Video Equalizer, Fully-Adaptive to 1 Mile (1600m); QFN20; Temp Range: -40&deg; to 85&deg;C
$73.01 查看
MAX9768ETG+T 1 Maxim Integrated Products Volume Control Circuit,
$3.31 查看

相關(guān)推薦

電子產(chǎn)業(yè)圖譜

最全電子漫畫收集達(dá)人,漫畫控必選!用文字和圖片帶你領(lǐng)略電子世界之美。 由曉宇哥哥操刀的芯片之家公眾號,提供45萬個(gè)Symbol和3D封裝庫免費(fèi)下載,定期分享軟硬件、物聯(lián)網(wǎng)類技術(shù)知識外,還精心整理大量參考設(shè)計(jì)和文檔資源,電路圖和源代碼資料供下載。 立即打開“芯片之家 ”,感受電子與藝術(shù)的完美結(jié)合。