Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-S3 |
---|
Bluedroid Connection Example
Overview
This example is extended from Bluedroid Beacon Example, and further introduces
- How to advertise as a connectable peripheral device
- How to capture GAP events and handle them
- How to update connection parameters
It uses ESP32's Bluetooth controller and Bluedroid host stack.
To test this demo, any BLE scanner application can be used.
Try It Yourself
Set Target
Before project configuration and build, be sure to set the correct chip target using:
idf.py set-target <chip_name>
For example, if you're using ESP32, then input
idf.py set-target esp32
Build and Flash
Run the following command to build, flash and monitor the project.
idf.py -p <PORT> flash monitor
For example, if the corresponding serial port is /dev/ttyACM0
, then it goes
idf.py -p /dev/ttyACM0 flash monitor
(To exit the serial monitor, type Ctrl-]
.)
See the Getting Started Guide for full steps to configure and use ESP-IDF to build projects.
Code Explained
Overview
- Initialize NVS flash, Bluedroid host stack, GAP and GATT service; configure Bluedroid Host stack
- Set advertisement and scan response data, then configure advertising parameters and start advertising
- On connect event
- Print out connection descriptions
- Update connection parameters
- On connection update event
- Print out connection descriptions
- On disconnect event
- Print out connection descriptions
Entry Point
Please refer to the Bluedroid Beacon Example for details.
Start Advertising
Please refer to the Bluedroid Beacon Example for details.
On GAP & GATT Events
To keep it simple, we're interested in 1 GAP event and 3 GATT events at the moment
ESP_GATTS_REG_EVT
- GATT service registered eventESP_GATTS_CONNECT_EVT
- GATT connection eventESP_GAP_BLE_UPDATE_CONN_PARAMS_EVT
- Connection update eventESP_GATTS_DISCONNECT_EVT
- GATT disconnection event
Register GATT service
In app_main
, we register gatts_event_handler
function as the callback function for all GATT services by calling esp_ble_gatts_register_callback
. Then, we need to register a GATT server application with application ID 0 by calling esp_ble_gatts_app_register
void app_main(void)
{
...
ret = esp_ble_gap_register_callback(esp_gap_cb);
if (ret) {
ESP_LOGE(CONN_TAG, "%s gap register failed, error code = %x", __func__, ret);
return;
}
ret = esp_ble_gatts_register_callback(gatts_event_handler);
if (ret) {
ESP_LOGE(CONN_TAG, "%s gatts register failed, error code = %x", __func__, ret);
return;
}
...
}
Connect Event
When the device is connected to a peer device, a connect event will be passed to gatts_event_handler
by Bluedroid host stack. Once connection has been established, we will call esp_ble_gap_update_conn_params
to update connection parameters.
static void gatts_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param)
{
...
case ESP_GATTS_CONNECT_EVT:
esp_ble_conn_update_params_t conn_params = {0};
memcpy(conn_params.bda, param->connect.remote_bda, sizeof(esp_bd_addr_t));
conn_params.latency = 0;
conn_params.max_int = 0x20;
conn_params.min_int = 0x10;
conn_params.timeout = 400;
ESP_LOGI(CONN_TAG, "Connected, conn_id %u, remote "ESP_BD_ADDR_STR"",
param->connect.conn_id, ESP_BD_ADDR_HEX(param->connect.remote_bda));
esp_ble_gap_update_conn_params(&conn_params);
break;
...
}
Connection Update Event
When connection parameters are updated, an ESP_GAP_BLE_UPDATE_CONN_PARAMS_EVT
will be passed to esp_gap_cb
by Bluedroid host stack.
static void esp_gap_cb(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param)
{
...
case ESP_GAP_BLE_UPDATE_CONN_PARAMS_EVT:
ESP_LOGI(CONN_TAG, "Connection params update, status %d, conn_int %d, latency %d, timeout %d",
param->update_conn_params.status,
param->update_conn_params.conn_int,
param->update_conn_params.latency,
param->update_conn_params.timeout);
break;
...
}
Disconnect Event
On ESP_GATTS_DISCONNECT_EVT
, we simply
- Print out disconnect reason and connection descriptor
- Re-start advertising
static void gatts_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param)
{
...
case ESP_GATTS_DISCONNECT_EVT:
ESP_LOGI(CONN_TAG, "Disconnected, remote "ESP_BD_ADDR_STR", reason 0x%02x",
ESP_BD_ADDR_HEX(param->disconnect.remote_bda), param->disconnect.reason);
esp_ble_gap_start_advertising(&adv_params);
break;
...
}
Observation
If everything goes well, except for what we have seen in Bluedroid Beacon example, you should be able to connect to and disconnect from the device successfully.
Troubleshooting
For any technical queries, please file an issue on GitHub. We will get back to you soon.