ESP32 Arduino WiFi + Eddystone beacon

ayandas4
Posts: 6
Joined: Wed Mar 20, 2019 5:11 am

ESP32 Arduino WiFi + Eddystone beacon

Postby ayandas4 » Thu Mar 21, 2019 5:36 am

I'm designing a device with with Wi-Fi, EEPROM, GPIO functions, and also trying to make the device advertise an Eddystone URL. After I added BLEDevice, I faced Sketch too big issue. To solve that issue, I changed the default partition to increase the program memory area. I also tried selecting partition scheme "No Ota (Large APP)", the sketch size issue got solved. But the advertise data is not correct, the device advertises something else.

Attached the screenshot of the raw data captured using nRF Connect APP.


Here is the BLE (Eddystone) Initialization code:

Code: Select all

BLEAdvertising *pAdvertising;
String product_url = "bit.ly/Brizo64a";

/*****************************************************************************
Initialize Bluetooth Low energy for Eddystone
*****************************************************************************/
void BLE_Init() {
  char beacon_data[36];
  uint16_t beaconUUID = 0xFFAA;   // UUID for Eddystone Service
  int url_length;
  int count;
  
  // Create BLE device
  BLEDevice::init("UniShelf");

  // Create BLE Server
  BLEServer *pServer = BLEDevice::createServer();
  
  pAdvertising = pServer->getAdvertising();

  //setBeacon();
  BLEAdvertisementData oAdvertisementData = BLEAdvertisementData();
  oAdvertisementData.setFlags(0x06);    // GENERAL_DISK_MODE 0x02 | BR_EDR_NOT_SUPPORTED 0x04
  oAdvertisementData.setCompleteServices(BLEUUID(beaconUUID));

  //beacon_data[0] = 0x20;    // Eddystone Frame Type (Unencrypted Eddystone - TLM)
  beacon_data[0] = 0x02;      // Length
  beacon_data[1] = 0x01;      // 
  beacon_data[2] = 0x06;      // 
  beacon_data[3] = 0x03;      // Length
  beacon_data[4] = 0x03;      // Flag - Complete list of 16-bit Service UUIDs data type value
  beacon_data[5] = 0xAA;      // 16bit Eddystone UUID
  beacon_data[6] = 0xFE;      // ...

  url_length = product_url.length();
  beacon_data[7] = url_length+6;      // Length
  beacon_data[8] = 0x16;      // Frame Type - Service Data
  beacon_data[9] = 0xAA;      // Eddystone
  beacon_data[10] = 0xFE;      // 
  beacon_data[11] = 0x10;      // Frame Type - URL
  beacon_data[12] = 0x00;      // Tx power 4dBm?
  beacon_data[13] = 0x03;      // URL Scheme Prefix - https://
  for(count=0; count<url_length; count++) {
    beacon_data[14+count] = product_url.charAt(count);
  }
  beacon_data[14+count] = 0xFF;

#ifdef DEBUG
  Serial.print("Beacon Data: ");
  for(count=0; count<url_length+15; count++) {
    if(beacon_data[count] < 16){
      Serial.print('0');
    }
    Serial.print(beacon_data[count], HEX);
    Serial.print(' ');
  }
  Serial.println();
#endif

  oAdvertisementData.setServiceData(BLEUUID(beaconUUID), std::string(beacon_data, url_length+15));
#ifdef DEBUG
  Serial.println("Service Data set!");
#endif

  pAdvertising->setScanResponseData(oAdvertisementData);
#ifdef DEBUG
  Serial.println("Scan response set!");
#endif
  // Start advertising
  pAdvertising->start();
#ifdef DEBUG
  Serial.println("Advertising started...");
#endif

  delay(5000);
}
The debug log seems to be saying that the advertisement data set is completed.
Debug log:

Code: Select all

[D][BLEDevice.cpp:82] createServer(): >> createServer
[D][BLEServer.cpp:290] registerApp(): >> registerApp - 0
[D][FreeRTOS.cpp:165] take(): Semaphore taking: name: RegisterAppEvt (0x3ffe461c), owner: <N/A> for registerApp
[D][FreeRTOS.cpp:174] take(): Semaphore taken:  name: RegisterAppEvt (0x3ffe461c), owner: registerApp
[V][FreeRTOS.cpp:70] wait(): >> wait: Semaphore waiting: name: RegisterAppEvt (0x3ffe461c), owner: registerApp for registerApp
[D][BLEDevice.cpp:108] gattServerEventHandler(): gattServerEventHandler [esp_gatt_if: 4] ... ESP_GATTS_REG_EVT
[V][BLEUtils.cpp:1519] dumpGattServerEvent(): GATT ServerEvent: ESP_GATTS_REG_EVT
[V][BLEUtils.cpp:1709] dumpGattServerEvent(): dumpGattServerEvent: *** NOT CODED ***
[D][BLEServer.cpp:153] handleGATTServerEvent(): >> handleGATTServerEvent: ESP_GATTS_REG_EVT
[V][FreeRTOS.cpp:120] give(): Semaphore giving: name: RegisterAppEvt (0x3ffe461c), owner: registerApp
[D][BLEServer.cpp:280] handleGATTServerEvent(): << handleGATTServerEvent
[V][FreeRTOS.cpp:86] wait(): << wait: Semaphore released: name: RegisterAppEvt (0x3ffe461c), owner: registerApp
[D][BLEServer.cpp:294] registerApp(): << registerApp
[D][BLEDevice.cpp:89] createServer(): << createServer
[I][BLEDevice.cpp:561] getAdvertising(): create advertising
[D][BLEDevice.cpp:563] getAdvertising(): get advertising
02 01 06 03 03 AA FE 15 16 AA FE 10 00 03 62 69 74 2E 6C 79 2F 42 72 69 7A 6F 36 34 61 FF 
Service Data set!
[D][BLEAdvertising.cpp:169] setScanResponseData(): >> setScanResponseData
[D][BLEAdvertising.cpp:177] setScanResponseData(): << setScanResponseData
[V][BLEUtils.cpp:1038] dumpGapEvent(): Received a GAP event: ESP_GAP_BLE_SCAN_RSP_DATA_RAW_SET_COMPLETE_EVT
[V][BLEUtils.cpp:1253] dumpGapEvent(): *** dumpGapEvent: Logger not coded ***
[D][BLEAdvertising.cpp:186] start(): >> start: customAdvData: 0, customScanResponseData: 1
[D][BLEAdvertising.cpp:205] start(): - no services adverti[D][BLEAdvertising.cpp:205] start(): - no services advertised
[D][BLEAdvertising.cpp:479] handleGAPEvent(): handleGAPEvent [event no: 5]
[D][BLEAdvertising.cpp:246] start(): << start
[V][BLEUtils.cpp:1038] dumpGapEvent(): Received a GAP event: ESP_GAP_BLE_ADV_DATA_SET_COMPLETE_EVT
[V][BLEUtils.cpp:1253] dumpGapEvent(): *** dumpGapEvent: Logger not coded ***
[D][BLEDevice.cpp:563] getAdvertising(): get advertising
[D][BLEAdvertising.cpp:479] handleGAPEvent(): handleGAPEvent [event no: 0]
[V][BLEUtils.cpp:1038] dumpGapEvent(): Received a GAP event: ESP_GAP_BLE_ADV_START_COMPLETE_EVT
[V][BLEUtils.cpp:1253] dumpGapEvent(): *** dumpGapEvent: Logger not coded ***
[D][BLEDevice.cpp:563] getAdvertising(): get advertising
[D][BLEAdvertising.cpp:479] handleGAPEvent(): handleGAPEvent [event no: 6]
Attachments
Screenshot_20190321-104637.png
Screenshot_20190321-104637.png (209.4 KiB) Viewed 10932 times

ayandas4
Posts: 6
Joined: Wed Mar 20, 2019 5:11 am

Re: ESP32 Arduino WiFi + Eddystone beacon

Postby ayandas4 » Fri Mar 22, 2019 5:41 am

Now I wrote a code with only BLE, in default partition.. and nothing else. It still doesn't advertise the parameters I'm giving.

Code: Select all

#include "BLEDevice.h"
#include "BLEUtils.h"
#include "BLEServer.h"
//#include "esp_sleep.h"


/******************** BLE ************************************/
BLEAdvertising *pAdvertising;
String product_url = "bit.ly/Brizo64a";


/*****************************************************************************
Initialize Bluetooth Low energy for Eddystone
*****************************************************************************/
void setup() {
  char beacon_data[36];
  uint16_t beaconUUID = 0xFFAA;   // UUID for Eddystone Service
  int url_length;
  int count;
  
  // Create BLE device
  BLEDevice::init("UniShelf");

  // Create BLE Server
  BLEServer *pServer = BLEDevice::createServer();
  
  pAdvertising = pServer->getAdvertising();

  //setBeacon();
  BLEAdvertisementData oAdvertisementData = BLEAdvertisementData();
  oAdvertisementData.setFlags(0x06);    // GENERAL_DISK_MODE 0x02 | BR_EDR_NOT_SUPPORTED 0x04
  oAdvertisementData.setCompleteServices(BLEUUID(beaconUUID));

  //beacon_data[0] = 0x20;    // Eddystone Frame Type (Unencrypted Eddystone - TLM)
  beacon_data[0] = 0x02;      // Length
  beacon_data[1] = 0x01;      // 
  beacon_data[2] = 0x06;      // 
  beacon_data[3] = 0x03;      // Length
  beacon_data[4] = 0x03;      // Flag - Complete list of 16-bit Service UUIDs data type value
  beacon_data[5] = 0xAA;      // 16bit Eddystone UUID
  beacon_data[6] = 0xFE;      // ...

  url_length = product_url.length();
  beacon_data[7] = url_length+6;      // Length
  beacon_data[8] = 0x16;      // Frame Type - Service Data
  beacon_data[9] = 0xAA;      // Eddystone
  beacon_data[10] = 0xFE;      // 
  beacon_data[11] = 0x10;      // Frame Type - URL
  beacon_data[12] = 0x00;      // Tx power 4dBm?
  beacon_data[13] = 0x03;      // URL Scheme Prefix - https://
  for(count=0; count<url_length; count++) {
    beacon_data[14+count] = product_url.charAt(count);
  }
  //beacon_data[14+count] = 0xFF;

#ifdef DEBUG
  Serial.print("Beacon Data: ");
  for(count=0; count<url_length+15; count++) {
    if(beacon_data[count] < 16){
      Serial.print('0');
    }
    Serial.print(beacon_data[count], HEX);
    Serial.print(' ');
  }
  Serial.println();
#endif

  oAdvertisementData.setServiceData(BLEUUID(beaconUUID), std::string(beacon_data, url_length+14));
#ifdef DEBUG
  Serial.println("Service Data set!");
#endif

  pAdvertising->setScanResponseData(oAdvertisementData);
#ifdef DEBUG
  Serial.println("Scan response set!");
#endif
  // Start advertising
  pAdvertising->start();
#ifdef DEBUG
  Serial.println("Advertising started...");
#endif

  delay(5000);
}


/*****************************************************************************
the loop function runs over and over again forever
*****************************************************************************/
void loop() {

}

chegewara
Posts: 2375
Joined: Wed Jun 14, 2017 9:00 pm

Re: ESP32 Arduino WiFi + Eddystone beacon

Postby chegewara » Fri Mar 22, 2019 1:45 pm

Hi,
i checked your code and its data length exceeds advertising data length (31 bytes). Your advertising data length is 40 bytes.

ayandas4
Posts: 6
Joined: Wed Mar 20, 2019 5:11 am

Re: ESP32 Arduino WiFi + Eddystone beacon

Postby ayandas4 » Sun Mar 24, 2019 1:12 pm

Thanks for your response.

My understanding may be wrong... but "bit.ly/Brizo64a" is 15 bytes, and beacon_data[] is loaded with 15 bytes prior to it, that comes to total 30 bytes. Am I missing something?

Regards
Ayan

ayandas4
Posts: 6
Joined: Wed Mar 20, 2019 5:11 am

Re: ESP32 Arduino WiFi + Eddystone beacon

Postby ayandas4 » Mon Mar 25, 2019 5:59 am

The problem is solved. It was mostly misunderstanding of the beacon advertisement data setting. I was doing repeated settings through the API as well as the raw data. here is the working code:

Code: Select all

#include "BLEDevice.h"
#include "BLEUtils.h"
#include "BLEServer.h"
//#include "esp_sleep.h"


/******************** BLE ************************************/
BLEAdvertising *pAdvertising;
String product_url = "bit.ly/Brizo64a";

#define DEBUG
/*****************************************************************************
Initialize Bluetooth Low energy for Eddystone
*****************************************************************************/
void setBeacon() {
  char beacon_data[36];
  uint16_t beaconUUID = 0xFEAA;   // UUID for Eddystone Service
  int url_length;
  int count;

  
  BLEAdvertisementData oAdvertisementData = BLEAdvertisementData();
  oAdvertisementData.setFlags(0x06);    // GENERAL_DISK_MODE 0x02 | BR_EDR_NOT_SUPPORTED 0x04
  oAdvertisementData.setCompleteServices(BLEUUID(beaconUUID));

  url_length = product_url.length();

  beacon_data[0] = 0x10;      // Frame Type - URL
  beacon_data[1] = 0x00;      // Tx power 4dBm?
  beacon_data[2] = 0x03;      // URL Scheme Prefix - https://
  for(count=0; count<url_length; count++) {
    beacon_data[3+count] = product_url.charAt(count);
  }
  //beacon_data[14+count] = 0xFF;

#ifdef DEBUG
  Serial.print("Beacon Data: ");
  for(count=0; count<url_length+3; count++) {
    if(beacon_data[count] < 16){
      Serial.print('0');
    }
    Serial.print(beacon_data[count], HEX);
    Serial.print(' ');
  }
  Serial.println();
#endif

  oAdvertisementData.setServiceData(BLEUUID(beaconUUID), std::string(beacon_data, url_length+3));
#ifdef DEBUG
  Serial.println("Service Data set!");
#endif

  pAdvertising->setScanResponseData(oAdvertisementData);
#ifdef DEBUG
  Serial.println("Scan response set!");
#endif  
}

/*****************************************************************************
Initialize Bluetooth Low energy for Eddystone
*****************************************************************************/
void setup() {
  
  // Create BLE device
  BLEDevice::init("UniShelf");

  // Create BLE Server
  BLEServer *pServer = BLEDevice::createServer();
  
  pAdvertising = pServer->getAdvertising();

  setBeacon();

  // Start advertising
  pAdvertising->start();
#ifdef DEBUG
  Serial.println("Advertising started...");
#endif

  delay(5000);
}


/*****************************************************************************
the loop function runs over and over again forever
*****************************************************************************/
void loop() {

}

Who is online

Users browsing this forum: egionet and 110 guests