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

如何解决ESP32 BLE的‘无串行配置文件’或GATT状态133问题?

问题描述

我使用带Wi-Fi和蓝牙功能的ESP32开发板,搭配MAX30102脉搏血氧传感器和电刺激电极,通过蓝牙将ESP32与手机连接,借助Google Play下载的ESP32蓝牙终端读取输出数据。

ESP32可在手机蓝牙列表及蓝牙终端APP中被发现,但尝试连接查看数据时,会出现“无串行配置文件”或“GATT状态133”错误。已尝试重启设备、更换ESP32,问题仍未解决,希望能成功连接APP并查看BPM数值。

原ESP32代码

#include <Wire.h>
#include <EEPROM.h>
#include <BLEDevice.h>
#include <BLEServer.h>
#include <BLEUtils.h>
#include <BLE2902.h>
#include "MAX30102_PulseOximeter.h"
#define BUTTON_PIN 2
#define SERVICE_UUID "4fafc201-1fb5-459e-8fcc-c5c9c331914b"
#define STEP_DATA_CHAR_UUID "beefcafe-36e1-4688-b7f5-00000000000b"
#define REPORTING_PERIOD_MS     1000
BLECharacteristic *pStepDataCharacteristic;

float BPM, SpO2;
const int shocker = 2;
PulseOximeter pox;
uint32_t tsLastReport = 0;
void onBeatDetected()
{
  Serial.println("Beat Detected!");
}
void setup() {
  Wire.begin();
  Serial.begin(115200);
  pinMode(19, OUTPUT);
 if (!pox.begin()) {
    Serial.println("FAILED");
    for (;;);
  } else {
    Serial.println("SUCCESS");
    pox.setOnBeatDetectedCallback(onBeatDetected);
  }
  pox.setIRLedCurrent(MAX30102_LED_CURR_7_6MA);

  BLEDevice::init("Step-Sense");
  
  BLEServer *pServer = BLEDevice::createServer();
  BLEService *pService = pServer->createService(SERVICE_UUID);

  pStepDataCharacteristic = pService->createCharacteristic(
      STEP_DATA_CHAR_UUID,
      BLECharacteristic::PROPERTY_READ | BLECharacteristic::PROPERTY_NOTIFY);
  pStepDataCharacteristic->addDescriptor(new BLE2902());

  pService->start();
  BLEAdvertising *pAdvertising = BLEDevice::getAdvertising();
  pAdvertising->addServiceUUID(SERVICE_UUID);
  pAdvertising->setScanResponse(true);
  pAdvertising->setMinPreferred(0x06);
  pAdvertising->setMinPreferred(0x12);
  BLEDevice::startAdvertising();
  Serial.println("BLE device is ready to be connected");

  pinMode(BUTTON_PIN, INPUT_PULLUP);
}

void loop() {
  pox.update();
  BPM = pox.getHeartRate();
  SpO2 = pox.getSpO2();
  analogWrite(shocker, 30);
  if (millis() - tsLastReport > REPORTING_PERIOD_MS)
  {
    Serial.print("BPM: ");
    Serial.println(BPM);
    Serial.print("SpO2: ");
    Serial.print(SpO2);
    Serial.println("%");
    Serial.println("*");
    Serial.println();
    tsLastReport = millis();
  }
  int result = (int)BPM;
  pStepDataCharacteristic->setValue(result);
  pStepDataCharacteristic->notify();
}
解决方案

错误原因

  • "无串行配置文件":你使用的ESP32蓝牙终端APP是针对标准BLE串口服务(SPP)设计的,但原代码创建的是自定义BLE服务,APP无法识别,因此报错。
  • GATT状态133:原代码在loop中每秒多次发送notify数据,导致连接超时;同时缺少连接状态判断,未连接时也发送数据,引发GATT服务异常。

代码修改方案

方案一:改用标准BLE串口服务(适配ESP32蓝牙终端APP)

替换为标准串口服务UUID,让APP能直接识别并连接:

#include <Wire.h>
#include <EEPROM.h>
#include <BLEDevice.h>
#include <BLEServer.h>
#include <BLEUtils.h>
#include <BLE2902.h>
#include "MAX30102_PulseOximeter.h"
#define BUTTON_PIN 2
// 标准BLE串口服务UUID
#define SERVICE_UUID "6E400001-B5A3-F393-E0A9-E50E24DCCA9E"
// ESP32发数据到手机的特征UUID
#define CHARACTERISTIC_UUID_TX "6E400002-B5A3-F393-E0A9-E50E24DCCA9E"
// 手机发数据到ESP32的特征UUID(可选)
#define CHARACTERISTIC_UUID_RX "6E400003-B5A3-F393-E0A9-E50E24DCCA9E"
#define REPORTING_PERIOD_MS     1000

BLECharacteristic *pTxCharacteristic;
bool deviceConnected = false;

float BPM, SpO2;
const int shocker = 2;
PulseOximeter pox;
uint32_t tsLastReport = 0;

void onBeatDetected()
{
  Serial.println("Beat Detected!");
}

// BLE连接状态回调
class MyServerCallbacks: public BLEServerCallbacks {
    void onConnect(BLEServer* pServer) {
      deviceConnected = true;
      Serial.println("Device connected");
    };

    void onDisconnect(BLEServer* pServer) {
      deviceConnected = false;
      Serial.println("Device disconnected");
      // 断开后重新广播
      BLEDevice::startAdvertising();
    }
};

void setup() {
  Wire.begin();
  Serial.begin(115200);
  pinMode(19, OUTPUT);
 if (!pox.begin()) {
    Serial.println("FAILED");
    for (;;);
  } else {
    Serial.println("SUCCESS");
    pox.setOnBeatDetectedCallback(onBeatDetected);
  }
  pox.setIRLedCurrent(MAX30102_LED_CURR_7_6MA);

  BLEDevice::init("Step-Sense");
  BLEServer *pServer = BLEDevice::createServer();
  pServer->setCallbacks(new MyServerCallbacks());

  BLEService *pService = pServer->createService(SERVICE_UUID);

  // 创建TX特征(支持notify)
  pTxCharacteristic = pService->createCharacteristic(
                      CHARACTERISTIC_UUID_TX,
                      BLECharacteristic::PROPERTY_NOTIFY
                    );
  pTxCharacteristic->addDescriptor(new BLE2902());

  // 创建RX特征(支持write,可选)
  BLECharacteristic *pRxCharacteristic = pService->createCharacteristic(
                      CHARACTERISTIC_UUID_RX,
                      BLECharacteristic::PROPERTY_WRITE
                    );

  pService->start();
  BLEAdvertising *pAdvertising = BLEDevice::getAdvertising();
  pAdvertising->addServiceUUID(SERVICE_UUID);
  pAdvertising->setScanResponse(true);
  pAdvertising->setMinPreferred(0x06);
  pAdvertising->setMinPreferred(0x12);
  BLEDevice::startAdvertising();
  Serial.println("BLE device is ready to be connected");

  pinMode(BUTTON_PIN, INPUT_PULLUP);
}

void loop() {
  pox.update();
  BPM = pox.getHeartRate();
  SpO2 = pox.getSpO2();
  analogWrite(shocker, 30);

  // 仅在设备连接且到上报周期时发送数据
  if (millis() - tsLastReport > REPORTING_PERIOD_MS && deviceConnected)
  {
    String data = "BPM: " + String(BPM) + "\nSpO2: " + String(SpO2) + "%\n";
    Serial.print(data);
    pTxCharacteristic->setValue(data.c_str());
    pTxCharacteristic->notify();
    tsLastReport = millis();
  }
}

方案二:优化原自定义服务的notify逻辑

如果坚持使用自定义服务,需减少数据发送频率并添加连接判断:
修改loop函数如下:

void loop() {
  pox.update();
  BPM = pox.getHeartRate();
  SpO2 = pox.getSpO2();
  analogWrite(shocker, 30);

  if (millis() - tsLastReport > REPORTING_PERIOD_MS)
  {
    Serial.print("BPM: ");
    Serial.println(BPM);
    Serial.print("SpO2: ");
    Serial.print(SpO2);
    Serial.println("%");
    Serial.println("*");
    Serial.println();

    // 仅在上报周期发送一次BLE数据
    int result = (int)BPM;
    pStepDataCharacteristic->setValue(result);
    pStepDataCharacteristic->notify();

    tsLastReport = millis();
  }
}

同时建议添加方案一中的MyServerCallbacks连接回调,确保仅在设备连接时发送数据。

APP使用注意事项

  • 方案一:使用ESP32蓝牙终端APP直接搜索并连接"Step-Sense",连接成功后即可看到BPM和SpO2数据。
  • 方案二:需使用支持自定义GATT服务的调试APP(如nRF Connect),手动订阅对应特征值接收数据,ESP32蓝牙终端APP无法识别自定义服务。

内容的提问来源于stack exchange,提问作者Kakiro

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 10:05:22