Comprehensive Workflow of BLE Devices: Core Steps and Code Examples from Initialization to Data Interaction

Comprehensive Workflow of BLE Devices: Core Steps and Code Examples from Initialization to Data Interaction

Below is a detailed explanation of the workflow of BLE devices, covering the complete process from device startup to data communication, incorporating the core steps of the GAP (Generic Access Profile) and GATT (Generic Attribute Profile) protocols.

1. Device Startup and Initialization

Step 1: Hardware Initialization

Hardware Preparation:

Power on the BLE chip (e.g., nRF52, ESP32) and initialize the RF module.

Software Initialization:

Start the Bluetooth protocol stack and configure the Bluetooth address (BD_ADDR).

Define the device role: Peripheral (broadcasting data) or Central (actively connecting).

Example Code (nRF Connect SDK):

C #include void main(void) { int err = bt_enable(NULL); if (err) { printk(“Bluetooth init failed: %d\n”, err); return; } printk(“Bluetooth initialized\n”); }

2. Advertising & Scanning

Step 2: Peripheral Device Advertising

Advertising Mode:

The Peripheral device periodically sends advertising packets containing device information (e.g., name, UUID).

Advertising Types:

Connectable Advertising: Allows Central devices to connect.

Non-connectable Advertising: Only sends information (e.g., Beacon advertising).

Key Parameters:

Advertising Interval: The interval at which advertising packets are sent (default 100ms to 1 second).

Advertising Data Content:

Service UUID: Identifies the functions supported by the device (e.g., 0x180F Battery Service).

Device Name: e.g., “Smart Sensor”.

Example Code (Start Advertising):

C static struct bt_data ad[] = { BT_DATA_BYTES(BT_DATA_FLAGS, BT_LE_AD_FLAG_BREDR_NOT_SUPPORTED), BT_DATA(BT_DATA_NAME_COMPLETE, “Sensor”, 7), BT_DATA_UUID16_LIST(BT_UUID_HEART_RATE_SERVICE), }; void start_advertising(void) { bt_le_adv_start(BT_LE_ADV_NCONN_NAME, ad, ARRAY_SIZE(ad), NULL, 0); }

Step 3: Central Device Scanning

Scanning Mode:

The Central device starts scanning and listens for nearby advertising packets.

Can filter specific UUIDs or device names.

Processing Scan Results:

Upon receiving an advertising packet, parse the advertising data and record device information.

Example Code (Start Scanning):

C static void scan_cb(const struct bt_le_scan_resp *resp, int err) { if (err) { printk(“Scan failed: %d\n”, err); return; } // Process scanned devices } void start_scanning(void) { bt_le_scan_start(BT_LE_SCAN_PASSIVE, scan_cb); }

3. Connection Setup

Step 4: Central Initiates Connection

Connection Request:

The Central selects a Peripheral device and sends a connection request.

Parameter Negotiation:

Both parties negotiate connection parameters:

Connection Interval: The interval for data transmission (default 7.5ms to 4 seconds).

Slave Latency: The number of times the Peripheral is allowed to delay responses (to reduce power consumption).

Supervision Timeout: The wait time before connection loss (usually over 10 seconds).

Example Code (Establish Connection):

C void connect_to_device(const bt_addr_le_t *addr) { bt_conn_le_create(addr, BT_CONN_LE_CREATE_CONN, NULL, conn_cb); }

4. Service Discovery and Data Interaction (GATT Interaction)

Step 5: Service Discovery

Service Discovery Process:

a.The main device (Client) sends a Discover Primary Services request to obtain all services.

b.The slave device (Server) returns the list of services (e.g., heart rate service).

c.The main device discovers characteristics for the target service.

Key Protocols:

GATT: Defines the structure of services and characteristics.

ATT: Transmits data within GATT services.

Example Code (Discover Services):

C static void discover_primary_cb(struct bt_gatt_dm *dm, void *user_data) { // Process discovered services } void discover_services(struct bt_conn *conn) { bt_gatt_dm_primary(conn, discover_primary_cb, NULL); }

Step 6: Data Read/Write and Notifications

Data Read/Write:

Read characteristic values: The main device reads characteristic values from the slave device (e.g., temperature value).

Write characteristic values: The main device configures parameters for the slave device (e.g., setting sensor thresholds).

Notifications and Indications:

Notification: The slave device actively pushes data to the main device (e.g., heart rate changes).

Indication: Similar to notification, but requires confirmation from the main device.

Example Code (Enable Notifications):

C void enable_notifications(struct bt_conn *conn, struct bt_gatt_subscribe_params *params) { bt_gatt_subscribe(conn, params); }

5. Connection Maintenance and Disconnection

Step 7: Connection Maintenance

Parameter Updates:

Dynamically adjust connection parameters to suit scenarios (e.g., low power or high-speed transmission).

Example:

C struct bt_le_conn_param params = { .interval_min = 75, // 7.5ms .interval_max = 80, // 8ms .latency = 0, .timeout = 200, // 2 seconds }; bt_conn_le_param_update(conn, &params);

Step 8: Disconnect

Active Disconnection:

Either party calls the disconnection interface.

Passive Disconnection:

Disconnection due to timeout, hardware errors, or insufficient resources.

Example Code (Disconnect):

C void disconnect(struct bt_conn *conn) { bt_conn_disconnect(conn, BT_HCI_ERR_REMOTE_USER_TERM_CONN); }

6. Typical Workflow Diagram

Plain Text Peripheral Device Workflow: Initialization → Advertising → Receiving Connection → Service Registration → Data Interaction → Disconnection Central Device Workflow: Initialization → Scanning → Initiating Connection → Service Discovery → Data Interaction → Disconnection

7. Key Concepts and Terminology

Term

Description

GAP

Defines device roles (Central/Peripheral) and connection modes.

GATT

Defines the structure of services, characteristics, and descriptors for data transmission.

ATT

Transmits data within GATT services and manages the attribute database.

UUID

Uniquely identifies services and characteristics (e.g., 0x180F represents Battery Service).

Connection Interval

The time interval between two data transmissions (in ms).

Slave Latency

The number of times the slave device is allowed to delay responses (to reduce power consumption).

8. Practical Application Example

Scenario: Heart Rate Monitor (Peripheral)

(1)Peripheral (Heart Rate Sensor):

Advertising includes advertising packets with heart rate service UUID.

Defines heart rate characteristic (0x2A37), and enables notifications.

(2)Central (Mobile App):

Establishes connection after scanning the device.

Discovers heart rate service and subscribes to heart rate characteristic notifications.

Receives real-time heart rate data.

9. Common Questions and Solutions

Q1: Connection failed?

Reason:

Advertising interval too long or insufficient scanning time.

Solution:

Makefile CONFIG_BT_BLE_ADV_INTERVAL=50 # Shorten advertising interval to 50ms

Q2: High data transmission delay?

Reason:

Connection interval set too large (e.g., 1 second).

Solution:

Makefile CONFIG_BT_CONN_INTERVAL_MIN=7.5 # Set minimum connection interval to 7.5ms

Q3: Service discovery failed?

Reason:

Characteristic UUID mismatch or not properly registered.

Solution:

C // Ensure service and characteristic UUIDs are correct BT_GATT_SERVICE_DEFINE(heart_rate_svc, BT_GATT_PRIMARY_SERVICE(BT_UUID_HEART_RATE), BT_GATT_CHARACTERISTIC(BT_UUID_HEART_RATE_MEASUREMENT, BT_GATT_CHRC_NOTIFY, BT_GATT_PERM_READ, heart_rate_read, NULL, NULL));

Conclusion

The workflow of BLE devices can be summarized as:

1 . Initialization and Advertising/Scanning → 2. Connection Establishment → 3. Service Discovery and Data Interaction → 4. Maintenance and Disconnection.

By mastering the GAP, GATT, and ATT protocols, developers can design efficient, low-power BLE applications. When encountering issues, prioritize checking advertising parameters, UUID matching, and connection configurations!

Leave a Comment