Android与ESP32 BLE通信接收异常问题求助
排查ESP32无法接收Android BLE数据的问题
我来帮你一步步排查这个问题,结合你给出的Android代码片段,咱们先从两端的配置和代码细节入手:
一、先检查Android端的写入逻辑
你贴的writeCustomCharacteristic函数只写了开头,这里可能存在几个关键问题:
1. 特征值(Characteristic)的属性与UUID匹配
首先要确保你写入的特征值必须支持WRITE权限(PROPERTY_WRITE或PROPERTY_WRITE_NO_RESPONSE),并且服务UUID、特征值UUID要和ESP32端定义的完全一致(注意大小写统一,避免拼写错误)。
2. int类型数据的字节转换问题
BLE传输的是字节数组,直接传入int类型的0xFFFF会导致数据格式错误。你需要把int转成字节数组,还要注意**端序(大小端)**和ESP32保持一致。补全后的函数示例:
public void writeCustomCharacteristic(int value) { if (mBluetoothAdapter == null || mBluetoothGatt == null) { Log.w(TAG, "BluetoothAdapter not initialized"); return; } // 替换成你自己的服务UUID和特征值UUID UUID serviceUuid = UUID.fromString("你的BLE服务UUID"); UUID charUuid = UUID.fromString("你的BLE特征值UUID"); BluetoothGattService service = mBluetoothGatt.getService(serviceUuid); if (service == null) { Log.w(TAG, "Target service not found"); return; } BluetoothGattCharacteristic characteristic = service.getCharacteristic(charUuid); if (characteristic == null) { Log.w(TAG, "Target characteristic not found"); return; } // 将int转为字节数组,这里用小端序(ESP32默认是小端架构,建议统一) ByteBuffer buffer = ByteBuffer.allocate(4); buffer.order(ByteOrder.LITTLE_ENDIAN); buffer.putInt(value); byte[] data = buffer.array(); characteristic.setValue(data); // 根据特征值属性选择写入类型,WRITE_NO_RESPONSE不需要等待回应 boolean writeSuccess = mBluetoothGatt.writeCharacteristic(characteristic); if (!writeSuccess) { Log.w(TAG, "Failed to write characteristic"); } }
3. 检查写入操作的返回值
一定要看Android日志里writeSuccess的结果,如果是false,大概率是特征值不存在、属性不支持写入,或者BLE连接已经断开。
二、ESP32端的接收配置检查
ESP32端必须正确配置BLE服务、特征值,并且注册回调函数来处理写入事件:
1. 确保特征值开启WRITE权限
在创建特征值时,必须包含BLECharacteristic::PROPERTY_WRITE属性,否则无法接收写入数据。示例代码:
#include <BLEDevice.h> #include <BLEServer.h> #include <BLEUtils.h> // 这里的UUID要和Android端完全一致 #define SERVICE_UUID "你的BLE服务UUID" #define CHARACTERISTIC_UUID "你的BLE特征值UUID" // 自定义回调类,处理写入事件 class BleCharCallbacks : public BLECharacteristicCallbacks { void onWrite(BLECharacteristic *pChar) override { std::string receivedData = pChar->getValue(); if (!receivedData.empty()) { Serial.println("Received raw data:"); for (byte b : receivedData) { Serial.printf("%02X ", b); } Serial.println(); // 将字节数组转回int(注意端序和Android一致) int receivedValue = 0; memcpy(&receivedValue, receivedData.data(), sizeof(receivedValue)); Serial.printf("Converted to int: %d (0x%X)\n", receivedValue, receivedValue); } } }; void setup() { Serial.begin(115200); BLEDevice::init("ESP32_BLE_Device"); // 创建BLE服务器和服务 BLEServer *pServer = BLEDevice::createServer(); BLEService *pService = pServer->createService(SERVICE_UUID); // 创建特征值,必须包含WRITE属性 BLECharacteristic *pChar = pService->createCharacteristic( CHARACTERISTIC_UUID, BLECharacteristic::PROPERTY_READ | BLECharacteristic::PROPERTY_WRITE // 关键:开启WRITE权限 ); // 设置回调函数,这样有数据写入时才会触发onWrite pChar->setCallbacks(new BleCharCallbacks()); pService->start(); // 开启广播 BLEAdvertising *pAdvertising = BLEDevice::getAdvertising(); pAdvertising->addServiceUUID(SERVICE_UUID); BLEDevice::startAdvertising(); Serial.println("ESP32 BLE server started, waiting for connection..."); } void loop() { delay(1000); }
2. 确认回调函数被触发
打开ESP32的串口监视器,当Android写入数据时,看是否打印出Received raw data:的日志。如果没有触发,说明:
- 特征值UUID不匹配
- 特征值没有开启WRITE权限
- Android端没有成功连接到ESP32
三、通用调试技巧
- 用第三方工具验证:用nRF Connect这类BLE调试APP,手动连接ESP32并写入
0xFFFF(转成4字节小端:FF FF 00 00),看ESP32是否能接收,以此排除是Android端还是ESP32端的问题。 - 检查连接状态:Android端要监听
onConnectionStateChange回调,确保设备处于连接状态再写入数据。 - 端序一致性:Android和ESP32的字节序必须统一,要么都用小端,要么都用大端,否则解析出来的int值会错误。
内容的提问来源于stack exchange,提问作者BOB
相关产品推荐
相关产品推荐

