How to parse data to use in a conditional statement

I'm using a ESP32 to as a proximity sensor to safeguard several android devices that are running an ibeacon simulator that's always on that the ESP32 is capable of detecting - which I've tested to make sure it works (see attached image).

Although, the mac addresses that the ibeacon simulator outputs constantly changes and therefore cannot be used, the manufactures id/data however from the ibeacon remains constant which can be used. As such when the code runs the following line...

Serial.printf("Advertised Device: %s \n", advertisedDevice.toString().c_str());

it outputs the entire ibeacon information which can be read in the attached image starting at the line reading "Advertised Device:..." letting me know that the code and the ESP32 are working properly to read and acquire the data of all the ibeacons in the area.

However, when I tell the code to execute a conditional function when the acquired manufacture data matches the manufacture data stored as a string in knownBLEAddresses... the condition does not function.

String knownBLEAddresses[] = {"4c000215b9a6adffaea94703903a58437a4d9d2400000000fd"};

As such, I then enabled the debugging within the code to see what the code is pulling as the just the manufacture data but for reasons unknown it only returns a single character or sometimes jibberish - which I've marked in red in the image. Which explains why the condition is not executing.

Serial.println(advertisedDevice.getManufacturerData().c_str());

So, unless someone can explain why the getManufacturerData() is not returning the correct information, I think the best work around to is parse the manufacture data (underlined in blue within the image) directly from

advertisedDevice.toString().c_str()

and use that to somehow match the manufacture data string stored within knownBLEAddresses and then use that to make this condition true somehow.

if (strcmp(advertisedDevice.getManufacturerData().toString().c_str(), knownBLEAddresses[i].c_str()) == 0)
                        {
          device_found = true;

However, I have no idea where to begin and could use some help.

Here is the entire code for reference.

#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEScan.h>
#include <BLEAdvertisedDevice.h>
#define LED 2
String knownBLEAddresses[] = {"4c000215b9a6adffaea94703903a58437a4d9d2400000000fd"};
int RSSI_THRESHOLD = -120;
bool device_found;
int scanTime = 5; //In seconds
BLEScan* pBLEScan;
class MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks {
    void onResult(BLEAdvertisedDevice advertisedDevice) {
      for (int i = 0; i < (sizeof(knownBLEAddresses) / sizeof(knownBLEAddresses[0])); i++)
      {
        //Uncomment to Enable Debug Information
        Serial.println("*************Start**************");
        Serial.println(sizeof(knownBLEAddresses));
        Serial.println(sizeof(knownBLEAddresses[0]));
        Serial.println(sizeof(knownBLEAddresses)/sizeof(knownBLEAddresses[0]));
        Serial.println(advertisedDevice.getManufacturerData().c_str());
        Serial.println(knownBLEAddresses[i].c_str());
        Serial.println("*************End**************");
        if (strcmp(advertisedDevice.getManufacturerData().toString().c_str(), knownBLEAddresses[i].c_str()) == 0)
                        {
          device_found = true;
                          //break;
                        }
        else
          device_found = false;
      }
      Serial.printf("Advertised Device: %s \n", advertisedDevice.toString().c_str());
    }
};
void setup() {
  Serial.begin(115200); //Enable UART on ESP32
  Serial.println("Scanning..."); // Print Scanning
  pinMode(LED, OUTPUT); //make BUILTIN_LED pin as output
  BLEDevice::init("");
  pBLEScan = BLEDevice::getScan(); //create new scan
  pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks()); //Init Callback Function
  pBLEScan->setActiveScan(true); //active scan uses more power, but get results faster
  pBLEScan->setInterval(100); // set Scan interval
  pBLEScan->setWindow(99);  // less or equal setInterval value
}
void loop() {
  // put your main code here, to run repeatedly:
  BLEScanResults foundDevices = pBLEScan->start(scanTime, false);
  for (int i = 0; i < foundDevices.getCount(); i++)
  {
    BLEAdvertisedDevice device = foundDevices.getDevice(i);
    int rssi = device.getRSSI();
    Serial.print("RSSI: ");
    Serial.println(rssi);
    if (rssi > RSSI_THRESHOLD && device_found == true)
      digitalWrite(LED, HIGH);
    else
      digitalWrite(LED, LOW);
  }
  pBLEScan->clearResults();   // delete results fromBLEScan buffer to release memory
}

Thank you

You do know that strcmp() returns 0 if the two strings are equal, don't you?

Are you sure your sketch compiles? When I select "ESP32 Dev Module" I get the following compile error:

sketch_jul22a.ino: In member function 'virtual void MyAdvertisedDeviceCallbacks::onResult(BLEAdvertisedDevice)':
sketch_jul22a:25:59: error: 'std::__cxx11::string' {aka 'class std::__cxx11::basic_string<char>'} has no member named 'toString'
         if (strcmp(advertisedDevice.getManufacturerData().toString().c_str(), knownBLEAddresses[i].c_str()) == 0)
                                                           ^~~~~~~~
exit status 1

A working alternative is:

std::string knownBLEAddresses[] = 

         if (advertisedDevice.getManufacturerData() == knownBLEAddresses[i])

are you using 1.0.4 for theESP32 Dev Module? That's the version I'm using and yes I'm sure it compiles. And this ``std::string knownBLEAddresses[] =

     if (advertisedDevice.getManufacturerData() == knownBLEAddresses[i])``

won't work at the getManufacturerData() is returning nonsense, as its mentioned here in this article - https://github.com/nkolban/esp32-snippets/issues/565

Do you mean the ESP32 core version? I have 2.0.4 installed which appears to be the most current.

yes, I have to use 1.0.4 for this project

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.