I'm trying to make my ESP32 discoverable via BLE on my phone. I tested it with the attached code, and it works well on my Galaxy S23 Ultra, I can see the device without any issues.
However, on some phones (e.g., iPhones), the device doesn't appear in the scan results. My goal is to have it function as a general BLE device without a specific profile (e.g., not HID). Ultimately, I want it to trigger a gate when I'm nearby.
Has anyone encountered this issue before? Any suggestions on making it universally discoverable?
Thanks in advance for your help!
Code: Select all
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_log.h"
#include "nvs_flash.h"
#include "esp_bt.h"
#include "esp_gap_ble_api.h"
#include "esp_gatts_api.h"
#include "esp_bt_main.h"
#define TAG "BLE"
// Callback for BLE events
static void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param) {
switch (event) {
case ESP_GAP_BLE_ADV_START_COMPLETE_EVT:
if (param->adv_start_cmpl.status == ESP_BT_STATUS_SUCCESS) {
ESP_LOGI(TAG, "BLE advertising started");
} else {
ESP_LOGE(TAG, "BLE advertising failed");
}
break;
case ESP_GAP_BLE_ADV_STOP_COMPLETE_EVT:
ESP_LOGI(TAG, "BLE advertising stopped");
break;
default:
break;
}
}
// Callback for GATT server events
static void gatts_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param) {
switch (event) {
case ESP_GATTS_CONNECT_EVT:
ESP_LOGI(TAG, "Device connected");
break;
case ESP_GATTS_DISCONNECT_EVT:
ESP_LOGI(TAG, "Device disconnected");
esp_ble_gap_start_advertising(NULL); // Restart advertising
break;
default:
break;
}
}
extern "C" void app_main() {
// Initialize NVS
esp_err_t ret = nvs_flash_init();
if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
ESP_ERROR_CHECK(nvs_flash_erase());
ret = nvs_flash_init();
}
ESP_ERROR_CHECK(ret);
// Initialize BLE
ESP_ERROR_CHECK(esp_bt_controller_mem_release(ESP_BT_MODE_CLASSIC_BT));
esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK(esp_bt_controller_init(&bt_cfg));
ESP_ERROR_CHECK(esp_bt_controller_enable(ESP_BT_MODE_BLE));
ESP_ERROR_CHECK(esp_bluedroid_init());
ESP_ERROR_CHECK(esp_bluedroid_enable());
// Register GAP and GATT events
ESP_ERROR_CHECK(esp_ble_gap_register_callback(gap_event_handler));
ESP_ERROR_CHECK(esp_ble_gatts_register_callback(gatts_event_handler));
// Set advertising data
esp_ble_adv_data_t adv_data = {
.set_scan_rsp = false,
.include_name = true,
.include_txpower = false,
.min_interval = 0x20,
.max_interval = 0x40,
.appearance = 0x00,
.manufacturer_len = 0,
.p_manufacturer_data = NULL,
.service_data_len = 0,
.p_service_data = NULL,
.service_uuid_len = 0,
.p_service_uuid = NULL,
.flag = ESP_BLE_ADV_FLAG_GEN_DISC | ESP_BLE_ADV_FLAG_BREDR_NOT_SPT,
};
ESP_ERROR_CHECK(esp_ble_gap_config_adv_data(&adv_data));
// Start advertising
esp_ble_adv_params_t adv_params = {
.adv_int_min = 0x20,
.adv_int_max = 0x40,
.adv_type = ADV_TYPE_IND,
.own_addr_type = BLE_ADDR_TYPE_PUBLIC,
.channel_map = ADV_CHNL_ALL,
.adv_filter_policy = ADV_FILTER_ALLOW_SCAN_ANY_CON_ANY,
};
ESP_ERROR_CHECK(esp_ble_gap_start_advertising(&adv_params));
ESP_LOGI(TAG, "BLE initialized and advertising");
}