Open hirschbrat opened 6 years ago
I am newbie in c++, but what i see is:
Why dont you create client in setup? This way you can reuse client every time you want to connect (multiple connection are not implemented yet anyway).
Hi,
I don't create the client in Setup, because then ESP32 crashes after the second connection to a server. See the examples below:
Example 1 Using local BLE Client works, but free heap is continuously reduced:
#include "BLEDevice.h"
static BLEAddress pServerAddress("c4:7c:8d:66:ac:7a");
static BLEUUID serviceUUID("00001204-0000-1000-8000-00805f9b34fb");
static BLEUUID characteristicUUID("00001a02-0000-1000-8000-00805f9b34fb");
//BLEClient* pClient;
//BLERemoteService* pRemoteService;
//BLERemoteCharacteristic* pRemoteCharacteristic;
int freeHeap;
int diff;
int freeHeapBefore;
bool connectToServer( BLEAddress pAddress ) {
BLEClient* pClient = BLEDevice::createClient();
Serial.println("--- Connecting to Server ---");
if (pClient->connect(pAddress)){
Serial.println("connected");
BLERemoteService* pRemoteService;
pRemoteService = pClient->getService(serviceUUID);
if (pRemoteService == nullptr) {
Serial.print("Failed to find our service UUID: ");
Serial.println(serviceUUID.toString().c_str());
}
BLERemoteCharacteristic* pRemoteCharacteristic;
pRemoteCharacteristic = pRemoteService->getCharacteristic(characteristicUUID);
pClient->disconnect();
} else {
Serial.println("failed");
}
pClient->~BLEClient();
}
void setup() {
Serial.begin(115200);
Serial.println("BLE Client with local BLE objects");
BLEDevice::init("");
//pClient = BLEDevice::createClient();
freeHeapBefore = ESP.getFreeHeap();
}
void loop() {
connectToServer(pServerAddress);
freeHeap = ESP.getFreeHeap();
diff = freeHeap - freeHeapBefore;
Serial.print("FreeHeap before: ");
Serial.println(freeHeapBefore);
Serial.print("FreeHeap after: ");
Serial.println(freeHeap);
Serial.print("FreeHeap difference: ");
Serial.println(diff);
freeHeapBefore = freeHeap;
delay(20000);
}
Example 2 Using global BLE Objects only works for the first connection, after the second connection it crashes (so maybe this example shows the real problem):
#include "BLEDevice.h"
static BLEAddress pServerAddress("c4:7c:8d:66:ac:7a");
static BLEUUID serviceUUID("00001204-0000-1000-8000-00805f9b34fb");
static BLEUUID characteristicUUID("00001a02-0000-1000-8000-00805f9b34fb");
BLEClient* pClient;
BLERemoteService* pRemoteService;
BLERemoteCharacteristic* pRemoteCharacteristic;
int freeHeap;
int diff;
int freeHeapBefore;
bool connectToServer( BLEAddress pAddress ) {
//BLEClient* pClient = BLEDevice::createClient();
Serial.println("--- Connecting to Server ---");
if (pClient->connect(pAddress)){
Serial.println("connected");
//BLERemoteService* pRemoteService;
pRemoteService = pClient->getService(serviceUUID);
if (pRemoteService == nullptr) {
Serial.print("Failed to find our service UUID: ");
Serial.println(serviceUUID.toString().c_str());
}
//BLERemoteCharacteristic* pRemoteCharacteristic;
pRemoteCharacteristic = pRemoteService->getCharacteristic(characteristicUUID);
pClient->disconnect();
} else {
Serial.println("failed");
}
pClient->~BLEClient();
}
void setup() {
Serial.begin(115200);
Serial.println("BLE Client with global BLE objects");
BLEDevice::init("");
pClient = BLEDevice::createClient();
freeHeapBefore = ESP.getFreeHeap();
}
void loop() {
connectToServer(pServerAddress);
freeHeap = ESP.getFreeHeap();
diff = freeHeap - freeHeapBefore;
Serial.print("FreeHeap before: ");
Serial.println(freeHeapBefore);
Serial.print("FreeHeap after: ");
Serial.println(freeHeap);
Serial.print("FreeHeap difference: ");
Serial.println(diff);
freeHeapBefore = freeHeap;
delay(20000);
}
Output after second connection:
--- Connecting to Server --- /Users/ficeto/Desktop/ESP32/ESP32/esp-idf-public/components/freertos/./queue.c:1442 (xQueueGenericReceive)- assert failed! abort() was called at PC 0x40087ac5 on core 1
Backtrace: 0x4008a818:0x3ffd8710 0x4008a917:0x3ffd8730 0x40087ac5:0x3ffd8750 0x400d67ed:0x3ffd8790 0x400d3cae:0x3ffd87d0 0x400d2a0e:0x3ffd8830 0x400d2c94:0x3ffd8880 0x40167f7e:0x3ffd88a0
You have some issue here:
(xQueueGenericReceive)- assert failed!
but it has nothing to do with global BLE variables. I am using global variables in product application (not only examples) and i have no issues with reconnecting to peer device. Here is beginning of my file(i cant post more):
#include "BLEDevice.h"
static BLEUUID serviceUUID("e7810a71-73ae-499d-8c15-faa9aef0c3f2");
static BLEUUID charUUID("bef8d6c9-9c21-4c9e-b632-bd58c1009f9f");
static BLEAddress *pServerAddress;
static boolean doConnect = false;
static boolean connected = false;
static BLERemoteCharacteristic* pRemoteCharacteristic;
BLEClient *pClient;
BLEScan* pBLEScan;
BLERemoteService* pRemoteService;
I meet the same problem, and I think it is obviously a serious bug. I use the example of BLE_client to reproduce the problem.
Case 1: Delete "doConnect = false;" in the loop() function Then esp32 will reconnect every loop, and it crashes after about 4 loops.
Case2: Move "pClient = BLEDevice::createClient();" into setup(). Then esp32 works only one time, and it crashes on second connection.
This problem is very easy to reproduce, which takes only 5 minutes.
for those struggling with the second client connection crashing the server:
this is the issue, update your library
Hi,
it seems there is a memory problem with the BLE Client: If the BLE Client is initialized in a function the free heap is reduced with every function call resulting in a crash of the ESP32. Up to now I didn't found a way to solve this problem. If I initialize the BLEClient in setup the ESP32 crashes after two connections to the server...
Here is a simple example:
Adding the following line at the end of connectToServer() reduces the consumed memory per function call from about 600 to 300 - but still not to zero.