diff --git a/examples/bluetooth/ble_remote_control/main/hidd.c b/examples/bluetooth/ble_remote_control/main/hidd.c index ebe627582..f6e7d9b61 100644 --- a/examples/bluetooth/ble_remote_control/main/hidd.c +++ b/examples/bluetooth/ble_remote_control/main/hidd.c @@ -23,7 +23,7 @@ client_info_t client; extern bool is_connected; // Need this here in the case of disconnection // Characteristic Values -static const uint8_t val_batt_level = 0; +static uint8_t val_batt_level = 0; // 0% battery level (assume battery not present, for user to modify if need) static uint8_t val_bat_cccd[] = {0x01, 0x00}; // CCCD allows the Central Device to enable/disable notifications/indications @@ -479,6 +479,7 @@ esp_err_t copy_attribute_handles(int instance_id, uint16_t *handles, int num_han switch (instance_id) { case INST_ID_BAT_SVC: memcpy(handle_table.handles_bat_svc, handles, num_handle * sizeof(uint16_t)); + client.bat_attr_handle = handles[IDX_BAT_LVL_VAL]; return ESP_OK; case INST_ID_HID: memcpy(handle_table.handles_hid_svc, handles, num_handle * sizeof(uint16_t)); @@ -558,3 +559,21 @@ esp_err_t send_user_input(void) false // need_confirm ); } + +esp_err_t set_hid_battery_level(uint8_t value) +{ + if (value > 100) { + value = 100; + } + + val_batt_level = value; + + return esp_ble_gatts_send_indicate( + client.gatt_if, // gatts_if + client.connection_id, // conn_id + client.bat_attr_handle, // attr_handle + 1, // value_len + &val_batt_level, // value + false // need_confirm + ); +} diff --git a/examples/bluetooth/ble_remote_control/main/hidd.h b/examples/bluetooth/ble_remote_control/main/hidd.h index e2e81541f..dc965a617 100644 --- a/examples/bluetooth/ble_remote_control/main/hidd.h +++ b/examples/bluetooth/ble_remote_control/main/hidd.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -140,6 +140,7 @@ typedef struct { esp_gatt_if_t gatt_if; uint16_t connection_id; uint16_t attr_handle; + uint16_t bat_attr_handle; } client_info_t; /** @@ -164,3 +165,11 @@ void set_hid_report_values(uint8_t joystick_x, uint8_t joystick_y, uint8_t butto * @brief Send the HID Report to the client (notification) */ esp_err_t send_user_input(void); + +/** + * @brief Set the hid battery level value to be sent + * + * @note Values to be set depends on the device specification + * @note The value is capped at 100 +*/ +esp_err_t set_hid_battery_level(uint8_t value); diff --git a/examples/bluetooth/ble_remote_control/main/main.c b/examples/bluetooth/ble_remote_control/main/main.c index 6912e62ed..291a38ca7 100644 --- a/examples/bluetooth/ble_remote_control/main/main.c +++ b/examples/bluetooth/ble_remote_control/main/main.c @@ -34,7 +34,7 @@ bool is_connected = false; QueueHandle_t input_queue = NULL; - +static uint8_t s_battery_level = 0; const char *DEVICE_NAME = "ESP32 Remote"; /** @@ -76,7 +76,6 @@ void joystick_task() uint8_t hat_switch = 0; // unused in this example uint8_t button_in = 0; uint8_t throttle = 0; // unused in this example - while (true) { DELAY(HID_LATENCY); @@ -140,6 +139,18 @@ void joystick_task() } } +static void battery_timer_cb(TimerHandle_t xTimer) +{ + s_battery_level = (s_battery_level + 1) % 100; + ESP_LOGI(HID_DEMO_TAG, "Change battery level to %d", s_battery_level); + if (is_connected) { + esp_err_t ret = set_hid_battery_level(s_battery_level); + if (ret != ESP_OK) { + ESP_LOGE(HID_DEMO_TAG, "Failed to set battery level"); + } + } +} + /** * @brief Initialize bluetooth resources * @return ESP_OK on success; any other value indicates error @@ -250,7 +261,11 @@ void app_main(void) #else //CONFIG_JOYSTICK_INPUT_MODE_ADC xTaskCreate(joystick_ext_read, "ext_hardware_joystick", 2048, NULL, tskIDLE_PRIORITY, NULL); #endif - + // Create a timer to update battery level periodically (add 1 each time as an example) + TimerHandle_t battery_timer = xTimerCreate(NULL, pdMS_TO_TICKS(5000), true, NULL, battery_timer_cb); + if (xTimerStart(battery_timer, 0) != pdPASS) { + ESP_LOGE(HID_DEMO_TAG, "Failed to start battery timer"); + } // Main joystick task joystick_task();