天天看點

ESP32中 低功耗藍牙 (BLE)

作者:Xzxxxxxx

低功耗藍牙簡介

Bluetooth Low Energy,簡稱BLE,是藍牙的一種節能變體。BLE 的主要應用是少量資料的短距離傳輸(低帶寬)。與始終開啟的藍牙不同,BLE 會一直保持睡眠模式,除非發起連接配接。這使得它消耗非常低的功率。BLE 的功耗比藍牙低大約 100 倍(取決于使用情況)。

ESP32中 低功耗藍牙 (BLE)

此外,BLE 不僅支援點對點通信,還支援廣播模式和網狀網絡。由于其特性,BLE 适用于需要在紐扣電池上定期交換少量資料的應用程式。例如,BLE 在醫療保健、健身、跟蹤、信标、安全和家庭自動化行業中有很大的用途。

ESP32中 低功耗藍牙 (BLE)

BLE 伺服器和用戶端

對于低功耗藍牙,有兩種類型的裝置:伺服器和用戶端。ESP32 既可以作為用戶端也可以作為伺服器。

伺服器廣播它的存在,是以可以被其他裝置發現,并包含用戶端可以讀取的資料。用戶端掃描附近的裝置,當它找到它正在尋找的伺服器時,它會建立連接配接并監聽傳入的資料。這稱為點對點通信。

ESP32中 低功耗藍牙 (BLE)

BLE 還支援廣播模式和網狀網絡:

  • 廣播模式:伺服器向多個連接配接的用戶端發送資料;
  • 網狀網絡:所有裝置都連接配接在一起,這是多對多連接配接。

ESP32中 的藍牙

ESP32 可以充當 BLE 伺服器或 BLE 用戶端。Arduino IDE 的 ESP32 BLE 庫中有幾個 ESP32 的 BLE 示例 。當您在 Arduino IDE 上安裝 ESP32 時,該庫預設安裝。

在您的 Arduino IDE 中,您可以轉到 檔案>示例> ESP32 BLE Arduino并浏覽 BLE 庫附帶的示例。

ESP32中 低功耗藍牙 (BLE)

注意:要檢視 ESP32 示例,您必須在Tools > Board上選擇 ESP32 board 。

為了簡要介紹在 Arduino IDE 上使用 BLE 的 ESP32,我們将建立一個 ESP32 BLE 伺服器,然後建立一個 ESP32 BLE 掃描器來查找該伺服器。我們将使用和解釋 BLE 庫附帶的示例。

要完成此示例,您需要兩塊 ESP32 開發闆。我們将使用 ESP32 DOIT DEVKIT V1 開發闆。

ESP32 藍牙伺服器

要建立 ESP32 BLE 伺服器,請打開您的 Arduino IDE 并轉到 檔案>示例> ESP32 BLE Arduino并選擇BLE_server示例。應加載以下代碼:

/*
    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
    updates by chegewara
*/

#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 伺服器,代碼應遵循以下步驟:

  1. 建立 BLE 伺服器。在這種情況下,ESP32 充當 BLE 伺服器。
  2. 建立 BLE 服務。
  3. 在服務上建立 BLE 特性。
  4. 在特性上建立 BLE 描述符。
  5. 啟動服務。
  6. 開始廣播,以便其他裝置可以找到它。

BLE 伺服器示例代碼的工作原理

首先導入 BLE 功能所需的庫。

#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEServer.h>           

然後,需要為 Service 和 Characteristic 定義一個 UUID。

#define SERVICE_UUID "4fafc201-1fb5-459e-8fcc-c5c9c331914b"
#define CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a8"           

可以保留預設 UUID,也可以轉到 uuidgenerator.net 建立随機 UUID。

在裡面設定(), 它以 115200 的波特率開始串行通信。

Serial.begin(115200);           

然後,建立一個名為“ MyESP32 ”的 BLE 裝置。

// Create the BLE Device
BLEDevice::init("MyESP32");           

在下一行中,将 BLE 裝置設定為伺服器。

BLEServer *pServer = BLEDevice::createServer();           

之後,使用之前定義的 UUID 為 BLE 伺服器建立服務。

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

然後,設定該服務的特征。還使用了之前定義的 UUID,并且需要将特性的屬性作為參數傳遞。在這種情況下,它是:READ 和 WRITE。

BLECharacteristic *pCharacteristic = pService->createCharacteristic(
                                     CHARACTERISTIC_UUID,
                                     BLECharacteristic::PROPERTY_READ |
                                     BLECharacteristic::PROPERTY_WRITE
                                     );           

建立特征後,可以使用設定值()方法。

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

在這種情況下,将值設定為文本“Hello World says Neil”。

最後,可以啟動服務和廣告,以便其他 BLE 裝置可以掃描并找到此 BLE 裝置。

BLEAdvertising *pAdvertising = pServer->getAdvertising();
pAdvertising->start();           

這隻是一個關于如何建立 BLE 伺服器的簡單示例。。

ESP32 藍牙掃描器

建立 ESP32 BLE 掃描器很簡單。用另一個ESP32,在 Arduino IDE 中,轉到 檔案 > 示例> ESP32 BLE Arduino并選擇BLE_scan示例。加載以下代碼。

/*
   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);
}           

此代碼将 ESP32 初始化為 BLE 裝置并掃描附近的裝置。将此代碼上傳到 ESP32。。

上傳代碼後,打開兩個 ESP32 開發闆:

  • 一個裝載“BLE_server”的 ESP32;
  • 另一裝載 ESP32“BLE_scan”。
ESP32中 低功耗藍牙 (BLE)

轉到運作“BLE_scan”示例的 ESP32 的串行螢幕,按下 ESP32)啟用按鈕以重新啟動并在掃描時等待幾秒鐘。

掃描器發現了裝置: MyESP32

ESP32中 低功耗藍牙 (BLE)

繼續閱讀