ESP32 BLE5 Extended Scan Guide

Summary : Learn how to implement BLE 5.0 Extended Scanning on the ESP32-C3 and ESP32-S3. This guide breaks down the C++ Bluedroid code required to detect both legacy BLE 4.x and modern BLE 5 extended advertising packets, giving you complete control over your IoT data payloads.

Mastering BLE 5.0 Extended Scanning on ESP32-C3 & S3

The jump from Bluetooth Low Energy (BLE) 4.2 to 5.0 introduced a game-changing feature: Extended Advertising. While legacy BLE 4.x advertising restricts payloads to a mere 31 bytes on three primary channels, BLE 5.0 offloads larger payloads onto secondary data channels, vastly increasing the amount of data you can broadcast without establishing a full connection.

If you are building projects with the ESP32-C3 or ESP32-S3, you have built-in hardware support for these BLE 5.0 features. Let’s break down a simple Arduino IDE C++ example (authored by chegewara) that sets up a scanner capable of reading both legacy and extended packets.

1. Prerequisites and Safety Checks

Before the main logic begins, the code includes crucial compiler checks:

C++

#ifndef CONFIG_BLUEDROID_ENABLED
#error "NimBLE does not support extended scan yet. Try using Bluedroid."
#elif !defined(SOC_BLE_50_SUPPORTED)
#error "This SoC does not support BLE5. Try using ESP32-C3, or ESP32-S3"
#else
// ... include libraries
  • Bluedroid Stack: Currently, the NimBLE stack does not fully support extended scanning in this context. You must ensure your environment is configured to use the default ESP-IDF Bluedroid stack.
  • Hardware Compatibility: Standard ESP32 boards (like the original ESP32-WROOM-32) only support BLE 4.2. This code forces a compilation error if you aren’t compiling for a BLE 5-capable chip like the C3 or S3.

2. The Callback Mechanism: Handling the Data

In the legacy API, the BLE stack automatically stored discovered devices in a list for you. With the new Extended Scan API, data management is now the user’s responsibility. You handle incoming data via a custom callback class:

C++

class MyBLEExtAdvertisingCallbacks : public BLEExtAdvertisingCallbacks {
  void onResult(esp_ble_gap_ext_adv_report_t report) {
    if (report.event_type & ESP_BLE_GAP_SET_EXT_ADV_PROP_LEGACY) {
      // Regular advertising data from BLE 4.x devices
      Serial.println("BLE4.2");
    } else {
      // Extended advertising data over data channel by BLE 5 devices
      Serial.printf("Ext advertise: data_le: %d, data_status: %d \n", report.adv_data_len, report.data_status);
    }
  }
};
  • ESP_BLE_GAP_SET_EXT_ADV_PROP_LEGACY: This flag checks if the incoming packet is a standard, 31-byte legacy advertisement. This ensures backwards compatibility with older devices.
  • report.adv_data_len: If it’s not a legacy packet, it’s an extended one. Here, you can extract the length of the extended payload and its status directly from the report.

3. Initializing and Starting the Scan

Finally, the setup() function puts the pieces together:

C++

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

  BLEDevice::init("");
  pBLEScan = BLEDevice::getScan(); 
  
  // 1. Assign the custom callback
  pBLEScan->setExtendedScanCallback(new MyBLEExtAdvertisingCallbacks());
  
  // 2. Load scan parameters
  pBLEScan->setExtScanParams(); 
  delay(1000); 
  
  // 3. Start scanning (Duration: 1000ms, Period: 3 seconds)
  pBLEScan->startExtScan(scanTime, 3); 
}
  • setExtScanParams(): This applies the default extended scanning parameters. The API allows for overloaded functions here if you need to tweak specific PHYs (like 1M, 2M, or Coded PHY for long-range).
  • startExtScan(scanTime, 3): The first parameter is the duration of the scan (in units of 10ms, so 100 = 1000ms). The second parameter is the period (in seconds) indicating when the scan should repeat.

By running this code on your C3 or S3, you’ll immediately see a serial monitor stream separating the older, noisy BLE 4.x devices from the modern, data-rich BLE 5.0 extended broadcasters.

Share your love

Leave a Reply

Your email address will not be published. Required fields are marked *