Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add BLE remote control example (AEGHB-286) #283

Closed
wants to merge 3 commits into from

Conversation

CheahHaoYi
Copy link
Contributor

Add an example that demonstrate how to use various ESP APIs to create a remote control using an ESP.

@CLAassistant
Copy link

CLAassistant commented Jul 10, 2023

CLA assistant check
All committers have signed the CLA.

@CheahHaoYi CheahHaoYi marked this pull request as draft July 10, 2023 06:52
@github-actions github-actions bot changed the title Add BLE remote control example Add BLE remote control example (AEGHB-286) Jul 10, 2023
@CheahHaoYi CheahHaoYi marked this pull request as ready for review July 10, 2023 06:57
@leeebo
Copy link
Collaborator

leeebo commented Jul 10, 2023

@CheahHaoYi Thanks for your contribution, we'll help review and then merge it!

set_button_bit(PIN_BUTTON_D, gpio_get_level(PIN_BUTTON_D));
#endif

*button_in = button_input;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is no operation on button_input in this function, yet it is being assigned to *button_in. This will look strange. You may have the current value of button_input returned by set_button_bit. In fact, the button_input can be encapsulated by get/set/clear functions. There is no need for the caller to manage it.

* @param[out] cali_handle Pointer to calibration handle
*/
esp_err_t adc_calibration_init(adc_channel_t channel, adc_cali_handle_t* cali_handle)
{
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Put local functions together.

#if ADC_CALI_SCHEME_CURVE_FITTING_SUPPORTED
ESP_LOGI(TAG, "deregister %s calibration scheme", "Curve Fitting");
ESP_ERROR_CHECK(adc_cali_delete_scheme_curve_fitting(handle));

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove line to have consistent spacing in #if block.

void hid_close_event(void);

void hid_event_callback(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if,
esp_ble_gatts_cb_param_t *param)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indentation.

break;
case ESP_GATTS_CREAT_ATTR_TAB_EVT:
if (param->add_attr_tab.status == ESP_GATT_OK) {
ESP_LOGI(HID_DEMO_TAG, "Create attribute table successfully, table size = %d",param->add_attr_tab.num_handle);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Space after comma.

break;
case ESP_GATTS_START_EVT:
ESP_LOGI(HID_DEMO_TAG, "Start Service %s, service_handle %d",
(param->start.status == ESP_GATT_OK ? "Sucessful" : "Failed") , param->start.service_handle);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Extra space before comma.

# ESP-IDF BLE Remote Control Example

This example shows how to create a BLE Joystick with an ESP32 implemented in BLUEDROID.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"ESP32 series SoC"

sizeof(val_batt_level),
(uint8_t *) &val_batt_level,
},
},
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's better to add the Client Characteristic Configuration descriptor for Battery Level Characteristic. So that we can send notification to client when the battery level changes.

.p_service_data = NULL,
.service_uuid_len = sizeof(hidd_service_uuid128),
.p_service_uuid = hidd_service_uuid128,
.flag = 0x6,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's better to replace with .flag = (ESP_BLE_ADV_FLAG_GEN_DISC | ESP_BLE_ADV_FLAG_BREDR_NOT_SPT), to improve code readability.

ESP_LOGI(HID_DEMO_TAG, "Profile Reciving a new connection, conn_id %d", param->connect.conn_id);
// Save the connection ID, need this for sending notification in send_user_input()
client.connection_id = param->connect.conn_id;
is_connected = true;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't set is_connected here. Because the connection is required to be encrypted for HID profile. We should set it to true in ESP_GAP_BLE_AUTH_CMPL_EVT.

gap_security_request_event(param);
break;
case ESP_GAP_BLE_AUTH_CMPL_EVT:
ESP_LOGI(HID_DEMO_TAG, "ESP_GAP_BLE_AUTH_CMPL_EVT");
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should check whether the authentication is successful by param->ble_security.auth_cmpl.success. If authentication is successful then we set is_connected to true.

{
// Same service instance ID as the one passed into esp_ble_gatts_create_attr_tab
ESP_LOGI(HID_DEMO_TAG, "Service Instance ID: %d, UUID: 0x%x", param->add_attr_tab.svc_inst_id, param->add_attr_tab.svc_uuid.uuid.uuid16);
// ESP_LOGI(HID_DEMO_TAG, "UUID of Service: 0x%x", param->add_attr_tab.svc_uuid.uuid.uuid16);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clean up.

}

ESP_LOGI(HID_DEMO_TAG, "Create attribute table successfully, the number handle = %d\n",param->add_attr_tab.num_handle);
// memcpy(handler_table, param->add_attr_tab.handles, param->add_attr_tab.num_handle * sizeof(uint16_t));
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clean up.


// Alternatively, to simply poll user input can do:
// joystick_adc_read(&x_axis, &y_axis);
// button_read(&button_in);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are these comments still useful?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comments here are to provide a simplified implementation of the remote control (where user just poll for the inputs), if let's say the event queue implementation does not fit the user's use case.

Copy link
Collaborator

@bubblesnake bubblesnake left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clean up.

Copy link
Collaborator

@bubblesnake bubblesnake left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me.

@leeebo
Copy link
Collaborator

leeebo commented Aug 3, 2023

Hi @CheahHaoYi Thanks again for the contributions, we're preparing to merge it. Before that, we suggest the following:

  1. Add a license declaration in each C headers and source files, please follow the license format
  2. Squash the 5 commits to one for a better look

Refactor project, Fix based on PR comments

Fix indentation

Add encapsulation of button_input

Remove unused comments

Add license
@leeebo
Copy link
Collaborator

leeebo commented Aug 8, 2023

Hi @CheahHaoYi sdkconfig.defaults also needs to be provided to ensure the example can be compiled successfully by default.

For IDF>=5.0, please run idf.py save-defconfig under your project to save the default values to file.

@leeebo
Copy link
Collaborator

leeebo commented Aug 8, 2023

Like this example bluedroid/ble/gatt_server, to support different targets, multiple sdkconfig.defaults.{target} needs to provide

@CheahHaoYi
Copy link
Contributor Author

Added the sdkconfig.defaults file, specialized support for different targets would not be necessary for this example I believe

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants