ESP32蓝牙低功耗(BLE)多连接问题技术咨询
ESP32 BLE多路继电器控制连接问题解答
问题描述
我用以下代码通过BLE实现ESP32与手机控制两路继电器,代码能正常运行,但仅支持单部手机连接:ESP32被连接后,其他手机无法搜索到它,只有断开当前连接后才会重新可见。想请教两个技术问题:
- ESP32能否同时与多部手机建立BLE连接?
- 若不支持多连接,能否在新手机尝试连接时自动中断原有连接?
用户提供的原始代码:
#include <BLEDevice.h> #include <BLEServer.h> #include <BLEUtils.h> #include <BLE2902.h> // Relais-Pins const int relay1Pin = 18; // GPIO 18 const int relay2Pin = 19; // GPIO 19 BLEServer *pServer = NULL; BLECharacteristic *pCharacteristic = NULL; bool relay1State = false; bool relay2State = false; class MyServerCallbacks : public BLEServerCallbacks { void onConnect(BLEServer *pServer) { // Handle connection } void onDisconnect(BLEServer *pServer) { // Handle disconnection BLEDevice::startAdvertising(); // Start advertising to allow reconnection } }; class MyCallbacks : public BLECharacteristicCallbacks { void onWrite(BLECharacteristic *pCharacteristic) { std::string value = pCharacteristic->getValue(); if (value.length() > 0) { if (value[0] == '1') { digitalWrite(relay1Pin, true); delay(500); digitalWrite(relay1Pin, false); } else if (value[0] == '2') { digitalWrite(relay2Pin, true); delay(500); digitalWrite(relay2Pin, false); } } } }; void setup() { pinMode(relay1Pin, OUTPUT); pinMode(relay2Pin, OUTPUT); digitalWrite(relay1Pin, relay1State); digitalWrite(relay2Pin, relay2State); BLEDevice::init("ESP32_Relay_Control"); pServer = BLEDevice::createServer(); pServer->setCallbacks(new MyServerCallbacks()); BLEService *pService = pServer->createService(BLEUUID("0000FFFF-0000-1000-8000-00805F9B34FB")); pCharacteristic = pService->createCharacteristic( BLEUUID("0000FF01-0000-1000-8000-00805F9B34FB"), BLECharacteristic::PROPERTY_READ | BLECharacteristic::PROPERTY_WRITE ); pCharacteristic->setCallbacks(new MyCallbacks()); pService->start(); BLEAdvertising *pAdvertising = BLEDevice::getAdvertising(); pAdvertising->addServiceUUID(pService->getUUID()); pAdvertising->start(); } void loop() { }
问题解答
1. ESP32能否同时与多部手机建立BLE连接?
ESP32的BLE协议栈原生支持最多3个并发BLE连接,但默认配置仅开启1个连接配额。要实现多设备连接,需要:
- 在创建BLEServer时通过
BLEDevice::createServer(nullptr, 3)设置最大连接数为3 - 修改广播配置,让ESP32在已连接状态下仍持续广播(默认连接后会停止广播,导致其他设备搜不到)
- 额外处理多设备并发控制逻辑,避免多个手机同时操作继电器产生冲突
不过多连接会增加ESP32的CPU和内存占用,若仅需基础控制,单连接模式足够稳定。
2. 若不支持多连接,能否在新手机尝试连接时自动中断原有连接?
完全可以实现。通过监听BLE连接回调,在新设备发起连接时检查当前连接状态,若已有设备连接则主动断开原有连接,同时保持广播让新设备能正常搜索并连接。
修改后的完整代码
#include <BLEDevice.h> #include <BLEServer.h> #include <BLEUtils.h> #include <BLE2902.h> // 继电器引脚 const int relay1Pin = 18; // GPIO 18 const int relay2Pin = 19; // GPIO 19 BLEServer *pServer = NULL; BLECharacteristic *pCharacteristic = NULL; bool relay1State = false; bool relay2State = false; // 记录当前已连接设备的句柄 uint16_t connectedDeviceHandle = 0; class MyServerCallbacks : public BLEServerCallbacks { void onConnect(BLEServer *pServer, esp_ble_gatts_cb_param_t *param) { // 检查是否已有设备连接 if (connectedDeviceHandle != 0) { // 主动断开原有连接 pServer->disconnect(connectedDeviceHandle); } // 记录新连接设备的句柄 connectedDeviceHandle = param->connect.conn_id; // 保持广播,确保新设备能搜索到 BLEDevice::startAdvertising(); } void onDisconnect(BLEServer *pServer) { // 清除连接记录 connectedDeviceHandle = 0; // 重启广播 BLEDevice::startAdvertising(); } }; class MyCallbacks : public BLECharacteristicCallbacks { void onWrite(BLECharacteristic *pCharacteristic) { std::string value = pCharacteristic->getValue(); if (value.length() > 0) { if (value[0] == '1') { digitalWrite(relay1Pin, HIGH); delay(500); digitalWrite(relay1Pin, LOW); } else if (value[0] == '2') { digitalWrite(relay2Pin, HIGH); delay(500); digitalWrite(relay2Pin, LOW); } } } }; void setup() { pinMode(relay1Pin, OUTPUT); pinMode(relay2Pin, OUTPUT); digitalWrite(relay1Pin, relay1State); digitalWrite(relay2Pin, relay2State); BLEDevice::init("ESP32_Relay_Control"); // 创建单连接模式的BLE服务器 pServer = BLEDevice::createServer(); pServer->setCallbacks(new MyServerCallbacks()); BLEService *pService = pServer->createService(BLEUUID("0000FFFF-0000-1000-8000-00805F9B34FB")); pCharacteristic = pService->createCharacteristic( BLEUUID("0000FF01-0000-1000-8000-00805F9B34FB"), BLECharacteristic::PROPERTY_READ | BLECharacteristic::PROPERTY_WRITE ); pCharacteristic->setCallbacks(new MyCallbacks()); pService->start(); BLEAdvertising *pAdvertising = BLEDevice::getAdvertising(); pAdvertising->addServiceUUID(pService->getUUID()); // 设置广播参数,确保连接期间持续广播 pAdvertising->setMinPreferred(0x06); pAdvertising->setMinPreferred(0x12); pAdvertising->start(); } void loop() { }
修改说明
- 添加
connectedDeviceHandle变量记录当前连接设备ID - 在
onConnect回调中实现旧连接断开逻辑 - 配置广播参数,让ESP32在连接状态下仍持续发送广播包
- 在断开连接时清除连接记录,恢复初始状态
内容的提问来源于stack exchange,提问作者DavidHenn1988
相关产品推荐
相关产品推荐

