一、背景
由于项目需要,我需要将ESP32作为服务端,持续广播特定蓝牙Beacon数据,且必须强制指定设备MAC地址以满足协议要求。实测发现,ESP-IDF默认MAC派生规则不满足需求,需深度定制地址,但百度搜索的方法存在隐性“坑点”,导致配置失效。
二、踩坑笔记和解决方法
1.1 百度学习到的其他博主分享的代码(不能成功改变MAC)
void setup() {
Serial.begin(115200);
uint8_t new_mac[8] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x07};
esp_base_mac_addr_set(new_mac);
// Create the BLE Device
BLEDevice::init("MyESP32");
// Create the BLE Server
// BLEServer *pServer = BLEDevice::createServer(); // <-- no longer required to instantiate BLEServer, less flash and ram usage
pAdvertising = BLEDevice::getAdvertising();
setBeacon();
// Start advertising
pAdvertising->start();
Serial.println("Advertizing started...");
delay(100);
}
1.2 解决方法
其实解决方法很简单,但是很多人都没有这种习惯,那就是看函数说明。其中很明确说明了:“第一个字节的最低有效位必须为零”。所以一开始使用的 “{0x01, 0x02, 0x03, 0x04, 0x05, 0x07};”其中第一个字节0x01(0000 0001)并不符合要求。
所以我把地址改为{0x02, 0x02, 0x03, 0x04, 0x05, 0x07};于是顺利更改了MAC地址。(0x02的二进制为 0000 0010,最后一位为0即可,并不需要整个字节为0)
void setup() {
Serial.begin(115200);
uint8_t new_mac[8] = {0x02, 0x02, 0x03, 0x04, 0x05, 0x07};
esp_base_mac_addr_set(new_mac);
// Create the BLE Device
BLEDevice::init("MyESP32");
// Create the BLE Server
// BLEServer *pServer = BLEDevice::createServer(); // <-- no longer required to instantiate BLEServer, less flash and ram usage
pAdvertising = BLEDevice::getAdvertising();
setBeacon();
// Start advertising
pAdvertising->start();
Serial.println("Advertizing started...");
delay(100);
}
但是,我又发现了新的问题:最后一个字节我明明设置的是0x07,但是扫描出来的却是0x08。而函数说明也没有提及,那么只能从官方手册中找答案。杂项系统 API - ESP32 - — ESP-IDF 编程指南 v5.2.5 文档
自此,所有问题已解决。比起具体的代码片段,解决问题的系统性思路更值得沉淀。