Chapter 56: Bluetooth LE Architecture Overview
Chapter Objectives
By the end of this chapter, you will be able to:
- Understand the fundamental principles and use cases of Bluetooth Low Energy (BLE).
- Differentiate BLE from Bluetooth Classic.
- Describe the roles of Central and Peripheral devices in BLE communication.
- Explain the BLE protocol stack and the function of its key layers (PHY, LL, HCI, L2CAP, ATT, SMP, GATT, GAP).
- Understand the concepts of advertising, scanning, and connections.
- Define Services, Characteristics, and Descriptors within the GATT framework.
- Identify key ESP-IDF components and header files related to BLE development.
- Recognize BLE capabilities across different ESP32 variants.
Introduction
Welcome to the world of Bluetooth Low Energy (BLE)! In previous chapters, we explored WiFi for robust, high-throughput wireless communication. Now, we shift our focus to BLE, a wireless technology designed specifically for short-range, low-power applications. This makes it an ideal choice for battery-operated devices, wearables, sensors, and a vast array of Internet of Things (IoT) devices where power efficiency is paramount.
Unlike Bluetooth Classic, which is optimized for streaming applications like audio, BLE excels at transmitting small amounts of data periodically. Imagine a heart rate monitor sending updates to a smartphone, a smart beacon broadcasting its presence, or a wireless sensor reporting temperature readings – these are all classic BLE use cases.
Understanding the architecture of BLE is crucial for developing effective and efficient applications. This chapter will provide a comprehensive overview of the BLE protocol stack, its operational modes, and the fundamental concepts that govern how BLE devices discover each other, connect, and exchange data. With this foundation, you’ll be well-prepared for subsequent chapters that delve into practical BLE implementation on ESP32 microcontrollers using the ESP-IDF.
Theory
Bluetooth Low Energy, as the name suggests, was designed from the ground up for minimal power consumption. It achieves this through several mechanisms:
- Short Data Packets: BLE transmits small packets of data, reducing on-air time.
- Quick Connections: Devices can connect and disconnect rapidly.
- Extended Sleep Periods: Devices spend most of their time in low-power sleep modes, waking up only briefly to communicate.
BLE vs. Bluetooth Classic
While both fall under the “Bluetooth” umbrella, BLE and Bluetooth Classic are distinct technologies serving different purposes.
Feature | Bluetooth Classic (BR/EDR) | Bluetooth Low Energy (BLE) |
---|---|---|
Primary Use Case | Audio streaming, data transfer | Low-power sensing, beacons, IoT |
Power Consumption | Moderate to High | Very Low |
Data Throughput | Higher (up to ~2-3 Mbps) | Lower (up to ~2 Mbps with 2M PHY) |
Connection Time | Longer | Shorter (< 3ms typical) |
Topology | Piconets (up to 7 slaves) | Star, Scatternet (many devices) |
Voice Support | Yes | Limited (emerging standards) |
Complexity | Higher | Lower |
Many modern devices, including most ESP32 variants, are “dual-mode,” meaning they support both Bluetooth Classic and BLE.
Core BLE Concepts
1. Roles: Central and Peripheral
BLE devices operate in specific roles:
- Peripheral (Advertiser/Slave): Typically a small, resource-constrained device like a sensor, beacon, or wearable.
- It advertises its presence, making itself discoverable.
- It can accept connections from a Central device.
- Once connected, it acts as a GATT Server, providing data (attributes) to the Central.
- Example: A fitness tracker advertising its heart rate service.
- Central (Scanner/Initiator/Master): Typically a more powerful device like a smartphone, tablet, or computer (or another ESP32).
- It scans for nearby advertising Peripherals.
- It can initiate a connection to a Peripheral.
- Once connected, it acts as a GATT Client, requesting and consuming data from the Peripheral’s GATT Server.
- Example: A smartphone scanning for and connecting to the fitness tracker to read heart rate data.
A device can sometimes act as both (e.g., an ESP32 acting as a Central to read sensor data and as a Peripheral to be configured by a phone).
2. Advertising and Scanning
This is the primary mechanism for device discovery:
- Advertising: Peripherals periodically broadcast “advertising packets.” These packets can contain a small amount of data, such as the device name, services it offers, or manufacturer-specific data.
- Scanning: Centrals listen for these advertising packets. They can passively listen or actively request more information (Scan Response) from advertisers.
3. Connections
Once a Central discovers a Peripheral, it can initiate a connection. Key connection parameters include:
- Connection Interval: The time between two consecutive connection events. A shorter interval means lower latency but higher power consumption.
- Slave Latency: The number of connection events a Peripheral can skip if it has no new data to send, allowing it to save power.
- Supervision Timeout: The maximum time between two received valid data packets before a connection is considered lost.
4. Generic Access Profile (GAP)
GAP defines how BLE devices discover each other, establish connections, and manage security. It specifies:
- Device roles (Central, Peripheral, Broadcaster, Observer).
- Operational modes (Advertising, Scanning, Initiating, Connecting).
- Advertising data formats.
- Security procedures (pairing, bonding).
5. Generic Attribute Profile (GATT)
GATT defines how data is exchanged between connected BLE devices. It establishes a hierarchical structure for data organization:
- Profile: A collection of one or more Services that define a specific use case (e.g., Heart Rate Profile). Profiles are generally high-level specifications defined by the Bluetooth SIG or custom-defined.
- Service: A collection of related data items called Characteristics. Each Service has a unique UUID (Universally Unique Identifier).
- Example: A “Heart Rate Service” might contain characteristics for “Heart Rate Measurement” and “Body Sensor Location.”
- Characteristic: A data value with associated properties (Read, Write, Notify, Indicate) and Descriptors. Each Characteristic also has a UUID.
- Example: The “Heart Rate Measurement” characteristic holds the actual heart rate value and might have “Notify” property.
- Descriptor: Provides additional information about a Characteristic, such as a human-readable description, units, or configuration settings (e.g., enabling notifications). Descriptors also have UUIDs.
GATT communication is a client-server model:
- GATT Server (usually the Peripheral): Hosts the data (services, characteristics, descriptors) and responds to requests from the GATT Client.
- GATT Client (usually the Central): Discovers services and characteristics on the GATT Server, and reads, writes, or requests notifications/indications for characteristic values.
graph TD subgraph GATT Structure direction TB P[/"<b>Profile</b><br>(e.g., Heart Rate Profile)"/]:::primary --> S1["<b>Service</b><br>UUID: 0x180D<br>(Heart Rate Service)"]:::process P --> S2["<b>Service</b><br>UUID: 0x180A<br>(Device Information Service)"]:::process S1 --> C1_1["<b>Characteristic</b><br>UUID: 0x2A37<br>(Heart Rate Measurement)<br>Properties: NOTIFY"]:::process S1 --> C1_2["<b>Characteristic</b><br>UUID: 0x2A38<br>(Body Sensor Location)<br>Properties: READ"]:::process C1_1 --> D1_1_1["<b>Descriptor</b><br>UUID: 0x2902<br>(Client Characteristic Configuration)<br>Value: 0x0001 (Notifications Enabled)"]:::check C1_1 --> D1_1_2["<b>Descriptor</b><br>UUID: 0x2901<br>(User Description)<br>Value: 'Measures continuous heart rate'"]:::check S2 --> C2_1["<b>Characteristic</b><br>UUID: 0x2A29<br>(Manufacturer Name String)<br>Properties: READ"]:::process end classDef primary fill:#EDE9FE,stroke:#5B21B6,stroke-width:2px,color:#5B21B6 classDef process fill:#DBEAFE,stroke:#2563EB,stroke-width:1px,color:#1E40AF classDef check fill:#FEE2E2,stroke:#DC2626,stroke-width:1px,color:#991B1B classDef decision fill:#FEF3C7,stroke:#D97706,stroke-width:1px,color:#92400E classDef success fill:#D1FAE5,stroke:#059669,stroke-width:2px,color:#065F46
BLE Protocol Stack
The BLE protocol stack is a layered architecture that defines how communication occurs. It’s typically divided into two main parts: the Controller and the Host.

Controller Layers
These layers are typically implemented in hardware or low-level firmware.
- Physical Layer (PHY):
- Responsible for the actual radio transmission and reception of bits.
- Operates in the 2.4 GHz ISM (Industrial, Scientific, and Medical) band.
- Uses Gaussian Frequency Shift Keying (GFSK) modulation.
- Defines radio channels (40 channels, 2 MHz spacing: 3 advertising channels, 37 data channels).
- BLE 5.0 introduced new PHY options:
LE 1M PHY
: The original 1 Mbps PHY (mandatory).LE 2M PHY
: A 2 Mbps PHY for higher throughput (optional).LE Coded PHY
: A long-range PHY using Forward Error Correction (FEC) for increased sensitivity and range, at the cost of lower data rates (125 kbps or 500 kbps) (optional).
- Link Layer (LL):
- Manages the radio state (advertising, scanning, initiating, connected).
- Defines packet formats for advertising and data.
- Handles device filtering, addressing, connection establishment, and maintenance.
- Implements link-layer security (encryption, authentication).
- Controls critical timing aspects like connection intervals and sleep.
Host Controller Interface (HCI)
- A standardized interface that allows the Host (software stack) to communicate with the Controller (hardware/firmware).
- HCI commands, events, and data packets are exchanged between the Host and Controller.
- This abstraction allows different Host stacks to be used with different Controller implementations. On ESP32, the HCI is typically an internal software interface as both Host and Controller run on the same chip.
Host Layers
These layers are typically implemented as a software stack. On ESP32, this is part of the Bluedroid stack (or NimBLE for a more lightweight option, though Bluedroid is common with ESP-IDF).
- Logical Link Control and Adaptation Protocol (L2CAP):
- Provides protocol multiplexing, allowing multiple higher-level protocols (like ATT and SMP) to share a single logical link.
- Handles segmentation and reassembly of larger data packets if needed.
- Manages connection-oriented channels and flow control.
- Security Manager Protocol (SMP):
- Responsible for pairing, authentication, and encryption.
- Pairing: The process of establishing a trusted relationship and generating shared secret keys.
- Bonding: Storing the shared keys generated during pairing for future reconnections without repeating the full pairing process.
- Defines different pairing methods (e.g., Just Works, Passkey Entry, Numeric Comparison) depending on device capabilities.
- Attribute Protocol (ATT):
- Defines how attributes (data) are structured and accessed on a GATT server.
- Specifies request/response messages for discovering, reading, writing, and being notified/indicated of attribute values.
- It’s a simple client-server protocol operating over L2CAP.
- Generic Attribute Profile (GATT): (Already discussed in Core Concepts)
- Builds upon ATT to define a service-oriented framework for data exchange.
- Specifies how services, characteristics, and descriptors are defined and used.
- Enables operations like Service Discovery, Characteristic Discovery, Read/Write Characteristic Value, Notifications, and Indications.
- Generic Access Profile (GAP): (Already discussed in Core Concepts)
- Defines the highest-level control procedures for BLE devices.
- Manages device discovery (advertising, scanning), connection establishment, and security modes.
- Determines how devices present themselves to the outside world.
sequenceDiagram actor Peripheral as Peripheral (GATT Server) actor Central as Central (GATT Client) Peripheral->>+Peripheral: Start Advertising (ADV_IND packets with Name, Services UUIDs) activate Peripheral Note over Peripheral: Broadcasting presence Central->>+Central: Start Scanning activate Central Note over Central: Listening for advertisers Peripheral-->>Central: Advertising Packet (ADV_IND) Central->>Central: Discovers Peripheral Central->>Peripheral: Connection Request (CONNECT_REQ) deactivate Central Peripheral->>Peripheral: Accept Connection Peripheral-->>Central: Connection Established activate Central deactivate Peripheral Note over Central,Peripheral: Secure Connection (if applicable) Central->>Peripheral: GATT: Discover All Primary Services Request Peripheral-->>Central: GATT: Primary Services Response (e.g., Heart Rate Service UUID) Central->>Peripheral: GATT: Discover Characteristics for Heart Rate Service Request Peripheral-->>Central: GATT: Characteristics Response (e.g., HR Measurement UUID, Body Sensor Location UUID) Central->>Peripheral: GATT: Read Characteristic Value Request (Body Sensor Location) Peripheral-->>Central: GATT: Read Response (e.g., "Chest") Central->>Peripheral: GATT: Write Characteristic Request (Client Char. Config. Descriptor for HR Measurement - Enable Notifications) Peripheral-->>Central: GATT: Write Response (Success) Note over Peripheral: Notifications enabled for HR Measurement loop Data Exchange Peripheral-->>Central: GATT: Handle Value Notification (New Heart Rate Data) Central->>Central: Process Heart Rate Data end
UUIDs (Universally Unique Identifiers)
UUIDs are 128-bit numbers used to uniquely identify services, characteristics, and descriptors.
- Bluetooth SIG Adopted UUIDs: These are 16-bit or 32-bit short-form UUIDs assigned by the Bluetooth SIG for standard profiles and data types (e.g.,
0x180D
for Heart Rate Service,0x2A37
for Heart Rate Measurement characteristic). These are derived from a base Bluetooth UUID. - Custom UUIDs: Developers can generate their own 128-bit UUIDs for custom services and characteristics to avoid collisions.
ESP-IDF and BLE
The ESP-IDF provides a comprehensive Bluetooth stack, often referred to as Bluedroid (though NimBLE is an alternative, Bluedroid is widely used with ESP-IDF examples). Key components include:
- Bluetooth Controller: Low-level firmware implementing the PHY and LL.
- Bluetooth Host: Software stack implementing L2CAP, SMP, ATT, GATT, GAP, and other profiles.
- API Layers:
esp_bt_controller_xxx
functions for managing the controller.esp_bluedroid_xxx
functions for initializing/deinitializing the Bluedroid host stack.esp_ble_gap_xxx
functions for GAP operations (advertising, scanning, connections).esp_ble_gatts_xxx
functions for GATT Server operations (creating services, characteristics).esp_ble_gattc_xxx
functions for GATT Client operations (discovering services, reading/writing characteristics).
BLE operations in ESP-IDF are heavily event-driven. Applications register callback functions for GAP and GATT events to handle asynchronous operations like scan results, connection establishment, data reception, etc.
Practical Examples
While subsequent chapters will delve into detailed coding for GATT servers, clients, advertising, and scanning, this section focuses on understanding the BLE architecture within the ESP-IDF v5.x environment.
Example 1: Exploring BLE Menuconfig Options in ESP-IDF
ESP-IDF’s menuconfig
tool allows you to configure various aspects of your project, including Bluetooth and BLE settings.
Steps:
- Open your ESP-IDF project in VS Code or your preferred terminal.
- Ensure your ESP-IDF environment is sourced.
- Run the command:
idf.py menuconfig
- Navigate to
Component config --->
. - Navigate to
Bluetooth --->
.- Here, you can enable/disable Bluetooth (
[*] Bluetooth
). - Select the Bluetooth mode (e.g.,
Bluetooth Dual Mode (BR/EDR + LE)
orBluetooth Low Energy Only
).
- Here, you can enable/disable Bluetooth (
- If Bluetooth is enabled, navigate into
Bluetooth Low Energy --->
.- Observe Key Options:
[*] BLE Max Connections
: Sets the maximum number of concurrent BLE connections.[*] BLE multi-connection master role support
: Enables the device to act as a central to multiple peripherals.[*] BLE multi-connection slave role support
: Enables the device to act as a peripheral connected to multiple centrals.[*] Enable BLE 5.0 features
: Allows enabling features like 2M PHY, Coded PHY, and Advertising Extensions if supported by the hardware.Default BLE MTU size
: Maximum Transmission Unit for ATT.- Various options for advertising PDU counts, GATT server/client configurations, etc.
- Observe Key Options:
Understanding:
Exploring these options gives you a sense of the configurable parameters of the BLE stack. For instance, knowing the maximum number of connections your hardware and stack configuration support is crucial for designing applications that interact with multiple BLE devices. Enabling BLE 5.0 features can significantly impact range and throughput.
Tip: Always save your
menuconfig
changes and rebuild your project (idf.py build
) for them to take effect.
Example 2: Identifying Key BLE Header Files in ESP-IDF
The ESP-IDF provides a set of C header files that expose the APIs for BLE functionality. Familiarizing yourself with these is essential for development.
Key Header Files:
You will typically find these in the components/bt/host/bluedroid/api/include/api or components/bt/esp_ble_ αντιπροσωπεία/include directories within your ESP-IDF installation, though you include them directly in your code.
// Main Bluetooth controller and Bluedroid stack initialization
#include "esp_bt.h" // For esp_bt_controller_init/enable, esp_bluedroid_init/enable
#include "esp_bt_main.h" // For esp_bluedroid_get_status
// BLE Specific APIs
#include "esp_gap_ble_api.h" // For GAP operations: advertising, scanning, connection management, security.
// Defines structures like esp_ble_adv_params_t, esp_ble_scan_params_t
// and functions like esp_ble_gap_start_advertising(), esp_ble_gap_start_scanning().
#include "esp_gatts_api.h" // For GATT Server operations: creating services, characteristics, descriptors,
// handling read/write requests, sending notifications/indications.
// Defines functions like esp_ble_gatts_create_service(), esp_ble_gatts_add_char().
// Callback events like ESP_GATTS_CONNECT_EVT, ESP_GATTS_READ_EVT.
#include "esp_gattc_api.h" // For GATT Client operations: discovering services, characteristics,
// reading/writing remote attributes, registering for notifications.
// Defines functions like esp_ble_gattc_open(), esp_ble_gattc_search_service().
// Callback events like ESP_GATTC_OPEN_EVT, ESP_GATTC_SEARCH_RES_EVT.
#include "esp_gatt_defs.h" // Defines common GATT definitions, UUID types, attribute permissions, etc.
// Includes structures like esp_gatt_id_t, esp_bt_uuid_t.
Purpose:
esp_bt.h
andesp_bt_main.h
: Essential for initializing and enabling the underlying Bluetooth controller and the Bluedroid host stack. This is the first step before any BLE operations can occur.esp_gap_ble_api.h
: Your primary interface for controlling how your ESP32 interacts with the BLE world at a high level – making itself known (advertising), discovering others (scanning), and managing connections.esp_gatts_api.h
: Used when your ESP32 needs to provide data or services to other BLE devices (acting as a Peripheral/GATT Server).esp_gattc_api.h
: Used when your ESP32 needs to consume data or services from other BLE devices (acting as a Central/GATT Client).esp_gatt_defs.h
: Contains fundamental definitions used across GATT server and client operations, particularly for UUIDs and attribute properties.
Understanding the scope of these headers helps you locate the necessary functions and data structures for the specific BLE task you are implementing.
Variant Notes
The ESP32 family offers a range of SoCs with varying BLE capabilities. ESP-IDF v5.x provides a largely unified API, but hardware differences exist:
- ESP32 (Original): Supports Bluetooth v4.2 BR/EDR and BLE. Later silicon revisions (ECO3 onwards) and the ESP-IDF stack enable BLE 5.0 features like 2M PHY and LE Coded PHY (long range), and Advertising Extensions. Always check the specific ESP32 module/chip datasheet for full BLE 5.0 feature support.
- ESP32-S2: Does not have any Bluetooth hardware. Therefore, this chapter and BLE functionalities are not applicable to the ESP32-S2. Its wireless connectivity is WiFi-only.
- ESP32-S3: Supports Bluetooth v5.0 LE. This includes 2M PHY, LE Coded PHY, and Advertising Extensions, providing higher throughput and longer-range options. It does not support Bluetooth Classic (BR/EDR).
- ESP32-C3: Supports Bluetooth v5.0 LE. Similar to ESP32-S3, it includes 2M PHY, LE Coded PHY, and Advertising Extensions. It is based on a RISC-V core. It does not support Bluetooth Classic.
- ESP32-C6: Supports Bluetooth v5.3 LE and also integrates 802.15.4 (for Thread/Zigbee). It offers the latest BLE features, including potential for LE Audio features (check ESP-IDF support status) and Direction Finding. It does not support Bluetooth Classic.
- ESP32-H2: Supports Bluetooth v5.3 LE and also integrates 802.15.4 (for Thread/Zigbee). Its feature set is similar to ESP32-C6, positioning it for advanced IoT applications requiring robust BLE and mesh networking. It does not support Bluetooth Classic.
ESP32 Variant | Bluetooth Classic (BR/EDR) | Bluetooth Low Energy (BLE) | Key BLE Features |
---|---|---|---|
ESP32 (Original) | Yes (v4.2) | Yes (v4.2; BLE 5.0 features on later revisions/ECO3+) | LE 1M PHY. Later chips/IDF versions add LE 2M PHY, LE Coded PHY, Advertising Extensions. |
ESP32-S2 | No | No | N/A (WiFi only) |
ESP32-S3 | No | Yes (v5.0 LE) | LE 1M PHY, LE 2M PHY, LE Coded PHY, Advertising Extensions. |
ESP32-C3 | No | Yes (v5.0 LE) | LE 1M PHY, LE 2M PHY, LE Coded PHY, Advertising Extensions. RISC-V Core. |
ESP32-C6 | No | Yes (v5.3 LE) | Latest BLE 5.3 features, 802.15.4 (Thread/Zigbee). Potential for LE Audio, Direction Finding (check IDF support). |
ESP32-H2 | No | Yes (v5.3 LE) | Similar to ESP32-C6; BLE 5.3 features, 802.15.4 (Thread/Zigbee). Positioned for advanced IoT. |
Important: While ESP-IDF strives for API consistency, always refer to the latest ESP-IDF documentation and the specific datasheet for your chosen ESP32 variant to confirm the exact set of supported BLE features (e.g., specific BLE 5.x capabilities, maximum number of connections, concurrent advertising sets). Some features might also depend on
menuconfig
settings.
Common Mistakes & Troubleshooting Tips
Mistake / Issue | Symptom(s) | Troubleshooting / Solution |
---|---|---|
Forgetting Bluetooth Stack Initialization | Functions like esp_ble_gap_start_advertising() return errors (e.g., ESP_ERR_INVALID_STATE), or the application crashes. BLE operations fail silently. | Solution: Ensure you call esp_bt_controller_init(), then esp_bt_controller_enable(ESP_BT_MODE_BLE), followed by esp_bluedroid_init(), and finally esp_bluedroid_enable(). This sequence must be done during application startup, before any other BLE API calls. Always check the return codes of these initialization functions. |
Misunderstanding Central vs. Peripheral Roles & GATT Client/Server | Device doesn’t advertise when it should, or doesn’t scan. GATT operations fail (e.g., cannot discover services, read/write characteristics). API calls might return errors related to incorrect state or role. | Solution: Clearly define your ESP32’s role.
– If providing data/services (e.g., sensor, smart bulb): It’s a Peripheral and GATT Server. Use esp_ble_gap_start_advertising() and esp_gatts_api.h. – If discovering and consuming data (e.g., phone app, data collector ESP32): It’s a Central and GATT Client. Use esp_ble_gap_start_scanning() and esp_gattc_api.h. |
Not Registering or Incorrectly Handling GAP/GATT Event Callbacks | Application seems unresponsive to BLE events (e.g., no indication of connection, scan results not processed, read requests ignored). Asynchronous operations don’t complete or trigger subsequent logic. | Solution: BLE is event-driven. Register callback functions using esp_ble_gap_register_callback() and esp_ble_gatts_register_callback() (for server) or esp_ble_gattc_register_callback() (for client). Inside these callbacks, use a switch statement to handle specific events (e.g., ESP_GAP_BLE_ADV_START_COMPLETE_EVT, ESP_GATTS_CONNECT_EVT, ESP_GATTC_READ_CHAR_EVT). Ensure all relevant events for your application logic are handled. |
Incorrect UUID Configuration | GATT client fails to discover services/characteristics. Read/write operations target incorrect attributes or fail. Debugging tools (like nRF Connect) show unexpected UUIDs or missing services. | Solution: Double-check UUIDs:
– Use 16-bit short UUIDs for Bluetooth SIG adopted services/characteristics (e.g., 0x180F for Battery Service). – Use full 128-bit UUIDs for custom services/characteristics. Ensure byte order is correct if manually defining. – Verify the client is searching for the exact UUIDs (and types) exposed by the server. Use a BLE scanner tool to inspect the server’s GATT table. |
Insufficient MTU Size for Data | Data sent or received is truncated. Write/read operations for characteristic values larger than ~20 bytes fail or behave unexpectedly. Notifications/Indications might not send full data. | Solution: The default ATT MTU is 23 bytes (payload of 20 bytes).
– For larger data, either segment it into multiple packets/operations. – Or, negotiate a larger MTU after connection. The client can request this using esp_ble_gattc_send_mtu_req(). The server must be prepared to handle this request and respond. Both devices must support the new MTU size. Check the ESP_GATTC_CFG_MTU_EVT (client) and ESP_GATTS_MTU_EVT (server). |
Advertising Data Too Large | esp_ble_gap_start_advertising() returns an error, or advertising fails to start. Device is not discoverable by scanners. | Solution: Legacy advertising packets have a limited size (31 bytes for payload). Ensure your advertising data (device name, service UUIDs, manufacturer data) fits. Use scan response packets for additional data if needed. For BLE 5.0, consider using Extended Advertising if larger payloads are required and supported. |
Missing Permissions for Characteristics | Client attempts to read/write/notify a characteristic, but the operation fails with an “Attribute Not Permitted” or similar error. | Solution: When defining characteristics on the GATT server (esp_ble_gatts_add_char()), ensure the perm field (e.g., ESP_GATT_PERM_READ, ESP_GATT_PERM_WRITE) and property field (e.g., ESP_GATT_CHAR_PROP_BIT_READ, ESP_GATT_CHAR_PROP_BIT_WRITE, ESP_GATT_CHAR_PROP_BIT_NOTIFY) are correctly set to allow the intended operations. |
Exercises
- Research BLE Profiles:
- Identify three standard Bluetooth SIG adopted BLE profiles (e.g., Device Information Service, Battery Service, Environmental Sensing Service).
- For each profile, list its assigned 16-bit UUID.
- For one characteristic within each of these services, list its assigned 16-bit UUID and briefly describe its purpose.
- Hint: The Bluetooth SIG website (“Assigned Numbers” or “Service Discovery” sections) is a good resource.
- Diagram GATT Interaction:
- Draw a sequence diagram illustrating a Central device discovering a Peripheral’s “Battery Service” (UUID
0x180F
) and then reading its “Battery Level” characteristic (UUID0x2A19
). Include the key GAP (advertising, scanning, connecting) and GATT (service discovery, characteristic discovery, read characteristic) steps.
- Draw a sequence diagram illustrating a Central device discovering a Peripheral’s “Battery Service” (UUID
- ESP-IDF API Exploration:
- In your ESP-IDF installation, navigate to the
esp_ble_gap_api.h
header file. - Identify and list three distinct functions related to advertising (e.g., starting, stopping, setting data). Briefly describe what each function does based on its name and any comments.
- Do the same for
esp_ble_gatts_api.h
, identifying three functions related to creating or managing characteristics on a GATT server.
- In your ESP-IDF installation, navigate to the
Summary
- Bluetooth Low Energy (BLE) is optimized for low-power, short-range wireless communication, ideal for IoT devices.
- BLE operates with distinct Central (scanner, initiator, GATT client) and Peripheral (advertiser, GATT server) roles.
- GAP (Generic Access Profile) governs device discovery (advertising/scanning), connection establishment, and security.
- GATT (Generic Attribute Profile) defines how data is exchanged using a hierarchy of Services, Characteristics, and Descriptors.
- The BLE Protocol Stack includes the Controller (PHY, LL) and Host (L2CAP, SMP, ATT, GATT, GAP) layers, connected via HCI.
- BLE 5.0 introduced features like 2M PHY (higher speed) and Coded PHY (longer range).
- UUIDs uniquely identify services, characteristics, and descriptors.
- ESP-IDF provides a comprehensive BLE stack (Bluedroid) with APIs (
esp_gap_ble_api.h
,esp_gatts_api.h
,esp_gattc_api.h
) for developing BLE applications. - BLE operations in ESP-IDF are event-driven, requiring registration of callback functions.
- Different ESP32 variants have varying BLE capabilities (e.g., ESP32-S3/C3/C6/H2 support BLE 5.0/5.3 LE, while ESP32-S2 has no Bluetooth).
Further Reading
- ESP-IDF Bluetooth LE Programming Guide: https://docs.espressif.com/projects/esp-idf/en/stable/esp32/api-guides/ble/index.html
- ESP-IDF API Reference – Bluetooth: https://docs.espressif.com/projects/esp-idf/en/stable/esp32/api-reference/bluetooth/esp_bt_device.html
- Bluetooth SIG Website (bluetooth.com):
- Specifications: For in-depth understanding of BLE protocols and profiles.
- Assigned Numbers: For lists of standard UUIDs for services, characteristics, and descriptors.
- Bluedroid Stack: (General information, as it’s the underlying stack used in ESP-IDF, though direct interaction is mostly through ESP-IDF APIs).
