Hi,
I have managed connecting my ESP to a BLE service, and finding the correct remote characteristic. However, calling registerForNotify results in a crash. I have already tried adding this line:
pRemoteCharacteristic->getDescriptor(BLEUUID((uint16_t)0x2902))->writeValue((uint8_t*)notifyOn, 2, true);
However, after calling this, the ESP crashes as well.
The error (without writing to the descriptor) is:
Guru Meditation Error: Core 1 panic'ed (LoadProhibited). Exception was unhandled.
Core 1 register dump:
PC : 0x400d47b3 PS : 0x00060330 A0 : 0x800d4116 A1 : 0x3ffc85a0
A2 : 0x00000000 A3 : 0x3ffc85de A4 : 0x00000002 A5 : 0x00000000
A6 : 0x3ffdf114 A7 : 0x3f018620 A8 : 0x800d3ea4 A9 : 0x3ffc8550
A10 : 0x3ffc859c A11 : 0x3fc322e8 A12 : 0x3ffc5f34 A13 : 0x3fc322e8
A14 : 0x000000d1 A15 : 0xff000000 SAR : 0x00000018 EXCCAUSE: 0x0000001c
EXCVADDR: 0x00000030 LBEG : 0x4000c349 LEND : 0x4000c36b LCOUNT : 0x00000000
The error (when writing to the descriptor) is:
Guru Meditation Error: Core 1 panic'ed (LoadProhibited). Exception was unhandled.
Core 1 register dump:
PC : 0x400d47ff PS : 0x00060130 A0 : 0x800d179d A1 : 0x3ffc85f0
A2 : 0x00000000 A3 : 0x3ffc8632 A4 : 0x00000002 A5 : 0x00000001
A6 : 0x3ffdec48 A7 : 0x3f018670 A8 : 0x800d3ef0 A9 : 0x3ffc85a0
A10 : 0x3ffc85ec A11 : 0x6691ff4c A12 : 0x3ffc5f34 A13 : 0x6691ff4c
A14 : 0x00000001 A15 : 0x0000002a SAR : 0x00000018 EXCCAUSE: 0x0000001c
EXCVADDR: 0x00000030 LBEG : 0x4000c349 LEND : 0x4000c36b LCOUNT : 0x00000000
Backtrace: 0x400d47ff:0x3ffc85f0 0x400d179a:0x3ffc8620 0x400d1943:0x3ffc8670 0x400d76dd:0x3ffc86b0 0x4008ff39:0x3ffc86d0
I tried pasting these into the "ESP Exception Decoder" but it just says "Decode failed"...
Here is my full code.
#include "BLEDevice.h"
#include <stdint.h>
//#include "BLEScan.h"
// The remote service we wish to connect to.
static BLEUUID serviceUUID("71c1e128-d92f-4fa8-a2b2-0f171db3436c");
// The characteristic of the remote service we are interested in.
static BLEUUID charUUID("503dd605-9bcb-4f6e-b235-270a57483026");
static BLEAddress *pServerAddress;
static boolean doConnect = false;
static boolean connected = false;
static BLERemoteCharacteristic* pRemoteCharacteristic;
static BLEClient* pClient;
volatile bool notifyTrigger = false;
static void notifyCallback(
BLERemoteCharacteristic* pBLERemoteCharacteristic,
uint8_t* pData,
size_t length,
bool isNotify) {
if (isNotify) {
notifyTrigger = true;
}
}
bool connectToServer(BLEAddress pAddress) {
Serial.print("Forming a connection to ");
Serial.println(pAddress.toString().c_str());
// Connect to the remove BLE Server.
bool connected = pClient->connect(pAddress);
if (!connected) {
Serial.println("Connection failed.");
return false;
}
Serial.println(" - Connected to server");
// Obtain a reference to the service we are after in the remote BLE server.
BLERemoteService* pRemoteService = pClient->getService(serviceUUID);
if (pRemoteService == nullptr) {
Serial.print("Failed to find our service UUID: ");
Serial.println(serviceUUID.toString().c_str());
return false;
}
Serial.println(" - Found our service");
// Obtain a reference to the characteristic in the service of the remote BLE server.
pRemoteCharacteristic = pRemoteService->getCharacteristic(charUUID);
if (pRemoteCharacteristic == nullptr) {
Serial.print("Failed to find our characteristic UUID: ");
Serial.println(charUUID.toString().c_str());
return false;
}
Serial.println(" - Found our characteristic");
Serial.println("Can read:");
Serial.println(pRemoteCharacteristic->canRead());
const uint8_t notifyOn[] = {0x01, 0x00};
Serial.println("Setting descriptor");
pRemoteCharacteristic->getDescriptor(BLEUUID((uint16_t)0x2902))->writeValue((uint8_t*)notifyOn, 2, true);
Serial.println("Registering");
pRemoteCharacteristic->registerForNotify(notifyCallback);
return true;
}
/**
* Scan for BLE servers and find the first one that advertises the service we are looking for.
*/
class MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks {
/**
* Called for each advertising BLE server.
*/
void onResult(BLEAdvertisedDevice advertisedDevice) {
Serial.print("BLE Advertised Device found: ");
Serial.println(advertisedDevice.toString().c_str());
// We have found a device, let us now see if it contains the service we are looking for.
if (advertisedDevice.haveServiceUUID() && advertisedDevice.getServiceUUID().equals(serviceUUID)) {
advertisedDevice.getScan()->stop();
pServerAddress = new BLEAddress(advertisedDevice.getAddress());
doConnect = true;
Serial.println("This device is correct!");
} // Found our server
} // onResult
}; // MyAdvertisedDeviceCallbacks
void setup() {
Serial.begin(115200);
Serial.println("Starting Arduino BLE Client application...");
BLEDevice::init("Fahrradnavi");
pClient = BLEDevice::createClient();
scan();
} // End of setup.
void scan() {
BLEScan* pBLEScan = BLEDevice::getScan();
pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());
pBLEScan->setActiveScan(true);
pBLEScan->setInterval(1349);
pBLEScan->setWindow(449);
pBLEScan->start(5, false);
}
// This is the Arduino main loop function.
void loop() {
// If the flag "doConnect" is true then we have scanned for and found the desired
// BLE Server with which we wish to connect. Now we connect to it. Once we are
// connected we set the connected flag to be true.
if (doConnect == true) {
if (connectToServer(*pServerAddress)) {
Serial.println("We are now connected to the BLE Server.");
connected = true;
doConnect = false;
} else {
Serial.println("We have failed to connect to the server; which means we will try again.");
doConnect = false;
scan();
}
}
if (notifyTrigger == true) {
std::string value = pRemoteCharacteristic->readValue();
Serial.println(value.c_str());
}
delay(1000); // Delay a second between loops.
} // End of loop
I have more info: the debug logs say:
[V][BLERemoteCharacteristic.cpp:438] registerForNotify(): >> registerForNotify(): Characteristic: uuid: 503dd605-9bcb-4f6e-b235-270a574830, handle: 42 0x002a, props: broadcast: 0, read: 1, write_nr: 0, write: 0, notify: 1, indicate: 0, auth: 0
[D][FreeRTOS.cpp:189] take(): Semaphore taking: name: RegForNotifyEvt (0x3ffdf9b4), owner: <N/A> for registerForNotify
[D][FreeRTOS.cpp:198] take(): Semaphore taken: name: RegForNotifyEvt (0x3ffdf9b4), owner: registerForNotify
[V][BLERemoteCharacteristic.cpp:323] getDescriptor(): >> getDescriptor: uuid: 2902-0000-1000-8000-00805f9b34fb
[V][BLEUtils.cpp:951] gattClientEventTypeToString(): Unknown GATT Client event type: 38
[V][BLERemoteCharacteristic.cpp:331] getDescriptor(): << getDescriptor: Not found
So, the descriptor is not found.
Which is, as I believe, a problem of the BLE service on the other end, not of this API.
I have the same problem, and want to make my code robust against problems on the other end. Other than a watchdog timer, is there any way I can protect against never returning from registerForNotify?
Hello!, I also run into this problem too. This is what I got
Guru Meditation Error: Core 1 panic'ed (LoadProhibited). Exception was unhandled.
Core 1 register dump:
PC : 0x400d52f3 PS : 0x00060330 A0 : 0x800d4b4e A1 : 0x3ffc95a0
A2 : 0x00000000 A3 : 0x3ffc95de A4 : 0x00000002 A5 : 0x00000000
A6 : 0x3ffe0d4c A7 : 0x3f019620 A8 : 0x800d48d8 A9 : 0x3ffc9550
A10 : 0x3ffc959c A11 : 0x53f4a06c A12 : 0x3ffc5318 A13 : 0x53f4a06c
A14 : 0x3ffc9550 A15 : 0xff000000 SAR : 0x00000018 EXCCAUSE: 0x0000001c
EXCVADDR: 0x00000030 LBEG : 0x4000c2e0 LEND : 0x4000c2f6 LCOUNT : 0x00000000
Backtrace: 0x400d52f3:0x3ffc95a0 0x400d4b4b:0x3ffc95d0 0x400d1f52:0x3ffc9620 0x400d2011:0x3ffc9670 0x400d7b19:0x3ffc96e0 0x4008e089:0x3ffc9700
and the exception decoder
0x400d52f3: BLERemoteDescriptor::writeValue(unsigned char, unsigned int, bool) at C:\Users\Automata\Documents\Arduino\libraries\ESP32_BLE_Arduino\src\BLERemoteDescriptor.cpp line 146
0x400d4b4b: BLERemoteCharacteristic::registerForNotify(void ()(BLERemoteCharacteristic, unsigned char, unsigned int, bool), bool) at C:\Users\Automata\Documents\Arduino\libraries\ESP32_BLE_Arduino\src\BLERemoteCharacteristic.cpp line 453
0x400d1f52: connectToServer() at C:\Users\Automata\Documents\Arduino\BLE_client/BLE_client.ino line 78
0x400d2011: connectToServer() at C:\Users\Automata\Documents\Arduino\BLE_client/BLE_client.ino line 105
0x400d7b19: String::substring(unsigned int, unsigned int) const at C:\Users\Automata\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.4\cores\esp32\WString.cpp line 710
0x4008e089: vPortTaskWrapper at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/freertos/port.c line 143
I don't know what I missing but this happened after read the characteristic value and keep rebooting.
I continue to have this issue, did the issue get resolved before it was closed?
I had hoped to hear from developers about this, for now my application is running with a watchdog timer and rebooting daily. I'm probably making some dumb rook mistake, and it's beneath anyone to comment. That or nobody has time to look at this issue. Maybe BLE is less popular than wifi. Unfortunately, for my application it's a key technology.
This has been answered already and closed by author.
Which is, as I believe, a problem of the BLE service on the other end, not of this API.
You have to check in app if characteristic has property notify/indicate. Then it is good to check if that characteristic has descriptor 0x2902. I saw few opened issues where the problem was it was missing this descriptor. When you try to write it and it is missing then app will crash.
Thanks @chegewara , is this descriptor present when creating characteristics on the BLE server using the espressif Arduino core? If not, can I simply replace the BLE code in the Arduino core with the nkolban BLE code?
Or is there an example I can look for?
You have to add it each time, but it is easy.
Search for ble 2902 and you will find plenty examples.
Thank you very much @chegewara!
Most helpful comment
This has been answered already and closed by author.
You have to check in app if characteristic has property notify/indicate. Then it is good to check if that characteristic has descriptor 0x2902. I saw few opened issues where the problem was it was missing this descriptor. When you try to write it and it is missing then app will crash.