nkolban / esp32-snippets

Sample ESP32 snippets and code fragments
https://leanpub.com/kolban-ESP32
Apache License 2.0
2.37k stars 710 forks source link

Crash on pRemoteCharacteristic->getDescriptor(BLEUUID("0x2902"))->writeValue((uint8_t*)notificationOn, 2, true); #1066

Open DShabroff opened 3 years ago

DShabroff commented 3 years ago

Get guaranteed processor reset on line

pRemoteCharacteristic->getDescriptor(BLEUUID("0x2902"))->writeValue((uint8_t*)notificationOn, 2, true);

Guru Meditation Error: Core 1 panic'ed (LoadProhibited). Exception was unhandled. Core 1 register dump: PC : 0x400d52b2 PS : 0x00060530 A0 : 0x800d17cc A1 : 0x3ffc7130
A2 : 0x00000000 A3 : 0x3f4003fc A4 : 0x00000002 A5 : 0x00000001
A6 : 0x3ffc425c A7 : 0x0000fc72 A8 : 0x800d4761 A9 : 0x3ffc7110
A10 : 0x3ffc715c A11 : 0xf8acc258 A12 : 0x3ffc425c A13 : 0xf8acc258
A14 : 0x00ff0000 A15 : 0xff000000 SAR : 0x00000010 EXCCAUSE: 0x0000001c
EXCVADDR: 0x00000030 LBEG : 0x4000c2e0 LEND : 0x4000c2f6 LCOUNT : 0xffffffff

The characteristic is:

Blood Pressure (0x1810)

  • Blood Pressure Measurement [I] (0x2A35)  Client Characteristic Configuration (0x2902)
  • Blood Pressure Feature [R] (0x2A49)
  • Date Time [R W] (0x2A08)

Code is:

    if(pRemoteCharacteristic->canRead())                                                //pRemoteCharacteristic->canRead() ВОЗВРАЩАЕТ 0
    {
      std::string value = pRemoteCharacteristic->readValue();
      Serial.print("The characteristic value was: ");
      Serial.println(value.c_str());
    }
    else
      {
        Serial.println("pRemoteCharacteristic->canRead() = 0");
      }
    if(pRemoteCharacteristic->canIndicate())                                            //pRemoteCharacteristic->canNotify() ВОЗВРАЩАЕТ 0
      {
          pRemoteCharacteristic->registerForNotify(notifyCallback, false);              //pRemoteCharacteristic->canIndicate() ВОЗВРАЩАЕТ 1
      }                                                                                 //false for listen indications and true for listen notifications
    else
      {
        Serial.println("pRemoteCharacteristic->canIndicate() = 0");
      }
    pRemoteCharacteristic->getDescriptor(BLEUUID("0x2902"))->writeValue((uint8_t*)notificationOn, 2, true);

Last line give the reset. Log:

Starting Arduino BLE Client application... BLE Advertised Device found: Name: A&D_UA-651BLE_8FCFAC, Address: 34:14:b5:8f:cf:ac, serviceUUID: 00001810-0000-1000-8000-00805f9b34fb, txPower: 0 Forming a connection to 34:14:b5:8f:cf:ac

  • Connected to server
  • Found our service
  • Found our characteristic

// The remote service we wish to connect to. static BLEUUID serviceUUID("00001810-0000-1000-8000-00805f9b34fb"); // The characteristic of the remote service we are interested in. static BLEUUID charUUID("00002a35-0000-1000-8000-00805f9b34fb");

Please, help me. Thank you.

chegewara commented 3 years ago

Is there any reason you want this characteristic notifications? As far as i remember it is used only to inform about service change on peer device and almost never is used.

DShabroff commented 3 years ago

Perhaps I do not understand something. I need to read the pressure from the tonometer. As shows nRFConnect, the characteristic 2A35 has no value S10401-18285850

, but has the property of indication. How then can I read the pressure value?

The code bellow shows me same information. 2A35 can indicate.

//Read the value of the characteristic.
    if(pRemoteCharacteristic->canRead())                                                //pRemoteCharacteristic->canRead() ВОЗВРАЩАЕТ 0
      {
        Serial.println("canRead = 1!!!");
        std::string value = pRemoteCharacteristic->readValue();
        Serial.print("The characteristic value was: ");
        Serial.println(value.c_str());
      }
    if(pRemoteCharacteristic->canIndicate())
      {
          pRemoteCharacteristic->registerForNotify(notifyCallback, false);
          Serial.println("canIndicate = 1!!!");
      }
    if(pRemoteCharacteristic->canWrite())
      {
          Serial.println("canWrite = 1!!!");
      }
    if(pRemoteCharacteristic->canNotify())
      {
          Serial.println("canNotify = 1!!!");
      }
//включение/выключение уведомлений:
    const uint8_t indicationOn[] =  {0x2, 0x0};
    const uint8_t indicationOff[] = {0x0, 0x0};
    pRemoteCharacteristic->getDescriptor(BLEUUID("0x2902"))->writeValue((uint8_t*)indicationOn, 2, true);   

but if I include last line, processor reboot. Please tell me - what I must to do? Thank you.

chegewara commented 3 years ago

Sorry, my bad. I didnt work with BLE for some time and mixed 0x1810 with 0x1801 service UUIDs and 0x2A35 and 0x2A05 char UUIDs.

chegewara commented 3 years ago

My suggestion is to do it this way:

BLE2902 p2902 = pRemoteCharacteristic->getDescriptor(BLEUUID("0x2902"));
if(p2902 != nullptr) p2902->writeValue((uint8_t*)indicationOn, 2, true);  

I may be wrong, but enable indicate should be 0x01, not 0x02;

DShabroff commented 3 years ago

Thank you are for code. Now processor is not reset, but indicate still does not work yet. I corrected your code a little. BLE2902 p2902 =... does not compile. Error is:

'BLE2902' was not declared in this scope

I change this to:

BLERemoteDescriptor* p2902 =...

And second as explained here :

https://github.com/nkolban/esp32-snippets/issues/618#issuecomment-423824201

BLEUUID("0x2902") is not working. The correct way is:

getDescriptor(BLEUUID((uint16_t)0x2902));

So the code:

const uint8_t indicationOn[] = {0x1, 0x0}; const uint8_t indicationOff[] = {0x0, 0x0}; BLERemoteDescriptor p2902 = pRemoteCharacteristic->getDescriptor(BLEUUID((uint16_t)0x2902)); if(p2902 != nullptr) { p2902->writeValue((uint8_t)indicationOn, 2, true); Serial.println("p2902!!!"); }

at least finds the descriptor and does not reset the processor! I have moved forward a bit. Many thanks.

chegewara commented 3 years ago

Yes. Like i said, i did not work with BLE for some time, thus so many little bugs, but im glad you fixed them.

What i can suggest is: 1) after connecting with esp32 you can try to connect with nRF connect and check if indications are enabled on 0x2902 (i am guessing it is disabled when you connect just with nRF connect) 2) try to add custom callbacks, which has been added to library for better debugging, you can find more info in few issues here https://github.com/nkolban/esp32-snippets/blob/master/cpp_utils/BLEDevice.h#L27-L29 https://github.com/nkolban/esp32-snippets/blob/master/cpp_utils/BLEDevice.h#L60-L62

DShabroff commented 3 years ago

Thanks for the answer. I wrote simple code for functions:

static void gattcEventHandler(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if, esp_ble_gattc_cb_param_t* param) { Serial.printf("gattc event %i detected\n", (uint8_t)event); } static void my_gatts_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gattc_if, esp_ble_gatts_cb_param_t* param) { Serial.printf("gatts event %i detected\n", (uint8_t)event); } static void my_gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t* param) { Serial.printf("gap event %i detected\n", (uint8_t)event); }

Setup pointed to the functions:

BLEDevice::setCustomGattcHandler(gattcEventHandler); // BLEDevice::setCustomGattsHandler(my_gatts_event_handler); // BLEDevice::setCustomGapHandler(my_gap_event_handler); And got the result:

Starting Arduino BLE Client application... gap event 2 detected gap event 7 detected BLE Advertised Device found: Name: A&D_UA-651BLE_8FCFAC, Address: 34:14:b5:8f:cf:ac, serviceUUID: 00001810-0000-1000-8000-00805f9b34fb, txPower: 0 gap event 3 detected gap event 18 detected Forming a connection to 34:14:b5:8f:cf:ac gattc event 0 detected gattc event 40 detected

  • Connected to server gattc event 2 detected gap event 8 detected gattc event 7 detected gattc event 7 detected gattc event 7 detected gattc event 7 detected gattc event 7 detected gattc event 7 detected gattc event 6 detected
  • Found our service
  • Found our characteristic

How to interpret this result? Perhaps I did something wrong.

DShabroff commented 3 years ago

I wanted to say that the code

BLERemoteDescriptor* p2902 = pRemoteCharacteristic->getDescriptor(BLEUUID((uint16_t)0x2902)); if(p2902 != nullptr) { pRemoteCharacteristic->getDescriptor(BLEUUID((uint16_t)0x2902))->writeValue((uint8_t*)indicationOn, 2, true); Serial.println("p2902!!!"); }

Works too. The processor was reset when I connected witn charUUID not equal charUUID("00002a35");. Where there is no charUUID ("00002902") ;. If you do not check for the presence of charUUID ("00002902"), we will get a reset.

RobosoftSystems commented 2 years ago

Hello,

I am also stuck on the same problem . Were you able to pull BP data from the unit?