You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ESP32蓝牙低功耗(BLE)多连接问题技术咨询

ESP32 BLE多路继电器控制连接问题解答

问题描述

我用以下代码通过BLE实现ESP32与手机控制两路继电器,代码能正常运行,但仅支持单部手机连接:ESP32被连接后,其他手机无法搜索到它,只有断开当前连接后才会重新可见。想请教两个技术问题:

  1. ESP32能否同时与多部手机建立BLE连接?
  2. 若不支持多连接,能否在新手机尝试连接时自动中断原有连接?

用户提供的原始代码:

#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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 06:12:10