博客專欄

        EEPW首頁 > 博客 > 「電子DIY」使用ESP32的BLE功能

        「電子DIY」使用ESP32的BLE功能

        發布人:電子資料庫 時間:2023-02-14 來源:工程師 發布文章

        最美麗的特征之一ESP32已經超過了ESP-12e事實上,除了WiFi,它還有另外兩個通訊模塊。ESP32配備車載經典藍牙和低功耗藍牙技術模塊。在今天的教程中,我們將探討如何在項目中使用ESP-32上的藍牙低能耗模塊。

        image.png


        介紹到低能耗藍牙

        藍牙協議可以分為兩種類型:經典藍牙和較新的藍牙低能量協議(也稱為藍牙4.0)。這兩種協議在2.4ghz ISM頻段內工作,但它們都具有不同的數據速率、不同的功耗速率,并針對不同的應用進行了優化。藍牙低能量(blue)的誕生是為了克服傳統藍牙的缺陷,它有點不適合用于物聯網和電池供電的智能設備,后者只需要在特定的時間間隔發送短時間的數據。與傳統藍牙的連續數據流不同,BLE的設計僅消耗傳統藍牙設備傳輸數據時所消耗的能量的一小部分,而不傳輸數據時則保持睡眠模式。這使得BLE設備更省電,更適合物聯網產品和其他電池供電的智能設備,這些設備通常希望在一次電池充電時盡可能長時間使用。

        下圖顯示了兩種藍牙類型之間的詳細比較。

        image.png


        BLE與經典藍牙

        BLE設備運行動態的一個缺點是消息傳遞系統的復雜性或健壯性(取決于您如何看待它)。在經典藍牙中,串行端口協議(SPP)通常用于在設備之間發送數據,因為通信發生時沒有太多開銷,但是對于BLE,通信期間的數據是使用GATT(通用屬性)的配置文件來組織的。

        在兩個BLE設備之間的通信中,基本上有兩個協議是重要的;差距和關貿總協定. 理解這兩個工作原理對于編程設備通過BLE協議進行通信非常重要。

        GAP協議

        GAP是通用訪問配置文件,它控制藍牙中的連接和廣告(使設備可見并為連接打開)。它定義了設備在通信中扮演的角色,還確定了如何廣播廣告(或掃描,取決于設備角色)負載。

        基于GAP,BLE器件基本上可以發揮兩種作用;中央設備和外圍設備 . these two devices are the ble's representation for the more popular words顧客 Holmium and holmium服務器“分別說。外圍設備通常是由電池供電的小型設備,它們廣播廣告數據,等待來自準備接收數據有效載荷的中央設備的連接。在基于物聯網的解決方案中,外圍設備通常是傳感器等,而中央設備通常是網關、智能手機等。在連接之前,通用接入配置文件將持續廣播廣告有效載荷,直到出現匹配的掃描響應。一旦外圍設備和中央設備之間建立了連接,廣告過程將停止,并且您通常不再能夠發送廣告包,此時,關貿總協定服務和特性的作用是促進雙向交流。

        GATT協定

        關貿總協定是通用屬性配置文件它定義了兩個藍牙低能耗設備如何使用稱為服務和特征的概念在彼此之間來回傳輸數據。它使用一種稱為屬性協議(attributeprotocol,ATT)的通用數據協議,將服務、特征和相關數據存儲在一個簡單的查找表中,對表中的每個條目使用16位id。關貿總協定分層數據結構包括三個主要要素;配置文件 ,服務,和特點 .

        image.png


        GATT協定

        配置文件是預定義的服務集合它是由藍牙SIG或外圍設計人員編譯的。例如,在心率監視器中,心率配置文件可以包括心率服務、電池壽命服務和設備信息服務。一份正式通過的關貿總協定的清單是可用的在這里 .

        服務用于將數據分組到邏輯實體中,并包含稱為特征的特定數據塊. 一個服務可以有一個或多個特征,每個服務通過一個稱為UUID的唯一數字ID來區別于其他服務,UUID可以是16位(對于正式采用的BLE服務)或128位(對于定制服務)。正式采用的BLE服務的完整列表可以在Bluetooth開發人員門戶的服務頁面上看到。為了更好地理解服務是如何工作的,再次考慮心率示例,它可以包含多達3個特征,其中正式采用的服務例如,包括:心率測量、身體傳感器位置和心率控制點。因此,本質上是對相關數據進行分組的服務。

        特征是關貿總協定結構中最底層的概念。它封裝了一個數據點,就像服務一樣,它使用一個唯一的數字ID(UUID)來區別于其他特征。特征是在兩個設備之間傳輸數據的主要容器。

        說到這里,今天的教程將展示如何將ESP32設置為顧客(中央設備)和as服務器(外圍設備)。為了正確演示,我們將使用兩個ESP32板。其中一塊板將被編程為充當服務器,具有發送隨機數據的特性,而另一塊ESP32板將被編程為BLE掃描儀來查找服務器。

        所需組件
        1. 必須是ESP32 DevKit(2個)

        2. 電源組/電池

        正如導言中提到的,我們只需要ESP32模塊,因為它已經具備了項目所需的全部功能。powerbank有助于在獨立模式下輕松地為Devkit供電。您可以通過添加傳感器將實時數據發送到中心設備來輕松修改本教程。

        我們將只使用ESP32板,所以沒有示意圖,我們直接去項目的代碼。

        代碼

        因為我們不會連接任何組件,所以讓我們直接跳到代碼。如引言中所述,我們將把ESP32設置為客戶機和服務器。我們需要一張又一張的素描,這意味著我們需要一張又一張。

        需要注意的是,此項目的代碼將使用Arduino IDE編寫,如果您的IDE沒有安裝ESP 32 Arduino板包,則無法上載代碼。此安裝、下載和安裝Arduino的ESP32板文件在我們的ESP32教程簡介. 一定要檢查一下

        一旦安裝了線路板文件,它會自動將幾個ESP32庫加載到Arduino IDE中。今天教程中的兩個草圖都將嚴重依賴于其中的一個庫 ESP32 BLE Arduino庫. 這個庫由函數和聲明組成,這些函數和聲明使得通過復雜的協議(至少比串行協議更復雜)發送數據,比如BLE。

        BLE服務器草圖

        我將從BLE服務器開始對這兩個草圖做一個簡短的解釋。BLE服務器的算法遵循上述介紹中的解釋。我們首先創建一個BLE服務,然后在該服務下創建BLE特征,然后在特征下創建BLE描述符。然后我們啟動服務并開始廣告,以便掃描BLE設備時可以看到設備。

        我們通過在bleaduino庫中導入代碼所需的庫來開始繪制草圖。



        #include <BLEDevice.h>

        #include <BLEUtils.h>

        #include <BLEServer.h>

        接下來,我們提供 UUID系統服務和特點。這些uuid可以通過以下網站生成 UUID發生器

        #define SERVICE_UUID "4fafc201-1fb5-459e-8fcc-c5c9c331914b"

        #define CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a8"

        接下來,我們編寫無效設置()功能。我們首先初始化串行通信以用于調試目的,然后創建 氣泡裝置類并將對象設置為服務器。

        void setup() {

        Serial.begin(115200);

        Serial.println("Starting BLE work!");

        BLEDevice::init("Long name works now");

        BLEServer *pServer = BLEDevice::createServer();

        接下來,我們為服務器創建一個服務和一個服務特征,在這兩種情況下都指定了UUID。還指定了特征屬性(在本例中是讀和寫)。

        BLEService *pService = pServer->createService(SERVICE_UUID);

        BLECharacteristic *pCharacteristic = pService->createCharacteristic(

        CHARACTERISTIC_UUID,

        BLECharacteristic::PROPERTY_READ |

        BLECharacteristic::PROPERTY_WRITE

        );

        接下來,我們為特征設置一個值。如前所述,我們將在本教程中使用一個隨機值,但這可能是一個傳感器值,或者您希望發送給客戶機的任何其他信息。

        pCharacteristic->setValue("Hello World says Neil");

        最后,我們啟動服務,設置廣告參數,并開始發送廣告負載。

        pService->start();

        // BLEAdvertising *pAdvertising = pServer->getAdvertising(); // this still is working for backward compatibility

        BLEAdvertising *pAdvertising = BLEDevice::getAdvertising();

        pAdvertising->addServiceUUID(SERVICE_UUID);

        pAdvertising->setScanResponse(true);

        pAdvertising->setMinPreferred(0x06); // functions that help with iPhone connections issue

        pAdvertising->setMinPreferred(0x12);

        BLEDevice::startAdvertising();

        對于這個演示,我們將留空循環部分,但您可以選擇在其中執行進一步的任務。您可以瀏覽bleaduino庫下的所有示例以更好地理解。

        void loop() {

        // put your main code here, to run repeatedly:

        }

        服務器的完整代碼在下面提供,它也附在教程末尾的下載部分。

        /*

        Based on Neil Kolban example for IDF: https://github.com/nkolban/esp32-snippets/blob/master/cpp_utils/tests/BLE%20Tests/SampleServer.cpp

        Ported to Arduino ESP32 by Evandro Copercini

        */

        #include <BLEDevice.h>

        #include <BLEUtils.h>

        #include <BLEServer.h>

        // See the following for generating UUIDs:

        // https://www.uuidgenerator.net/

        #define SERVICE_UUID "4fafc201-1fb5-459e-8fcc-c5c9c331914b"

        #define CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a8"

        void setup() {

        Serial.begin(115200);

        Serial.println("Starting BLE work!");

        BLEDevice::init("Long name works now");

        BLEServer *pServer = BLEDevice::createServer();

        BLEService *pService = pServer->createService(SERVICE_UUID);

        BLECharacteristic *pCharacteristic = pService->createCharacteristic(

        CHARACTERISTIC_UUID,

        BLECharacteristic::PROPERTY_READ |

        BLECharacteristic::PROPERTY_WRITE

        );

        pCharacteristic->setValue("Hello World says Neil");

        pService->start();

        // BLEAdvertising *pAdvertising = pServer->getAdvertising(); // this still is working for backward compatibility

        BLEAdvertising *pAdvertising = BLEDevice::getAdvertising();

        pAdvertising->addServiceUUID(SERVICE_UUID);

        pAdvertising->setScanResponse(true);

        pAdvertising->setMinPreferred(0x06); // functions that help with iPhone connections issue

        pAdvertising->setMinPreferred(0x12);

        BLEDevice::startAdvertising();

        Serial.println("Characteristic defined! Now you can read it in your phone!");

        }

        void loop() {

        // put your main code here, to run repeatedly:

        delay(2000);

        }

        BLE掃描儀草圖

        在ESP 32 BLE Arduino庫中提供了與服務器草圖類似的掃描儀草圖示例。

        像往常一樣,我們從包含所需庫開始繪制草圖。

        #include <BLEDevice.h>

        #include <BLEUtils.h>

        #include <BLEScan.h>

        #include <BLEAdvertisedDevice.h>

        接下來,我們指示掃描有效負載廣播和創建布萊斯掃描班級

        int scanTime = 5; //In seconds

        BLEScan* pBLEScan;

        接下來,我們編寫無效設置()功能。我們首先初始化串行監視器,然后初始化BLE,它會自動激活ESP32上的BLE模塊。參數設置為空,因為我們不需要設備的名稱。

        void setup() {

        Serial.begin(115200);

        Serial.println("Scanning...");

        BLEDevice::init("");

        把設置()函數,我們調用scan函數,設置掃描所需的所有參數。

        pBLEScan = BLEDevice::getScan(); //create new scan

        pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());

        pBLEScan->setActiveScan(true); //active scan uses more power, but get results faster

        pBLEScan->setInterval(100);

        pBLEScan->setWindow(99); // less or equal setInterval value

        }

        接下來,我們編寫無效循環()功能。背后的算法無效循環()函數用于簡單地檢查是否找到任何設備,并將這些設備打印在其編號旁邊。結果被清除,循環重新開始。

        void loop() {

        // put your main code here, to run repeatedly:

        BLEScanResults foundDevices = pBLEScan->start(scanTime, false);

        Serial.print("Devices found: ");

        Serial.println(foundDevices.getCount());

        Serial.println("Scan done!");

        pBLEScan->clearResults(); // delete results fromBLEScan buffer to release memory

        delay(2000);

        }

        掃描器的完整代碼如下所示,并附在下載部分下的zip文件中。

        /*

        Based on Neil Kolban example for IDF: https://github.com/nkolban/esp32-snippets/blob/master/cpp_utils/tests/BLE%20Tests/SampleScan.cpp

        Ported to Arduino ESP32 by Evandro Copercini

        */

        #include <BLEDevice.h>

        #include <BLEUtils.h>

        #include <BLEScan.h>

        #include <BLEAdvertisedDevice.h>

        int scanTime = 5; //In seconds

        BLEScan* pBLEScan;

        class MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks {

        void onResult(BLEAdvertisedDevice advertisedDevice) {

        Serial.printf("Advertised Device: %s n", advertisedDevice.toString().c_str());

        }

        };

        void setup() {

        Serial.begin(115200);

        Serial.println("Scanning...");

        BLEDevice::init("");

        pBLEScan = BLEDevice::getScan(); //create new scan

        pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());

        pBLEScan->setActiveScan(true); //active scan uses more power, but get results faster

        pBLEScan->setInterval(100);

        pBLEScan->setWindow(99); // less or equal setInterval value

        }

        void loop() {

        // put your main code here, to run repeatedly:

        BLEScanResults foundDevices = pBLEScan->start(scanTime, false);

        Serial.print("Devices found: ");

        Serial.println(foundDevices.getCount());

        Serial.println("Scan done!");

        pBLEScan->clearResults(); // delete results fromBLEScan buffer to release memory

        delay(2000);

        }

        演示

        復制代碼并粘貼到Arduino IDE中(或從示例文件啟動代碼),然后一個接一個地將服務器草圖上載到指定為服務器的板上,并將掃描儀代碼上載到指定為掃描儀的板上。要使此演示生效,兩塊板都需要“打開”,因為如果服務器“關閉”,客戶端將無法看到服務器,因此您可以將其中兩塊板保持連接到您的PC,或者將服務器連接到電源組或任何其他電源。排序后,啟動串行監視器,確保它設置為客戶端連接的串行端口。幾秒鐘后,您將看到找到的藍牙設備的數量以及串行監視器上顯示的名稱。

        今天的教程到此為止。你可以通過將一個傳感器連接到BLE服務器并在另一個ESP32板上運行BLE客戶端示例來立即擴展項目,或者最好還是使用支持BLE設備的移動應用程序與服務器交互。BLE是目前智能設備中使用最廣泛的通信方法之一,我希望本教程能為您提供在您自己的項目中使用它所需的信息。

        像往常一樣,請隨時通過評論區與我聯系,提出關于本教程的問題或一般性意見。


        *博客內容為網友個人發布,僅代表博主個人觀點,如有侵權請聯系工作人員刪除。



        關鍵詞: 電子 BLE

        相關推薦

        技術專區

        關閉
        主站蜘蛛池模板: 白玉县| 井陉县| 郸城县| 黔江区| 杭锦后旗| 天柱县| 东海县| 远安县| 察雅县| 朝阳区| 呼和浩特市| 金塔县| 台州市| 大田县| 江北区| 双柏县| 汝城县| 张家港市| 七台河市| 论坛| 台中县| 昭苏县| 谷城县| 滦平县| 清远市| 东港市| 沅江市| 新干县| 迭部县| 合肥市| 高台县| 陆丰市| 阿拉尔市| 麻城市| 水富县| 翁牛特旗| 棋牌| 襄樊市| 克什克腾旗| 宝山区| 竹山县|