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

ESP32 couldn't Find Service #1126

Open Fuzzy-Mind opened 2 years ago

Fuzzy-Mind commented 2 years ago

Hi, First of all thanks for the library, i love it.

I’m trying to connect a BLE sensor with ESP32 development module by using BLE_client.ino script. I can connect the service with Raspbery Pi 4 via bluetoothctl tool but i couldn't connect with BLE_client.ino script. ESP32 device couldn't find service

Here steps that i followed; STEP 1 : List of services and characteristics linux1_marked

STEP 2 : Select service linux4

STEP 3 : Enable notifications linux6_marked


When I tried with ESP32 dev module and BLE_client.ino script;

STEP 1 : Edited service and characteristic UUID ard_1

STEP 2 : If the device cannot find the service, print “No Service” for debug. ard_2

STEP 3 : Device couldnt find service. ard_3

Why can't the ESP32 dev module find the service? How can I solve this problem?

PS: Other services work well except "fff0" and "fff4". When i tried "1809" and "2a1e" it works.

chegewara commented 2 years ago

Its because you are mixing 2 things. Advertising and advertised service is not the same as services UUID which you get after connecting. Device can advertise any service UUID or none, and then when you connect you have to discover services which can be completely different.

Fuzzy-Mind commented 2 years ago

Thank you for your quick reply. I am newbie to BLE library.

I edited the script a little bit. After connecting, I checked the services. Currently I can find the service UUID and characteristic UUID. But I'm getting the "Guru Meditation Error: Core 1 panic'ed (LoadProhibited). Exception was unhandled." error.

guru1

guru2

Here my script;

#include "BLEDevice.h"
//#include "BLEScan.h"

static String choistecMacAddress = "d8:71:4d:bc:f5:f1";
static BLEUUID serviceUUID("0000fff0-0000-1000-8000-00805f9b34fb");
static BLEUUID    charUUID("0000fff4-0000-1000-8000-00805f9b34fb"); 

static boolean doConnect = false;
static boolean connected = false;
static boolean doScan = false;
static BLERemoteCharacteristic* pRemoteCharacteristic;
static BLEAdvertisedDevice* myDevice;

static BLEAddress *Server_BLE_Address;
String Scaned_BLE_Address;

static void notifyCallback(
  BLERemoteCharacteristic* pBLERemoteCharacteristic,
  uint8_t* pData,
  size_t length,
  bool isNotify) {
    Serial.print("Notify callback for characteristic ");
    Serial.print(pBLERemoteCharacteristic->getUUID().toString().c_str());
    Serial.print(" of data length ");
    Serial.println(length);
    Serial.print("data: ");
    Serial.println((char*)pData);
}

class MyClientCallback : public BLEClientCallbacks {
  void onConnect(BLEClient* pclient) {
  }

  void onDisconnect(BLEClient* pclient) {
    connected = false;
    Serial.println("onDisconnect");
  }
};

bool connectToServer() {
    Serial.print("Forming a connection to ");
    Serial.println(myDevice->getAddress().toString().c_str());

    BLEClient*  pClient  = BLEDevice::createClient();
    Serial.println(" - Created client");

    pClient->setClientCallbacks(new MyClientCallback());

    // Connect to the remove BLE Server.
    pClient->connect(myDevice);  // if you pass BLEAdvertisedDevice instead of address, it will be recognized type of peer device address (public or private)
    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());
      pClient->disconnect();
      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());
      pClient->disconnect();
      return false;
    }
    Serial.println(" - Found our characteristic");

    // Read the value of the characteristic.
    if(pRemoteCharacteristic->canRead()) {
      std::string value = pRemoteCharacteristic->readValue();
      Serial.print("The characteristic value was: ");
      Serial.println(value.c_str());
    }

    if(pRemoteCharacteristic->canNotify())
      pRemoteCharacteristic->registerForNotify(notifyCallback);

    connected = 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: ");
    Server_BLE_Address = new BLEAddress(advertisedDevice.getAddress());
    Scaned_BLE_Address = Server_BLE_Address->toString().c_str();
    Serial.println(Scaned_BLE_Address);

    // We have found a device, let us now see if it contains the service we are looking for.
    if (Scaned_BLE_Address == choistecMacAddress) {
      BLEDevice::getScan()->stop();
      myDevice = new BLEAdvertisedDevice(advertisedDevice);
      doConnect = true;
      doScan = true;
    } // Found our server
  } // onResult
}; // MyAdvertisedDeviceCallbacks

void setup() {
  Serial.begin(115200);
  Serial.println("Starting Arduino BLE Client application...");
  BLEDevice::init("");

  // Retrieve a Scanner and set the callback we want to use to be informed when we
  // have detected a new device.  Specify that we want active scanning and start the
  // scan to run for 5 seconds.
  BLEScan* pBLEScan = BLEDevice::getScan();
  pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());
  pBLEScan->setInterval(1349);
  pBLEScan->setWindow(449);
  pBLEScan->setActiveScan(true);
  pBLEScan->start(5, false);
} // End of setup.

// This is the Arduino main loop function.
void loop() {

  if (doConnect == true) {
    if (connectToServer()) {
      Serial.println("We are now connected to the BLE Server.");
    } else {
      Serial.println("We have failed to connect to the server; there is nothin more we will do.");
    }
    doConnect = false;
  }

  if (connected) {
    Serial.println("Connected");
  }else if(doScan){
    BLEDevice::getScan()->start(0);  // this is just eample to start scan after disconnect, most likely there is better way to do it in arduino
  }

  delay(1000); // Delay a second between loops.
} // End of loop

Is there a way to solve this problem?