1

When I use my ESP32 to emit a BLE iBeacon signal there seems to be something wrong with the signal. It emits a bluetooth signal, but it's not recognized as an iBeacon signal.

I have an ESP32 Wroom32 DevKit V1 / ESP32-D0WD-V3 (revision v3.0), use the Arduino IDE with the board manager set to V2.0.7. The device is bare and completely new.

Don't know if it's relevant, but some times there is a warning that the frequency of the crystal is off: WARNING: Detected crystal freq 41.01MHz is quite different to normalized freq 40MHz. Unsupported crystal in use? Crystal is 40MHz

I tried the default ESP32 iBeacon Arduino demo sketch below. This and other attempts all result in the same; the upload succeeds fine, the serial output is fine, and ESP32 emits a bluetooth signal, but isn't recognized as an iBeacon (or beacon of any kind) like shown in the screenshot of the nRF Connect app.

Can some one spot what I might be missing here?

#include <BLEDevice.h>
#include <BLEServer.h>
#include <BLEUtils.h>
#include <BLE2902.h>
#include <BLEBeacon.h>

#define DEVICE_NAME            "ESP32"
#define SERVICE_UUID           "7A0247E7-8E88-409B-A959-AB5092DDB03E"
#define BEACON_UUID            "2D7A9F0C-E0E8-4CC9-A71B-A21DB2D034A1"
#define BEACON_UUID_REV        "A134D0B2-1DA2-1BA7-C94C-E8E00C9F7A2D"
#define CHARACTERISTIC_UUID    "82258BAA-DF72-47E8-99BC-B73D7ECD08A5"

BLEServer *pServer;
BLECharacteristic *pCharacteristic;
bool deviceConnected = false;
uint8_t value = 0;

class MyServerCallbacks: public BLEServerCallbacks {
    void onConnect(BLEServer* pServer) {
      deviceConnected = true;
      Serial.println("deviceConnected = true");
    };

    void onDisconnect(BLEServer* pServer) {
      deviceConnected = false;
      Serial.println("deviceConnected = false");

      // Restart advertising to be visible and connectable again
      BLEAdvertising* pAdvertising;
      pAdvertising = pServer->getAdvertising();
      pAdvertising->start();
      Serial.println("iBeacon advertising restarted");
    }
};

class MyCallbacks: public BLECharacteristicCallbacks {
    void onWrite(BLECharacteristic *pCharacteristic) {
      std::string rxValue = pCharacteristic->getValue();

      if (rxValue.length() > 0) {
        Serial.println("*********");
        Serial.print("Received Value: ");
        for (int i = 0; i < rxValue.length(); i++) {
          Serial.print(rxValue[i]);
        }
        Serial.println();
        Serial.println("*********");

      }
    }
};


void init_service() {
  BLEAdvertising* pAdvertising;
  pAdvertising = pServer->getAdvertising();
  pAdvertising->stop();

  // Create the BLE Service
  BLEService *pService = pServer->createService(BLEUUID(SERVICE_UUID));

  // Create a BLE Characteristic
  pCharacteristic = pService->createCharacteristic(
                      CHARACTERISTIC_UUID,
                      BLECharacteristic::PROPERTY_READ   |
                      BLECharacteristic::PROPERTY_WRITE  |
                      BLECharacteristic::PROPERTY_NOTIFY
                    );
  pCharacteristic->setCallbacks(new MyCallbacks());
  pCharacteristic->addDescriptor(new BLE2902());

  pAdvertising->addServiceUUID(BLEUUID(SERVICE_UUID));

  // Start the service
  pService->start();

  pAdvertising->start();
}

void init_beacon() {
  BLEAdvertising* pAdvertising;
  pAdvertising = pServer->getAdvertising();
  pAdvertising->stop();
  // iBeacon
  BLEBeacon myBeacon;
  myBeacon.setManufacturerId(0x4c00);
  myBeacon.setMajor(5);
  myBeacon.setMinor(88);
  myBeacon.setSignalPower(0xc5);
  myBeacon.setProximityUUID(BLEUUID(BEACON_UUID_REV));

  BLEAdvertisementData advertisementData;
  advertisementData.setFlags(0x1A);
  advertisementData.setManufacturerData(myBeacon.getData());
  pAdvertising->setAdvertisementData(advertisementData);

  pAdvertising->start();
}

void setup() {
  Serial.begin(115200);
  Serial.println();
  Serial.println("Initializing...");
  Serial.flush();

  BLEDevice::init(DEVICE_NAME);
  pServer = BLEDevice::createServer();
  pServer->setCallbacks(new MyServerCallbacks());

  init_service();
  init_beacon();

  Serial.println("iBeacon + service defined and advertising!");
}

void loop() {
  if (deviceConnected) {
    Serial.printf("*** NOTIFY: %d ***\n", value);
    pCharacteristic->setValue(&value, 1);
    pCharacteristic->notify();
    value++;
  }
  delay(2000);
}

The screen shot showing the esp32 above as a bluetooth device and missing the iBeacon properties:

screen shot of the nRF Connect app, showing the esp32 above as a bluetooth device and missing the iBeacon characteristics

2 Answers 2

3

I found the solution. Apparently the proximity uuid is emitted in reversed order. The solution is to set your uuid as follows:

BLEUUID bleUUID = BLEUUID(SERVICE_UUID) ;
bleUUID = bleUUID.to128();
myBeacon.setProximityUUID(BLEUUID( bleUUID.getNative()->uuid.uuid128, 16, true ));

Credits to this GitHub issue: https://github.com/nkolban/esp32-snippets/issues/385

Sign up to request clarification or add additional context in comments.

Comments

0

A few tips:

  • The NRF Connect app for iOS does not detect iBeacon due to operating system restrictions. The Android version of the app can detect iBeacon. If you have an Android device, use that to test detections. If not, try the Locate Beacon app and pre-configure it with your UUID so it can detect that beacon.

  • If you still have trouble, try making the ESP32 advertise AltBeacon which is a manufacturer advertisement similar to iBeacon, but uses the first two bytes be ac instead of 02 15. By transmitting AltBeacon instead of iBeacon you will avoid special filtering on iOS receivers. Once you get that working, you can switch back to iBeacon.

1 Comment

I actually try to receive the signal with my own app, but I'm unsuccessful when doing so with the ESP32. Other emitters work fine. The screenshot was included for visualization, but indeed maybe was better to be left out. I'll try your second suggestion tomorrow! Thanks

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.