Bluetooth dan ESP32 – BLE Mesh network – Praktek

Tujuan contoh project adalah membuat LED node yang dapat berjalan dalam BLE Mesh network. LED element akan report status on/off ke network.

Diagram

Persiapan Project

Buat project baru, lalu edit file platformio.ini

[env:az-delivery-devkit-v4]
platform = espressif32
board = az-delivery-devkit-v4
framework = espidf
monitor_speed = 115200

ESP-IDF configuration, sdkconfig, gunakan setting dibawah:

Cukup repot untuk mengubah config satu persatu, Anda dapat download sdkconfig disini: https://drive.google.com/file/d/1FaBaxJYZ2n35N_dMzsyiwRwzI0BmXLPa/view?usp=sharing

CONFIG_BLE_MESH_CFG_CLI=y
CONFIG_BLE_MESH_FRIEND=y
CONFIG_BLE_MESH_GATT_PROXY_SERVER=y
CONFIG_BLE_MESH_GATT_PROXY=y
CONFIG_BLE_MESH_HCI_5_0=y
CONFIG_BLE_MESH_HEALTH_CLI=y
CONFIG_BLE_MESH_IV_UPDATE_TEST=y
CONFIG_BLE_MESH_MEM_ALLOC_MODE_INTERNAL=y
CONFIG_BLE_MESH_NET_BUF_POOL_USAGE=y
CONFIG_BLE_MESH_NET_BUF_TRACE_LEVEL_WARNING=y
CONFIG_BLE_MESH_NODE=y
CONFIG_BLE_MESH_PB_ADV=y
CONFIG_BLE_MESH_PB_GATT=y
CONFIG_BLE_MESH_PROV=y
CONFIG_BLE_MESH_PROXY=y
CONFIG_BLE_MESH_RELAY=y
CONFIG_BLE_MESH_RX_SEG_MSG_COUNT=10
CONFIG_BLE_MESH_SCAN_DUPLICATE_EN=y
CONFIG_BLE_MESH_SELF_TEST=y
CONFIG_BLE_MESH_SETTINGS=y
CONFIG_BLE_MESH_TEST_AUTO_ENTER_NETWORK=y
CONFIG_BLE_MESH_TRACE_LEVEL_WARNING=y
CONFIG_BLE_MESH_TX_SEG_MSG_COUNT=10
CONFIG_BLE_MESH_USE_DUPLICATE_SCAN=y
CONFIG_BLE_MESH=y
CONFIG_BT_BTU_TASK_STACK_SIZE=4512
CONFIG_BTDM_BLE_MESH_SCAN_DUPL_EN=y
CONFIG_BTDM_CTRL_MODE_BLE_ONLY=y
CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY=n
CONFIG_BTDM_CTRL_MODE_BTDM=n
CONFIG_BTDM_MODEM_SLEEP=n
CONFIG_BTDM_SCAN_DUPL_TYPE_DATA_DEVICE=y
CONFIG_BT_ENABLED=y
CONFIG_BT_GATTS_SEND_SERVICE_CHANGE_MANUAL=y

Project juga memerlukan beberapa library tambahan:

Code

Buka file src/main.c, gunakan code berikut:

//import lib dan variable init
#include "esp_log.h"
#include "nvs_flash.h"

#include "esp_ble_mesh_defs.h"
#include "esp_ble_mesh_common_api.h"
#include "esp_ble_mesh_networking_api.h"
#include "esp_ble_mesh_provisioning_api.h"
#include "esp_ble_mesh_config_model_api.h"
#include "esp_ble_mesh_generic_model_api.h"
#include "esp_ble_mesh_local_data_operation_api.h"

#include "board.h"
#include "appmesh_setup.h"
#include "appbt_init.h"

#define TAG "app"

//fungsi provisioning
static void provisioning_cb(esp_ble_mesh_prov_cb_event_t event,
                            esp_ble_mesh_prov_cb_param_t *param)
{
    switch (event)
    {
    case ESP_BLE_MESH_NODE_PROV_COMPLETE_EVT:
        ESP_LOGI(TAG, "provisioned. addr: 0x%04x", param->node_prov_complete.addr);
        break;
    case ESP_BLE_MESH_NODE_PROV_RESET_EVT:
        ESP_LOGI(TAG, "node reset");
        esp_ble_mesh_node_local_reset();
        break;
    default:
        break;
    }
}

//fungsi generic server
static void generic_server_cb(esp_ble_mesh_generic_server_cb_event_t event,
                              esp_ble_mesh_generic_server_cb_param_t *param)
{
    switch (event)
    {
    case ESP_BLE_MESH_GENERIC_SERVER_STATE_CHANGE_EVT:
        ESP_LOGI(TAG, "event name: state-changed");
        if (param->ctx.recv_op == ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_SET ||
            param->ctx.recv_op == ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_SET_UNACK)
        {
            board_set_led(param->value.state_change.onoff_set.onoff);
        }
        break;
    default:
        ESP_LOGW(TAG, "unexpected event");
        break;
    }
}


//fungsi config server
static void config_server_cb(esp_ble_mesh_cfg_server_cb_event_t event,
                             esp_ble_mesh_cfg_server_cb_param_t *param)
{
    if (event == ESP_BLE_MESH_CFG_SERVER_STATE_CHANGE_EVT)
    {
        switch (param->ctx.recv_op)
        {
        case ESP_BLE_MESH_MODEL_OP_APP_KEY_ADD:
            ESP_LOGI(TAG, "config: app key added");
            break;
        default:
            break;
        }
    }
}


//fungsi update element
static void update_element_cb(uint8_t led_s)
{
    esp_ble_mesh_model_t *model = appmesh_get_onoff_model();
    esp_ble_mesh_gen_onoff_srv_t *srv = appmesh_get_onoff_server();
    srv->state.onoff = led_s;

    esp_ble_mesh_model_publish(model, ESP_BLE_MESH_MODEL_OP_GEN_ONOFF_STATUS,
                               sizeof(srv->state.onoff), &srv->state.onoff, ROLE_NODE);
}

//main function
void app_main(void)
{
    esp_err_t err;

    board_init(update_element_cb);
    err = nvs_flash_init();
    if (err == ESP_ERR_NVS_NO_FREE_PAGES)
    {
        ESP_ERROR_CHECK(nvs_flash_erase());
        ESP_ERROR_CHECK(nvs_flash_init());
    }
    ESP_ERROR_CHECK(appbt_init());

    esp_ble_mesh_register_prov_callback(provisioning_cb);
    esp_ble_mesh_register_config_server_callback(config_server_cb);
    esp_ble_mesh_register_generic_server_callback(generic_server_cb);
    ESP_ERROR_CHECK(appmesh_init());
}

Penjelasan Code

Bagian Main Function

Pertama kita jalankan fungsi board_init untuk inisialisasi LED dan button. Kita kirim callback function, update_element_cb, yang akan dipanggil oleh button ISR untuk update mesh element dengan state LED saat ini.

Kemudian inisialisasi nvs partition dan Bluetooth stack dengan memanggil appbt_init.

BLE Mesh stack bergantung pada callbacks untuk berhubungan dengan aplikasi. Kita gunakan provisioning callback untuk mengetahui provisioning events, configuration
callback,yang menangani configuration events, dan server callback untuk menangani LED
change-state requests dari clients.

Terakhir , kita panggil appmesh_init untuk inisialisasi BLE Mesh stack dan membuat BLE Mesh element dari aplikasi.

Bagian fungsi provisioning

Kita menangani dua events. Pertama, event ketika device bergabung ke dalam network dan event ketika keluar dari network. Ketika node keluar, kita clear network information dengan memanggil esp_ble_mesh_node_local_reset, agar resource tersedia untuk provisioning.

Bagian config server

config_server_cb, menangani event node configuration.

Hanya ada satu event untuk configuration server, yaitu ESP_BLE_MESH_CFG_SERVER_STATE_CHANGE_EVT. Kita periksa dengan menggunakan param->ctx.recv_op parameter value, dimana berisi informasi opcode, contoh, add network key, add application key, set node role, dan lainnya.

Bagiain fungsi generic server

Kita tangani event ESP_BLE_MESH_GENERIC_SERVER_STATE_CHANGE_EVT dan jika opcode yang diterima adalah generic on/off model set command, kita update state dari LED dengan value yang diterima.

Bluetooth SIG mendefinisikan banyak models, kita gunakan generic on/off model untuk perangkat yang dibuat, karena LED hanya memiliki dua states: on atau off.

Untuk dokumentasi lebih lengkap lihat di https://www.bluetooth.com/bluetooth-resources/bluetooth-mesh-models/

Bagian fungsi update element

Fungsi callback terakhir yang berguna untuk mengubah state dari LED dan element.

Untuk memperjelas hierarki abstraksi, setiap node memiliki satu atau lebih elemen dan setiap elemen berisi satu atau lebih model. Fungsionalitas ini disediakan oleh server dan/atau klien
tertutup dalam models.

update_element_cb dipanggil dari button ISR sebagai FreeRTOS tasks. Dalam callback ini, kita update status on/off server dan memanggil esp_ble_mesh_model_publish untuk memberi tahu klien tentang perubahan status.

Compile, Upload dan Testing

Sampai disini aplikasi sudah siap, compile dan flash devkit, lalu lakukan testing menggunakan nRF.

Kesimpulan

Dengan berakhir modul ini, section Bluetooth sudah selesai. Masih banyak fitur dari ESP32 BLE yang bisa dipelajari. SIlakan kunjungi example repository di: https://github.com/espressif/esp-idf/tree/master/examples/bluetooth/esp_ble_mesh

Sharing is caring:

Leave a Comment