博客专栏

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

相关推荐

技术专区

关闭