基于 ESP32-WROOM-32 实践 iBeacon 蓝牙信标 – PlatformIO

最近更新于 2026-07-26 21:31

测试环境

  • ESP32-WROOM-32
  • PlatformIO IDE 3.3.4
  • PlatformIO Core 6.1.19
  • pioarduino platform-espressif32 55.03.311(Arduino Release v3.3.11 based on ESP-IDF v5.5.5)

platformio.ini

[env:esp32dev]
platform = https://github.com/pioarduino/platform-espressif32/releases/download/55.03.311/platform-espressif32.zip
board = esp32dev
framework = arduino
monitor_speed = 115200

实践

源码参考来源:https://github.com/espressif/arduino-esp32/blob/3.3.11/libraries/BLE/examples/iBeacon/iBeacon.ino

iBeacon 通常用于室内定位、打开考勤、APP贴近感知

/*
    【纯粹 iBeacon 极简广播示例】

    原理说明:
    iBeacon 是 Apple 制定的一种基于 BLE 广播包协议的“信标”标准。
    设备只需要持续对外发送特定格式的广播数据包(包含 Manufacturer Data 厂商数据),
    不需要建立任何连接,也不需要创建 GATT 服务或特征值。
*/

#include <Arduino.h>
#include <BLEDevice.h>
#include <BLEServer.h>
#include <BLEUtils.h>
#include <BLEBeacon.h> // ESP32 官方的 iBeacon 数据结构封装库

// 1. 定义设备名称
#define DEVICE_NAME "ESP32_iBeacon"

// 2. 定义 iBeacon 的核心标识符
// Proximity UUID:用来标识同一组或同一机构的信标(如某个商场、某个园区)
#define BEACON_UUID "2D7A9F0C-E0E8-4CC9-A71B-A21DB2D034A1"

// Major & Minor:16位无符号整数 (0 ~ 65535),用于细分设备
#define BEACON_MAJOR 5  // 通常表示大区域/楼层(如:5号楼)
#define BEACON_MINOR 88 // 通常表示具体位置/房间(如:88号房间)

void setup()
{
    Serial.begin(115200);
    Serial.println("正在初始化 ESP32 iBeacon...");

    // 1. 初始化 BLE 设备引擎
    BLEDevice::init(DEVICE_NAME);

    // 2. 构建 iBeacon 格式的数据结构
    BLEBeacon myBeacon;
    myBeacon.setManufacturerId(0x4C00);              // 0x4C00 代表 Apple 公司 ID(iBeacon 协议标准强制要求)
    myBeacon.setMajor(BEACON_MAJOR);                 // 设置 Major 标识
    myBeacon.setMinor(BEACON_MINOR);                 // 设置 Minor 标识
    myBeacon.setSignalPower(0xC5);                   // 设置 RSSI 补偿值/测距参考功率(0xC5 即 -59dBm,用于在 1 米处估算距离)
    myBeacon.setProximityUUID(BLEUUID(BEACON_UUID)); // 设置 128位的 UUID

    // 3. 构建 BLE 广播包 (Advertisement Data)
    BLEAdvertisementData advertisementData;

    /*
       设置 0x01 Flags 标志位:
       0x1A 即二进制 0001 1010:
       - Bit 1 (0x02): LE General Discoverable Mode (通用可发现模式)
       - Bit 3 (0x08): BR/EDR Not Supported (不支持传统蓝牙,仅支持低功耗蓝牙)
       - Bit 4 (0x10): LE only for Controller & Host
    */
    advertisementData.setFlags(0x1A);

    // 将打包好的 iBeacon 数据(格式化的 25 字节 payload)塞进广播包的厂商数据段中
    advertisementData.setManufacturerData(myBeacon.getData());

    // 4. 获取广播管理器并应用配置
    BLEAdvertising *pAdvertising = BLEDevice::getAdvertising();
    pAdvertising->setAdvertisementData(advertisementData);

    // 5. 开启广播
    pAdvertising->setScanResponse(true); // 允许响应扫描请求(提高部分设备的发现概率)
    pAdvertising->setMinPreferred(0x06); // 帮助 iOS 改善连接与广播识别速度
    pAdvertising->setMinPreferred(0x12);
    pAdvertising->start();

    Serial.println("iBeacon 广播已启动!手机/调试工具现在可以扫描到了。");
}

void loop()
{
    // iBeacon 只需要在后台由蓝牙硬件自动持续发包
    // 主循环不需要做任何操作,直接休眠 10 秒,极大地降低 CPU 资源消耗
    delay(10000);
}

iBeacon 就是用于广播信标的,比如一个商场有 5 层,每层有 100 个门店,每个门店都有一个 iBeacon 信号。
可以先规定 Major 用作楼层,Minor 用作层内门牌号,“RSSI at 1m: -59dBm” 就是设定的在 1m 处无遮挡的信号强度。
设备接收到 iBeacon 就可以根据约定的内容算出当前最靠近哪个门店。
file

基于 ESP32-WROOM-32 实践 iBeacon 蓝牙信标 – PlatformIO
Scroll to top
打开目录