BLE 入门 · 蓝牙信标与广播
📅 2026-05-10 · 📂 硬件编程 · ⏱ 阅读约 6 分钟
概述
Bluetooth Low Energy(BLE,低功耗蓝牙)是物联网近距离通信的首选协议。本篇带你理解 BLE 的核心概念:GAP 广播、GATT 服务/特征、UUID,并实现一个蓝牙信标。
学习目标:理解 BLE 协议栈结构,掌握广播和扫描,学会定义 GATT 服务。
BLE 核心概念
| 概念 | 说明 | 类比 |
|---|
| GAP | 通用访问配置—广播/扫描/连接 | WiFi 的 SSID 广播 |
| GATT | 通用属性协议—数据交换 | 文件系统(服务=文件夹,特征=文件) |
| Service UUID | 16/128位服务标识 | 文件夹名 |
| Characteristic | 特征值(读/写/通知) | 文件内容 |
实战一:iBeacon 蓝牙信标
// BLE_Beacon.ino — 模拟 iBeacon 广播
#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEServer.h>
#include <BLEBeacon.h>
#define BEACON_UUID "8ec76ea3-6668-48da-9866-75be8bc86f4d"
void setup() {
Serial.begin(115200);
BLEDevice.init("ESP32_Beacon");
BLEServer *pServer = BLEDevice.createServer();
BLEAdvertising *pAdv = pServer->getAdvertising();
BLEBeacon beacon;
beacon.setManufacturerId(0x4C00); // Apple
beacon.setProximityUUID(BEACON_UUID);
beacon.setMajor(1);
beacon.setMinor(1);
beacon.setSignalPower(-59);
BLEAdvertisementData data;
data.setFlags(0x04);
data.setManufacturerData(beacon.getData());
pAdv->setAdvertisementData(data);
pAdv->start();
Serial.println("iBeacon 广播已启动");
Serial.println("用手机 nRF Connect 或 LightBlue 扫描");
}
void loop() { delay(1000); }
实战二:BLE 扫描周围设备
// BLE_Scan.ino — 扫描周围蓝牙设备
#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEScan.h>
class MyAdvertisedDeviceCallbacks : public BLEAdvertisedDeviceCallbacks {
void onResult(BLEAdvertisedDevice device) {
Serial.printf("📶 %s | RSSI:%d | %s
",
device.getName().c_str(), device.getRSSI(),
device.getAddress().toString().c_str());
}
};
void setup() {
BLEDevice.init("");
BLEScan *pScan = BLEDevice.getScan();
pScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());
pScan->setActiveScan(true);
pScan->start(5); // 扫描5秒
}
void loop() {}
常见问题
⚠️ WiFi 与 BLE 共享天线:ESP32 的 WiFi 和 BLE 共用 2.4GHz 天线。同时开启时会分时复用,通信速率和稳定性都会下降。
💡 调试工具:手机安装 nRF Connect(免费)可以扫描、连接、读写特征值,是 BLE 开发必备调试工具。