如何解决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
相关产品推荐
相关产品推荐

