ESP32的BLE使用学习

news2025/7/11 12:14:46

UUID生成网站:

Online UUID Generator Tool

0.前言

什么是低功耗蓝牙?

BLE之所以被称为低功耗蓝牙,就是需要通讯的时候才握手,数据传输完成后,就断开连接。在通讯过程中,主动方是客户端,由客户端发起连接请求、收发数据、断开连接等操作服务器是被动的一方,随时做好了被连接的准备,并对连接请求作出相应

如果需要不断发送控制和接收数据的指令,则在控制端APP中设计中,需要加入定时器

BLE低功耗蓝牙,主要应用于少量数据的短距离传输(低带宽)。与经典蓝牙不同,BLE只在传输数据时建立连接,空闲时进入睡眠模式来节能。这使得它消耗非常低的功率,BLE的功耗比经典蓝牙低约100倍(取决于实际使用)。BLE不仅支持点对点通信,还支持广播模式和网状网络。

BLE适用场景:短距离、偶尔发送少量数据,长时间靠电池供电,比如健康手环、追踪标签、物联网传感器等。

  1. 点对点通信:客户端扫描附近的设备,当搜索到服务器时,建立连接并监听传入的数据
  2. 广播模式:服务器向连接的多个客户端进行数据传输,服务器notify
  3. 网状网络: 所有设备都已连接,多对多连接

BLE和经典蓝牙的对比:

1.BLE服务器和客户端

BLE蓝牙有两种类型的设备:服务器和客户端,ESP32既可以作为客户端,也可以作为服务器(例如ESP32开发板与BLE手柄间的数据通信)。

服务器:可以被其他设备(客户端)搜索,进行读取数据。

2.GATT协议

GATT (Generic Attribute Profile)通用属性配置文件,它定义了向连接的BLE设备公开的分层数据结构。这意味着GATT定义了两个BLE设备发送和接收标准信息的方式。

  •  profile:服务器集合,针对特定用例的标准服务集合
  • service:服务器UUID,只有一个,收集相关信息,如传感器读数、电池电量
  • Characteristic:特征量(每个特征量都有一个分配的专属UUID),它是实际数据保存在层次结构上的位置
  • properties描述如何与特征值交互,notify。例如:读、写、通知、广播、指示等
  • value:特征值
  • descriptor:描述符

在示例中,创建一个具有两个特征的服务,温度和湿度。温度和湿度数据保存在其特征值上,每个特征都有notify属性,以便在值变化时通知客户端

3.UUID

每个服务、特征和描述符都有一个UUID(通用唯一标识符),UUID用于唯一标识信息,它可以识别蓝牙设备提供的特定服务

UUID是唯一的128位(16字节)数字,例如:

0340fde2-67b2-11ed-9022-0242ac120002

 UUID生成网站: 

Online UUID Generator Tool

 4.BLE程序

所需库文件

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

程序说明

(1)定义service和characteristic UUID:

// See the following for generating UUIDs: https://www.uuidgenerator.net/
#define SERVICE_UUID "06CDF89C-005D-4899-998B-6C7E8F48AEF5" // UART service UUID
#define CHARACTERISTIC_UUID_RX "4b88ba09-d579-4823-ba39-3b01cd0d2481"
#define CHARACTERISTIC_UUID_TX "21136456-0ef8-4044-9b6a-47f2fde41b5b"

(2)创建BLE设备:

BLEDevice::init("ESP32 UART Test"); // Give it a name

(3)创建一个BLE服务:

示例1:创建BLE服务器代码流程

  1. 创建一个BLE Sever(BLE 服务器),在这种情况下,ESP32充当BLE服务器
  2. 创建一个BLE Service(BLE 服务)
  3. 创建一个BLE Characteristic,在服务上创建BLE特征

  4. 创建一个BLE Descriptor,在特征上创建一个BLE描述符。

  5. 启动服务

  6. 开始广播,以便其他设备可以找到它

uint8_t txValue = 0;                         // 要发送的值,先不用管
BLEServer *pServer = NULL;                   // BLEServer指针 pServer
BLECharacteristic *pTxCharacteristic = NULL; // BLECharacteristic指针 pTxCharacteristic
bool deviceConnected = false;                //本次连接状态
bool oldDeviceConnected = false;             //上次连接状态
  pServer = BLEDevice::createServer(); // 创建BLE服务(只有一个)
  pServer->setCallbacks(new MyServerCallbacks()); //设置回调
  BLEService *pService = pServer->createService(SERVICE_UUID); // 服务UUID

示例2:(8条消息) 轻松易懂arduino低功耗BLE蓝牙通信_DLGG创客DIY的博客-CSDN博客

①使用ESP32创建BLE Server 

  1. 创建BLE Server
  2. 给这个BLE Server添加一个Service,传入头部设置的Service UUID
  3. 再为这个Service创建Characteristic,这里除了传入UUID,还要声明这个Characteristic的读写属性。
  4. 然后给Characteristic赋个初始值,这个值可以被客户端读取然后改写。
  5. 最后,开启这个Service,然后开始广播,这样这个Server就可以被BLE的客户端扫描到。
  BLEDevice::init("MyESP32");
  BLEServer *pServer = BLEDevice::createServer();
  BLEService *pService = pServer->createService(SERVICE_UUID);
  BLECharacteristic *pCharacteristic = pService->createCharacteristic(
                                         CHARACTERISTIC_UUID,
                                         BLECharacteristic::PROPERTY_READ |
                                         BLECharacteristic::PROPERTY_WRITE
                                       );

 Characteristic赋个初始值:

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

 开启这个Service,然后开始广播:

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

 ②BLE Client端

  BLE Server创建完成后,需要Client端来连接Server,并读写数据。在BLE应用中,Client端往往是手机,当然也可以是其他单片机。

(4)创建一个BLE特征:

  // 创建一个 BLE 特征
  pTxCharacteristic = pService->createCharacteristic(CHARACTERISTIC_UUID_TX, BLECharacteristic::PROPERTY_NOTIFY);
  pTxCharacteristic->addDescriptor(new BLE2902());
  BLECharacteristic *pRxCharacteristic = pService->createCharacteristic(CHARACTERISTIC_UUID_RX, BLECharacteristic::PROPERTY_WRITE);
  pRxCharacteristic->setCallbacks(new MyCallbacks()); //设置回调

(5)设置回调函数:

// 回调函数,让连接状态发送改变,重点!
class MyServerCallbacks : public BLEServerCallbacks
{
  void onConnect(BLEServer *pServer) // 开始连接
  {
    deviceConnected = true; // 连接成功
  };

  void onDisconnect(BLEServer *pServer) // 断开连接
  {
    deviceConnected = false; // 设备连接错误
  }
};

(6)启动广播:

pService->start();                  // 开始服务
  pServer->getAdvertising()->start(); // 开始广播,开启广播时,功耗很大,BLE连接成功后,可以关闭广播,功耗会下降
  Serial.println(" Waiting a client connection to notify...");

(7)断开连接和正在连接,写在loop中

void loop()
{
  // deviceConnected 已连接
  if (deviceConnected)
  {
    pTxCharacteristic->setValue(&txValue, 1); // 设置要发送的值为1
    pTxCharacteristic->notify();              // 广播
    txValue++;                                // 数值加1,然后取地址
    delay(2000);                              // 如果有太多包要发送,蓝牙会堵塞
  }

  // disconnecting  断开连接
  if (!deviceConnected && oldDeviceConnected)
  {
    delay(500);                  // 留时间给蓝牙缓冲
    pServer->startAdvertising(); // 重新广播
    Serial.println(" 开始广播 ");
    oldDeviceConnected = deviceConnected;
  }

  // connecting  正在连接
  if (deviceConnected && !oldDeviceConnected)
  {
    // do stuff here on connecting
    oldDeviceConnected = deviceConnected;
  }
}

重要参考程序:

(8条消息) ESP32经典蓝牙和BLE的使用 (基于Arduino)_月烨洵纾鄞.的博客-CSDN博客_esp32蓝牙arduino

5.APP Inventor

注意事项:

        单片机发送数据到手机:如果一直执行数据接收,数据一定会乱套,手机app可以通过定时器在间隔指定时间执行指定函数。

        切换界面,蓝牙依旧保持连接

在打开蓝牙扫描后,完成扫描后记得停止扫描,不然会一直扫描占用系统资源

连接蓝牙设备:连接蓝牙设备需要蓝牙设备的地址,蓝牙设备的地址则以字符串的形式保存在下拉框中。扫描得到的信息:蓝牙地址、设备名称、信号强度,地址的字符串长度为17.

接收和发送数据需要服务UUID和特征UUID。服务UUID只有一个,特征UUID可以有多个

APP设计参考:

(5条消息) ESP32S蓝牙04_tongyue的博客-CSDN博客

(5条消息) Appinventor——蓝牙app(蓝牙遥控器、串口助手、温湿度显示、切换界面蓝牙依旧保持连接)_霄耀在努力的博客-CSDN博客

(5条消息) APP Invertor 制作BLE蓝牙APP 控制esp32蓝牙小车_青烨慕容的博客-CSDN博客

(5条消息) APP Invertor 蓝牙BLE 个人案例分享 快速开发自己的蓝牙APP_重行HC的博客-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/18043.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

中微SC8F5771模拟IIC通信——指令运行速度的探索(附编译软件与烧录软件)

文章目录一、中微单片机烧录与使用编译软件烧录软件下载地址烧录软件二、模拟IIC三、逻辑分析仪下的时序一、中微单片机烧录与使用 编译软件 中微所使用编译软件为SCMCU_IDE&#xff0c;不过个人不推荐使用这个软件写代码&#xff08;十分不好用&#xff0c;不能跳转&#xf…

Linux搜索查找命令【详细整理】

目录Linux下文件搜索、查找、查看命令findfind 【搜索范围】【选项】​ find /home -name ‘hello.txt’​ find /home -user root​ find / -size 100Mlocate特别说明&#xff1a;locate 文件名whichwhich lsgrep​ 基本语法&#xff1a;grep [选项] 查找内容 源文件grep -niL…

第六章 图论 8 AcWing 1624. 地铁地图

第六章 图论 8 AcWing 1624. 地铁地图 原题链接 AcWing 1624. 地铁地图 算法标签 图论 单源最短路 dijkstra spfa 思路 若采用邻接矩阵存储 超出本题空间限制&#xff0c;因此无法采用邻接矩阵存储&#xff0c;可采用邻接表存储 若采用常规建图方式&#xff08;即相邻两…

微信小程序|基于小程序实现人脸融合

文章目录一、文章前言二、具体流程及准备三、开发步骤四、完整代码一、文章前言 此文主要通过小程序实现人脸图像融合&#xff0c;将检测到的两张人脸进行融合&#xff0c;输出一张融合后的人脸。 二、具体流程及准备 2.1、注册百度开放平台及微信公众平台账号。 2.2、下载及安…

概论_第2章随机变量及其概率分布__离散型随机变量之二项分布

二项分布是离散型随机变量的内容 一. 定义&#xff1a; 若随机变量X的可能取值为0, 1, ... ,n, 而X的分布值为 , k0,1,…n 其中&#xff0c;0<p<1, q 1-p, 称X服从参数为n, p的二项分布&#xff0c; 简记为 X ~ B(n, p) 1. 当n1时&#xff0c; X服从0-1分布, …

想进入游戏建模行业,这4点必须了解

“游戏行业不关心你的专业&#xff0c;只关心你的作品”&#xff0c;想要进入游戏行业就记住这句话&#x1f44d; 这一年可是越来越多人想要进入游戏行业啦&#xff5e;造成了汤多肉少的情况&#xff0c;咱们怎样才能在一群竞争者中脱颖而出呢❓有4⃣大点你要注意的&#xff1…

决策树算法在计算机视觉中的应用附matlab代码

✅作者简介&#xff1a;热爱科研的Matlab仿真开发者&#xff0c;修心和技术同步精进&#xff0c;matlab项目合作可私信。 &#x1f34e;个人主页&#xff1a;Matlab科研工作室 &#x1f34a;个人信条&#xff1a;格物致知。 更多Matlab仿真内容点击&#x1f447; 智能优化算法 …

利用SpringBoot和vue+elementui做一个简单的书本信息管理系统

目录 1.准备工作 1.1.数据库准备 1.2.前端准备工作 1.3.后端准备工作 2.后台代码的编写 2.1.修改配置文件 2.2. 编写service层 2.3.编写Controller层 3.前台代码的编写 3.1.在src里面的api里面的action.js 3.2.搜索栏&#xff0c;表单 3.3.表格 3.4.弹出新增的模态…

[附源码]SSM计算机毕业设计整形美容咨询网站JAVA

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

【考研复试】计算机专业考研复试英语常见问题二(研究方向/前沿技术/本科毕设篇)

相关链接&#xff1a; 【考研复试】计算机专业考研复试英语常见问题一&#xff08;家庭/家乡/学校篇&#xff09;【考研复试】计算机专业考研复试英语常见问题二&#xff08;研究方向/前沿技术/本科毕设篇&#xff09;【考研复试】计算机专业考研复试英语常见问题三&#xff0…

助老服务机器人结构设计

目 录 摘要 I Abstract II 第1章 绪论 1 1.1 课题背景 1 1.2 国外助老服务机器人的研究 1 1.2.1 爱尔兰PAM-AID 助老服务机器人 1 1.2.2 美国SmartCane 助老服务机器人 2 1.2.3 韩国WAR 助老服务机器人 3 1.2.4 日本助老服务机器人 4 1.2.5 可穿戴的外骨骼式助老服务机器人 4 …

(九)Spring之Bean的循环依赖问题

文章目录环境什么是Bean的循环依赖singleton下的set注入产生的循环依赖prototype下的set注入产生的循环依赖构造注入产生的循环依赖singleton下的构造注入prototype下的构造注入Spring解决循环依赖的机理&#xff08;底层实现&#xff09;上一篇&#xff1a;&#xff08;八&…

注释写的好,文档不潦草.

大家好&#xff0c;long time no see&#xff01;这次聊一聊「注释」。写「注释」的好处众所周知&#xff0c;但有时在实现一些「公共代码」后&#xff0c;需要编写「文档」&#xff0c;其中「注释」和「文档」的内容是大致相同的&#xff0c;比如param和returns等(相信有不少同…

Java_抽象类和接口(一)

作者&#xff1a;爱塔居的博客_CSDN博客-JavaSE领域博主 专栏&#xff1a;JavaSE 作者简介&#xff1a;大三学生&#xff0c;希望跟大家一起进步&#xff01; 文章目录 目录 文章目录 一、抽象类 1.1 抽象类概念 1.2 抽象类语句 1.3 抽象类特性 1.4 抽象类和普通类的区别 1.5 抽…

赞不绝口!仅靠阿里P9分享的 Redis 工作手册,拿到60W年薪Offer

昨晚有六七位小伙伴告诉我说&#xff1a;“大佬&#xff0c;有没有Redis的面试教程啊&#xff0c;最近面试被问到好多” 这就帮小伙伴们专门整理了一份资料&#xff08;不仅仅是面试题&#xff09;&#xff0c;从Redis核心原理到Redis设计与源码帮助大家梳理体系&#xff0c;快…

教你自己写Arcpy批处理程序

自己写Arcpy批处理栅格和矢量 先上代码&#xff0c;讲解各行代码的意思&#xff0c;从而达到自己写代码的目的 #....Edit by Longhao Wang.... import arcpy from arcpy import env from arcpy.sa import * import os import os.path import sys arcpy.env.workspace"D:…

Vue项目开发经验

文章目录前言网页组件echarts使用打包后显示包体积安装tensorflow和anaconda可能出现的错误![在这里插入图片描述](https://img-blog.csdnimg.cn/c1facd95a7f645c5af3e8dc1237913a3.png)总结前言 本博客仅做学习笔记&#xff0c;如有侵权&#xff0c;联系后即刻更改 科普&…

《调试九法》阅读笔记

1. 理解系统 阅读手册、仔细阅读每个细节、掌握基础知识、了解工作流程、了解工具。 2. 制造失败 制造失败、从头开始、引发失败、但不要模拟失败、查找不受你控制的条件、记录每件事情&#xff0c;并找到间歇性bug特征、不要过于相信统计数据、要认识到“那”是可能会发生的…

[附源码]java毕业设计商场日常维修管理系统

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

【云原生】k8s 中的 hostNetwork 和 NetworkPolicy(网络策略)讲解与实战操作

文章目录一、hostNetwork 介绍二、k8s 网络策略 NetworkPolicy三、Pod 隔离的两种类型四、NetworkPolicy 资源1&#xff09;NetworkPolicy 示例演示2&#xff09;选择器 to 和 from 的行为五、总结一、hostNetwork 介绍 在k8s中&#xff0c;若pod使用主机网络&#xff0c;也就是…