BLE beacon adalah perangkat yang mentransmisikan unique identifier sebagai BLE advertisement. dimana mobile application akan bereaksi ketika smartphone mendeteksi beacon.
Teknik ini berguna ketika proximity sensing diperlukan, contoh, tracking applications
atau misalnya di museums untuk menunjukan informasi lebih lanjut mengenai suatu object.
Contoh implementasi dari teknik adalah iBeacon, yang didevelop oleh Apple. BLE advertisment dari iBeacon frame mengandung tiga data fields:
- 16 bytes of UUID: Global unique identifier untuk application.
- Major (2 bytes): application-specific major identifier untuk group iBeacon devices kedalam regions.
- Minor (2 bytes): application-specific minor identifier untuk group iBeacon devices kedalam locations dalam region yang dimaksud.
iBeacon frame juga mengandung TX power value dari device, yang diukur dari jarak 1-meter saat melakukan proses calibration. Mobile application akan mengestimasi jarak ke iBeacon device dengan membandingkan value tersebut dan signal strength yang diterima dari iBeacon.
Dengan informasi diatas, kita akan develop iBeacon device.
Persiapan Project
Buat project baru, jalankan menu config melalui PlatformIO CLI.
(penv)$ pio run -t menuconfig
Buka menu Component config | Bluetooth untuk memilih Bluetooth Host, pilih Bluedroid – Dual mode.

Kemudian tambahkan pada lib folder, library untuk implementasi iBeacon. Download di: https://drive.google.com/drive/folders/1ZPJTnclHiR3Apf1dnBoM6n7xpAPcMdg6?usp=sharing
Code
Buka file src/main.c, tambahkan code berikut:
//import library
#include "nvs_flash.h"
#include "esp_bt.h"
#include "esp_gap_ble_api.h"
#include "esp_bt_main.h"
#include "esp_bt_defs.h"
#include "esp_ibeacon_api.h"
#include "esp_log.h"
#include "freertos/FreeRTOS.h"
static const char *TAG = "ibeacon";
static esp_ble_adv_params_t ble_adv_params = {
.adv_int_min = 0x20,
.adv_int_max = 0x40,
.adv_type = ADV_TYPE_NONCONN_IND,
.own_addr_type = BLE_ADDR_TYPE_PUBLIC,
.channel_map = ADV_CHNL_ALL,
.adv_filter_policy = ADV_FILTER_ALLOW_SCAN_ANY_CON_ANY,
};
//ble gap event handler
static void ble_gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param)
{
switch (event)
{
case ESP_GAP_BLE_ADV_DATA_RAW_SET_COMPLETE_EVT:
esp_ble_gap_start_advertising(&ble_adv_params);
break;
case ESP_GAP_BLE_ADV_START_COMPLETE_EVT:
if (param->adv_start_cmpl.status != ESP_BT_STATUS_SUCCESS)
{
ESP_LOGE(TAG, "advertisement failed");
}
break;
default:
break;
}
}
//init function
void init(void)
{
nvs_flash_init();
esp_bt_controller_mem_release(ESP_BT_MODE_CLASSIC_BT);
esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT();
esp_bt_controller_init(&bt_cfg);
esp_bt_controller_enable(ESP_BT_MODE_BLE);
esp_bluedroid_init();
esp_bluedroid_enable();
esp_ble_gap_register_callback(ble_gap_event_handler);
}
//main function
void app_main(void)
{
init();
esp_ble_ibeacon_t ibeacon_adv_data;
esp_init_ibeacon_data(&ibeacon_adv_data);
esp_ble_gap_config_adv_data_raw((uint8_t *)&ibeacon_adv_data, sizeof(ibeacon_adv_data));
}
Penjelasan Code
Bagian Import Libarary
Pertama, kita include header files yang dibutuhkan dan definisikan advertisement parameters dalam variable ble_adv_params yang berisi:
- Minimum dan maximum advertisement intervals. BLE stack menyediakan randomness antara nilai minimum dan maximum ini.
- Advertisement type, yaitu non-connectable, non-scannable, undirected advertising untuk iBeacon. Setiap mobile device dapat mendeteksi advertisements, namun tidak dapat terhubung ke iBeacon.
- Device address type, dispesifikasikan sebagai public.
- Advertise BLE channel, terdapat 3 advertisement channel, kita akan gunakan semuanya.
- Filter policy untuk connection dan scan requests.
Bagian GAP event handler
Saat initialization, kita register ble_gap_event_handler untuk menangani GAP events. Kita hanya akan handle event ketika advertisement data sudah diset dan setelah advertisement dimulai.
Setelah setting advertisement data, kita mulai advertisement dengan memanggil esp_ble_gap_start_advertising dan check result dalam event ESP_GAP_BLE_ADV_START_COMPLETE_EVT.
Bagian Initialization
Fungsi Init memiliki tiga tugas utama yaitu:
- Inisialisasi Bluetooth controller dalam BLE mode.
- Inisialisasi host stack, Bluedroid.
- Inisialisasi GAP dengan setting GAP event handler dan device name.
Bagian Main Function
Setelah BLE component siap, kita definisikan iBeacon advertisement data
dan pass ke esp_ble_gap_config_adv_data_raw, yang akan men-trigger GAP untuk memulai iBeacon advertisement.
Aplikasi sudah siap ditest. Flash devkit, kemudian jalankan nRF Connect pada mobile device untuk melihat apakah ESP32 iBeacon terdeteksi.

Sesuai ekspektasi, kita dapat lihat ESP32 iBeacon tampil pada aplikasi nRF Connect. Terdapat juga informasi latest Received Signal Strength Indicator (RSSI) value dan advertisement interval.
Pada modul selanjutnya, kita akan belajar menggunakan GATT API untuk mengirim data ke BLE peers.