ESP32 BLE Not Discoverable on Some Phones
Posted: Wed Mar 05, 2025 9:12 am
Hi everyone,
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!
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");
}