ESP-NOW: ESP32項(xiàng)目的即時(shí)無線通信
ESP-NOW使無線ESP32通信變得簡單。廣播傳感器數(shù)據(jù)或立即創(chuàng)建設(shè)備到設(shè)備的網(wǎng)絡(luò),用最少的代碼。
忘掉NRF、藍(lán)牙、433MHz模塊——甚至Wi-Fi!有一種更好的無線方式。我是來自educ8s的尼克。今天,我要向你們展示的是ESP32內(nèi)置的一種改變游戲規(guī)則的協(xié)議,它可以讓你的設(shè)備即時(shí)、可靠地通話,而且沒有傳統(tǒng)無線設(shè)置的麻煩。
我們將用它來建立一個(gè)無線氣象站,在esp32之間傳輸實(shí)時(shí)傳感器數(shù)據(jù),并將其顯示在大屏幕上,我們將在不到10分鐘的時(shí)間內(nèi)完成。你準(zhǔn)備好升級你的無線游戲了嗎?我們開始吧!
部件清單
?ESP32
?ESP32S3
?BME280傳感器
?2.8" ILI9341顯示屏
?USB電纜
?試驗(yàn)板(可選)
?跳線
步驟1:ESP-NOW:快速概述
你知道這個(gè)小小的ESP32板…在不使用Wifi的情況下,我們已經(jīng)擁有了將數(shù)據(jù)無線發(fā)送到另一臺設(shè)備所需的一切?這是正確的!沒有任何額外的模塊,天線或其他任何東西!這一切都是與生俱來的!這要感謝一種叫做ESP-NOW的東西。
ESP-NOW是ESP32的制造商expressif開發(fā)的一種輕量級無連接無線協(xié)議。Wi-Fi或藍(lán)牙需要握手、認(rèn)證和復(fù)雜的設(shè)置過程,而ESP-NOW不同,它允許設(shè)備之間即時(shí)直接通信??梢园阉胂蟪蒭sp32的對講機(jī)系統(tǒng)——一臺設(shè)備發(fā)送數(shù)據(jù),另一臺設(shè)備接收數(shù)據(jù),而不需要互聯(lián)網(wǎng)連接、路由器,甚至不需要事先配對。這使得它快速,高效,并且非常容易用于物聯(lián)網(wǎng)項(xiàng)目,傳感器網(wǎng)絡(luò)和實(shí)時(shí)數(shù)據(jù)共享。
ESP-NOW最大的優(yōu)點(diǎn)之一是它的低功耗。因?yàn)樗灰蕾囉诔掷m(xù)的網(wǎng)絡(luò)連接或后臺通信開銷,所以非常適合遠(yuǎn)程傳感器、氣象站和智能家居設(shè)備等電池供電的應(yīng)用。它還支持一對一、一對多甚至多對多通信,這意味著您可以建立一個(gè)由ESP設(shè)備組成的網(wǎng)絡(luò),方便地交換數(shù)據(jù)。盡管它很簡單,但ESP-NOW可以加密數(shù)據(jù)以確保安全,使其成為傳統(tǒng)無線選項(xiàng)的強(qiáng)大而輕便的替代品。
好的,太棒了!現(xiàn)在你知道了ESP-NOW是什么,讓我們實(shí)際一點(diǎn)。在本指南中,我們將展示最簡單的方法來開始使用ESP-NOW。我們將設(shè)置一個(gè)ESP32來發(fā)送消息…但不是針對任何特定的設(shè)備!
而不是針對一個(gè)特定的地址,我們將使用一種叫做廣播的東西。這意味著我們發(fā)送的ESP32將向任何正在收聽ESP-NOW頻道的人發(fā)出它的信息。
最酷的是……附近的任何ESP32設(shè)備都可以接收到此消息!不需要預(yù)編程地址,不需要復(fù)雜的配對列表。只需將數(shù)據(jù)發(fā)送到無線以太網(wǎng),任何準(zhǔn)備好偵聽的ESP32都可以接收到數(shù)據(jù)。
這對于簡單的數(shù)據(jù)廣播來說是完美的,就像我們的氣象站,我們想要發(fā)送傳感器讀數(shù)給任何顯示單元。
請記住,ESP-NOW實(shí)際上是一個(gè)非常先進(jìn)的協(xié)議,具有許多功能,但今天我們只是邁出了我們的第一步,我將準(zhǔn)備更多先進(jìn)的視頻,以探索其未來的全部潛力。
步驟2:設(shè)置你的第一個(gè)ESP-NOW項(xiàng)目
為了使ESP-NOW的使用變得非常簡單,我創(chuàng)建了一個(gè)特殊的ESPNowEasy類!這個(gè)類以兩個(gè)簡單文件的形式提供——一個(gè)espno鼬.h文件和一個(gè)espno鼬.cpp文件。您只需要將這兩個(gè)文件包含在您的Arduino項(xiàng)目中,然后您將擁有這個(gè)類的所有魔力!
在Arduino代碼中使用這個(gè)類之前,我們需要導(dǎo)入它的頭文件。就像使用任何Arduino庫一樣,您可以在草圖的最頂部使用#include語句完成此操作。
這使得ESPNowEasy類的所有特性都可以在你的代碼中使用。
現(xiàn)在,在我們創(chuàng)建“ESP-NOW助手”對象之前,我們首先需要告訴ESPNowEasy類它將發(fā)送什么樣的數(shù)據(jù)。記得嗎,在我們的基本例子中,我們說過我們會(huì)發(fā)送一個(gè)數(shù)字和一條消息?為了定義這些數(shù)據(jù),我們創(chuàng)建了一個(gè)自定義數(shù)據(jù)結(jié)構(gòu)。可以把它想象成設(shè)計(jì)一個(gè)特殊的“盒子”來保存我們的特定數(shù)據(jù)。
它看起來像這樣:};在這個(gè)結(jié)構(gòu)體中,我們定義了“盒子”將保存的數(shù)據(jù)塊。對于我們的例子,我們想要發(fā)送:
?一個(gè)整數(shù),我們叫它c(diǎn)ounter。
?還有一個(gè)消息——一個(gè)文本字符串,“Hello World!”,存儲在一個(gè)名為text的字符數(shù)組中。
一旦我們定義了這個(gè)消息結(jié)構(gòu)——告訴ESPNowEasy期待什么樣的數(shù)據(jù)——那么我們就可以創(chuàng)建ESPNowEasy對象,我們的“ESP-NOW助手”。當(dāng)我們創(chuàng)建這個(gè)對象時(shí),我們需要告訴它要使用哪個(gè)消息結(jié)構(gòu)。
我們用這行來做:
看到了嗎?只需一行,我們現(xiàn)在就有了espNow對象,專門設(shè)計(jì)用于處理消息數(shù)據(jù)類型,準(zhǔn)備好使無線通信變得超級簡單!
步驟3:發(fā)送代碼:發(fā)送計(jì)數(shù)器和文本
現(xiàn)在,讓我們發(fā)送一條消息。首先,我們需要初始化ESP-NOW協(xié)議。在我們的ESPNowEasy類中,這非常簡單-只需使用這一行:
接下來,讓我們準(zhǔn)備第一個(gè)數(shù)據(jù)包。我們將計(jì)數(shù)器設(shè)置為0,并將短信設(shè)置為“Hello World!”。一旦我們的dataToSend結(jié)構(gòu)中填充了這些信息,無線發(fā)送它就很容易了:
這就是它的全部!信不信由你,使用ESPNowEasy庫,發(fā)送數(shù)據(jù)真的很簡單——只需要幾行代碼。為了使我們的示例更具動(dòng)態(tài)性,讓我們將數(shù)據(jù)發(fā)送和計(jì)數(shù)器增量移到loop()函數(shù)中。這樣,我們可以在發(fā)送每個(gè)消息后增加計(jì)數(shù)器,確保每次傳輸不同的值。最后,在每次發(fā)送之間增加一秒鐘的短暫延遲,將使觀察數(shù)據(jù)傳輸變得更容易。
以下是完整的發(fā)射機(jī)代碼:
步驟4:接收代碼:顯示接收到的數(shù)據(jù)
現(xiàn)在,讓我們創(chuàng)建接收器草圖。接收方代碼和發(fā)送方代碼一樣簡單!事實(shí)上,它有很多相似之處。
首先,就像發(fā)送方一樣,接收方需要理解它將要接收的消息的結(jié)構(gòu)。這意味著我們需要在接收器代碼中定義完全相同的Message結(jié)構(gòu)!
接下來,就像在發(fā)送器中一樣,我們創(chuàng)建ESPNowEasy對象,專門用于處理我們的消息數(shù)據(jù)類型,如下所示:
現(xiàn)在,在setup()函數(shù)中,第一個(gè)關(guān)鍵步驟是使用espNow.begin();初始化ESP-NOW協(xié)議本身。然后,我們通過調(diào)用onReceive()方法并告訴它使用我們的onmessagerreceived函數(shù)作為處理程序來配置接收器以偵聽傳入的消息。
可以把這個(gè)函數(shù)看作是ESP32接收器內(nèi)的一個(gè)專門的小工作人員。它唯一的工作就是耐心地等待無線ESP-NOW消息到達(dá)。當(dāng)有消息進(jìn)來時(shí),這個(gè)功能會(huì)自動(dòng)啟動(dòng)!
這種類型的函數(shù)通常被稱為“回調(diào)函數(shù)”。它不是我們在主循環(huán)()中直接調(diào)用的函數(shù)。相反,我們用這行代碼注冊它:espNow.onReceive(onmessagerreceived);在注冊之后,ESPNowEasy庫接管并在新消息到達(dá)時(shí)自動(dòng)為我們調(diào)用onmessagerreceived函數(shù)。在onmessagerreceived函數(shù)中,魔術(shù)變量是receivedMessage。
注意,receivedMessage的類型是Message&。這意味著它是對Message結(jié)構(gòu)的引用。當(dāng)ESPNowEasy調(diào)用onmessagerreceived時(shí),它會(huì)自動(dòng)用來自無線接收消息的數(shù)據(jù)填充這個(gè)receivedMessage結(jié)構(gòu)!
因此,在onmessagerreceived中,我們可以使用receivedMessage直接訪問來自傳入消息的數(shù)據(jù)。計(jì)數(shù)器和receivedMessage.text。然后,我們可以對接收到的數(shù)據(jù)做任何我們想做的事情——在我們的示例中,我們只是將其打印到串行監(jiān)視器。但在實(shí)際項(xiàng)目中,您可能會(huì)使用這些數(shù)據(jù)來更新顯示、控制電機(jī)、觸發(fā)動(dòng)作或任何您可以想象的事情!
以下是完整的接收器代碼:
步驟5:測試基本ESP-NOW通信
我們快到了!現(xiàn)在是時(shí)候?qū)ξ覀兊拇a進(jìn)行測試了。
首先,確保您已將發(fā)射器代碼上傳到一個(gè)ESP32板,并將接收器代碼上傳到另一個(gè)ESP32板。
在Arduino IDE中打開接收器ESP32的串行監(jiān)視器。將波特率設(shè)置為115200,與代碼中的Serial.begin()調(diào)用相匹配。
一旦兩個(gè)ESP32板都上電,您應(yīng)該開始看到消息出現(xiàn)在接收器的串行監(jiān)視器中。輸出應(yīng)該看起來像這樣:
您將注意到計(jì)數(shù)器的值隨著接收到的每條消息的增加而增加,這表明正在成功地傳輸和接收數(shù)據(jù)。
為了真正向您展示ESP-NOW的多功能,我甚至將使用不同的ESP32型號作為接收器-這次是ESP32- s3板!看看這個(gè),效果很好!在串行監(jiān)視器上,我們可以看到無線發(fā)送的消息!這表明ESP-NOW廣播與各種ESP32板兼容。
如果沒有看到任何輸出,請仔細(xì)檢查以下內(nèi)容:
?接線:確保兩塊ESP32板都已正確接通電源。
?波特率:確保串口監(jiān)視器的波特率為115200。
?代碼上傳:檢查每個(gè)ESP32上傳的代碼是否正確。
?距離:確保ESP32板之間的距離在合理范圍內(nèi)。
一旦您在串行監(jiān)視器中看到消息,您就已經(jīng)成功地使用ESP-NOW和ESPNowEasy類在兩個(gè)ESP32板之間建立了基本的無線通信!
步驟6:搭建無線氣象站:發(fā)射機(jī)
現(xiàn)在我們有了基本的ESP-NOW通信的堅(jiān)實(shí)基礎(chǔ),讓我們繼續(xù)我們的無線氣象站項(xiàng)目。我們將從修改發(fā)射器代碼開始,從BME280傳感器發(fā)送真實(shí)世界的傳感器數(shù)據(jù)。
正如您所料,主要的調(diào)整是修改我們的數(shù)據(jù)結(jié)構(gòu)以匹配傳感器讀數(shù)。讓我們看一下氣象站的WeatherData結(jié)構(gòu)。你會(huì)發(fā)現(xiàn),我們已經(jīng)重新設(shè)計(jì)了“數(shù)據(jù)盒”,專門用來保存溫度、濕度和壓力值。
下面是新的WeatherData結(jié)構(gòu):
我們現(xiàn)在不再使用直接的Adafruit BME280庫調(diào)用,而是使用一個(gè)單獨(dú)的Sensor .h文件和一個(gè)Sensor類來封裝傳感器交互。這使得主代碼更簡潔、更有條理。
以下是更新后的發(fā)射機(jī)代碼:
變更說明:
?#include "sensor.h":包含自定義傳感器處理代碼。
?Sensor Sensor (true);:創(chuàng)建一個(gè)Sensor對象,初始化它以使用公制系統(tǒng)。
?sensor.begin():通過sensor類初始化BME280傳感器。
?sensor. gettemperature()、sensor. gethumidity()、sensor. getpressure():使用sensor類的方法檢索傳感器數(shù)據(jù)。
?錯(cuò)誤處理:增加了espNow.begin()和sensor.begin()的檢查,以確保正確的初始化。
?2000ms延遲:延遲已更改為2000ms。
接線說明:
有關(guān)BME280傳感器連接到ESP32的詳細(xì)說明,請參閱附件接線圖。確保傳感器的VCC、GND、SDA和SCL引腳正確連接。
現(xiàn)在,把這個(gè)代碼上傳到你的ESP32發(fā)射機(jī)。您將開始看到傳感器數(shù)據(jù)以無線方式發(fā)送!
步驟7:搭建無線氣象站:接收器
現(xiàn)在,讓我們把注意力轉(zhuǎn)向氣象站的接收端。我們將修改接收器代碼,以便在il9341顯示器上顯示傳入的天氣數(shù)據(jù)。
首先,我們需要包括必要的庫并定義WeatherData結(jié)構(gòu),就像在發(fā)送器代碼中一樣。我們還將包含一個(gè)定制的display .h文件來處理顯示交互。
接收器代碼中的關(guān)鍵變化是:
?包括display. h文件:這允許我們與ILI9341顯示器進(jìn)行交互。
?創(chuàng)建顯示對象:該對象將管理顯示。
定義onWeatherDataReceived回調(diào)函數(shù):該函數(shù)對于處理傳入的天氣數(shù)據(jù)至關(guān)重要。函數(shù)如下:
當(dāng)ESP32從發(fā)射器接收到天氣數(shù)據(jù)時(shí),該功能自動(dòng)觸發(fā)。它首先將接收到的數(shù)據(jù)打印到串行監(jiān)視器進(jìn)行調(diào)試和驗(yàn)證。然后,它調(diào)用display.update()函數(shù),傳遞接收到的數(shù)據(jù),以更新ILI9341的顯示。
?在setup()函數(shù)中初始化顯示:我們調(diào)用display.begin()來設(shè)置顯示。
?實(shí)際上,我們正在添加代碼來接收天氣數(shù)據(jù),然后將其發(fā)送到ILI9341顯示器以進(jìn)行可視化。
上傳守則:
?使用USB電纜將ESP32接收器連接到計(jì)算機(jī)。
?打開Arduino IDE,選擇正確的板和端口。
?確保Display.h和Display.cpp文件正確放置在Arduino項(xiàng)目文件夾中,或作為IDE中的選項(xiàng)卡包含。
?驗(yàn)證代碼,然后點(diǎn)擊“上傳”按鈕。
接線說明:
請參考附件接線圖,了解連接ILI9341顯示器到ESP32的詳細(xì)說明。確保顯示器的VCC、GND、SDA、SCL和其他必要引腳正確連接。
現(xiàn)在,一旦代碼上傳到您的ESP32接收器,并且發(fā)射器正在運(yùn)行,您將看到從發(fā)射器接收到的天氣數(shù)據(jù)顯示在ILI9341屏幕上。串行監(jiān)視器也將顯示數(shù)據(jù)。
步驟8:ESP-NOW的范圍和可靠性
現(xiàn)在我們的無線氣象站已經(jīng)建立并運(yùn)行,讓我們談?wù)凟SP-NOW的范圍和可靠性。
在我的測試中,ESP-NOW的性能出奇地強(qiáng)勁。我已經(jīng)能夠帶著這些esp32在我的房子里走來走去,天氣數(shù)據(jù)一直保持完美的流-沒有丟失一個(gè)數(shù)據(jù)包!老實(shí)說,對于這種本地的家庭無線通信,我發(fā)現(xiàn)ESP-NOW比我用過的任何藍(lán)牙、433MHz或NRF模塊設(shè)置都要可靠得多。它就是有效,而且一直有效。
更令人興奮的是,ESP-NOW能夠?qū)崿F(xiàn)更大的范圍——高達(dá)400米。
這種可靠性使ESP-NOW成為傳感器網(wǎng)絡(luò)、智能家居應(yīng)用以及任何數(shù)據(jù)傳輸一致性至關(guān)重要的項(xiàng)目的理想選擇。雖然障礙物、干擾和天線放置等因素會(huì)影響探測范圍,但ESP-NOW為ESP32項(xiàng)目提供了強(qiáng)大而可靠的無線解決方案。
步驟9 .結(jié)論
這就是答案!我們已經(jīng)成功地使用ESP-NOW建立了一個(gè)無線氣象站,證明了該協(xié)議對于ESP32通信是多么容易和可靠。
我們已經(jīng)學(xué)會(huì)了如何:
?建立基本的ESP-NOW通信來發(fā)送和接收數(shù)據(jù)。
?為我們的天氣數(shù)據(jù)創(chuàng)建一個(gè)自定義數(shù)據(jù)結(jié)構(gòu)。
?使用ESPNowEasy庫來簡化這個(gè)過程。
?集成BME280傳感器,捕捉實(shí)時(shí)環(huán)境數(shù)據(jù)。
?在ILI9341屏幕上顯示該數(shù)據(jù)。
ESP-NOW提供了一種強(qiáng)大而高效的方式來創(chuàng)建無線項(xiàng)目,而無需傳統(tǒng)Wi-Fi或藍(lán)牙設(shè)置的復(fù)雜性。其低功耗和可靠的通信使其成為廣泛應(yīng)用的完美選擇。
本文編譯自hackster.io