I am testing with multiple BLE Buttons with Bluetooth HID profile.
Pressing the button shows the equivalent behavior of pressing a key on the keyboard.
It seems to be very very stable compared to the original BLEClient !!
In simultaneous connection, if the number of BLE Buttons is one or two, no problem has been found, but if it is three, a Panic error will occur immediately after pairing.
#include <NimBLEDevice.h>
static void notifyCallback(BLERemoteCharacteristic* pRemoteCharacteristic, uint8_t* pData, size_t length, bool isNotify) {
Serial.printf("notifyCallback: %s %s handle: %02x value:", pRemoteCharacteristic->getRemoteService()->getClient()->getPeerAddress().toString().c_str(), pRemoteCharacteristic->getUUID().toString().c_str(), pRemoteCharacteristic->getHandle());
for (int i=0; i<length; i++)
Serial.printf(" %02x", pData[i]);
Serial.println();
}
void setup() {
Serial.begin(115200);
NimBLEDevice::init("");
auto* pBLEScan = NimBLEDevice::getScan();
pBLEScan->setActiveScan(true);
Serial.println("wait 10 secs..");
auto pScanResults = pBLEScan->start(10);
for (int i = 0; i < pScanResults.getCount(); i++) {
auto advertisedDevice = pScanResults.getDevice(i);
if (advertisedDevice.haveServiceUUID()) {
Serial.print("Found Device ");
Serial.print(advertisedDevice.toString().c_str());
auto pClient = NimBLEDevice::createClient();
if(pClient && pClient->connect(&advertisedDevice)) {
auto* pRemoteServiceMap = pClient->getServices();
for (auto itr : *pRemoteServiceMap) {
auto *pCharacteristicMap = itr.second->getCharacteristicsByHandle();
for (auto itr : *pCharacteristicMap)
if(itr.second->canNotify())
if(itr.second->registerForNotify(notifyCallback)) {
Serial.printf("registerForNotify: %s %s handle:%02x", pClient->getPeerAddress().toString().c_str(), itr.second->getUUID().toString().c_str(), itr.second->getHandle());
Serial.println();
}
}
}
}
}
}
void loop() {
delay(1);
}
The log is too long, so here is the most recent panic error:
06:22:14.081 -> D NimBLERemoteCharacteristic: ">> registerForNotify(): Characteristic: uuid: 0x2a4d, handle: 23 0x0017, props: 0x12
06:22:14.081 -> Descriptor: uuid: 0x2902, handle: 24
06:22:14.128 -> Descriptor: uuid: 0x2908, handle: 25"
06:22:14.128 -> D NimBLERemoteCharacteristic: ">> getDescriptor: uuid: 0x2902"
06:22:14.128 -> D NimBLERemoteCharacteristic: "<< getDescriptor: found"
06:22:14.128 -> D NimBLERemoteCharacteristic: "<< registerForNotify()"
06:22:14.128 -> D NimBLERemoteDescriptor: ">> Descriptor writeValue: Descriptor: uuid: 0x2902, handle: 24"
06:22:14.128 -> D FreeRTOS: "Semaphore taking: name: WriteDescEvt (0x3ffd2178), owner: <N/A> for WriteDescriptor"
06:22:14.128 -> D FreeRTOS: "Semaphore taken: name: WriteDescEvt (0x3ffd2178), owner: WriteDescriptor"
06:22:14.128 -> D FreeRTOS: ">> wait: Semaphore waiting: name: WriteDescEvt (0x3ffd2178), owner: WriteDescriptor for WriteDescriptor"
06:22:14.221 -> D NimBLERemoteDescriptor: "Write complete; status=0 conn_handle=2"
06:22:14.221 -> D FreeRTOS: "Semaphore giving: name: WriteDescEvt (0x3ffd2178), owner: WriteDescriptor"
06:22:14.221 -> D FreeRTOS: "<< wait: Semaphore released: name: WriteDescEvt (0x3ffd2178), owner: <N/A>"
06:22:14.221 -> D NimBLERemoteDescriptor: "<< Descriptor writeValue, rc: 0"
06:22:14.221 -> registerForNotify: ff:ff:c5:05:f5:2a 0x2a4d handle:17
06:22:15.066 -> D NimBLEClient: "Got Client event BLE_GAP_EVENT_L2CAP_UPDATE_REQ"
06:22:15.066 -> D NimBLEClient: "Peer requesting to update connection parameters"
06:22:15.066 -> D NimBLEClient: "MinInterval: 16, MaxInterval: 32, Latency: 2, Timeout: 100, min_ce_len:16,max_ce_len:768"
06:22:15.066 -> Guru Meditation Error: Core 0 panic'ed (LoadProhibited). Exception was unhandled.
06:22:15.066 -> Core 0 register dump:
06:22:15.066 -> PC : 0x401184d6 PS : 0x00060130 A0 : 0x80049b9c A1 : 0x3ffb5d40
06:22:15.066 -> A2 : 0x07ffffff A3 : 0x00009660 A4 : 0x000000a8 A5 : 0x00000001
06:22:15.113 -> A6 : 0x3ffb5da0 A7 : 0x00000000 A8 : 0x3ffb2ec4 A9 : 0x3ffb5d20
06:22:15.113 -> A10 : 0x0030bb00 A11 : 0x00000001 A12 : 0x00000000 A13 : 0x3ffafd68
06:22:15.113 -> A14 : 0x00000000 A15 : 0x3ffb8360 SAR : 0x00000016 EXCCAUSE: 0x0000001c
06:22:15.113 -> EXCVADDR: 0x00000008 LBEG : 0x4000c2e0 LEND : 0x4000c2f6 LCOUNT : 0x00000000
06:22:15.113 ->
06:22:15.113 -> ELF file SHA256: 0000000000000000000000000000000000000000000000000000000000000000
06:22:15.113 ->
06:22:15.113 -> Backtrace: 0x401184d6:0x3ffb5d40 0x40049b99:0x3ffb5da0 0x400457cd:0x3ffb5dd0 0x4001a637:0x3ffb5e10 0x40019d11:0x3ffb5e40 0x40055b4d:0x3ffb5e60 0x40112ddf:0x3ffb5e80 0x40113331:0x3ffb5ea0 0x4009066d:0x3ffb5ed0
06:22:15.113 ->
06:22:15.113 -> Rebooting...
06:22:15.160 -> ets Jun 8 2016 00:22:57
I don't know how to look at the backtrace, but it seems that an error occurs immediately after NimBLEClient :: handleGapEvent receives BLE_GAP_EVENT_L2CAP_UPDATE_REQ generated by the device and returns rc = 0 indicating normality.
Forcing the device to reject the request does not cause the Panic error, albeit with a different problem.
case BLE_GAP_EVENT_CONN_UPDATE_REQ:
case BLE_GAP_EVENT_L2CAP_UPDATE_REQ: {
if(client->m_conn_id != event->conn_update_req.conn_handle){
return 0; //BLE_HS_ENOTCONN BLE_ATT_ERR_INVALID_HANDLE
}
return BLE_ERR_CONN_PARMS; // Adding this line will avoid Panic errors, but ...
Is there anything you can think of ?
I'm just getting started with JTAG, but I'm glad if I can tell you what to try.