diff --git a/esphome/components/esp32_ble_client/ble_client_base.cpp b/esphome/components/esp32_ble_client/ble_client_base.cpp index 07bd3f8a64..d9d3737791 100644 --- a/esphome/components/esp32_ble_client/ble_client_base.cpp +++ b/esphome/components/esp32_ble_client/ble_client_base.cpp @@ -12,6 +12,12 @@ namespace esphome::esp32_ble_client { static const char *const TAG = "esp32_ble_client"; +// Default connection parameters matching ESP-IDF's BTM_BLE_CONN_INT_*_DEF +// These are conservative values that work well with most devices +static const uint16_t DEFAULT_MIN_CONN_INTERVAL = 0x0A; // 10 * 1.25ms = 12.5ms +static const uint16_t DEFAULT_MAX_CONN_INTERVAL = 0x0C; // 12 * 1.25ms = 15ms +static const uint16_t DEFAULT_CONN_TIMEOUT = 600; // 600 * 10ms = 6s + // Intermediate connection parameters for standard operation // ESP-IDF defaults (12.5-15ms) are too slow for stable connections through WiFi-based BLE proxies, // causing disconnections. These medium parameters balance responsiveness with bandwidth usage. @@ -111,8 +117,12 @@ void BLEClientBase::connect() { this->remote_addr_type_); this->paired_ = false; - // Open the connection without setting connection parameters - // Parameters will be set after connection is established if needed + // Set default connection parameters before connecting + // This ensures we use conservative parameters that work well with weak signal devices + // rather than potentially aggressive parameters from a previous connection + this->set_default_conn_params_(); + + // Open the connection with default parameters auto ret = esp_ble_gattc_open(this->gattc_if_, this->remote_bda_, this->remote_addr_type_, true); if (ret) { this->log_gattc_warning_("esp_ble_gattc_open", ret); @@ -215,8 +225,8 @@ void BLEClientBase::log_warning_(const char *message) { ESP_LOGW(TAG, "[%d] [%s] %s", this->connection_index_, this->address_str_.c_str(), message); } -void BLEClientBase::set_conn_params_(uint16_t min_interval, uint16_t max_interval, uint16_t latency, uint16_t timeout, - const char *param_type) { +void BLEClientBase::update_conn_params_(uint16_t min_interval, uint16_t max_interval, uint16_t latency, + uint16_t timeout, const char *param_type) { esp_ble_conn_update_params_t conn_params = {{0}}; memcpy(conn_params.bda, this->remote_bda_, sizeof(esp_bd_addr_t)); conn_params.min_int = min_interval; @@ -230,16 +240,33 @@ void BLEClientBase::set_conn_params_(uint16_t min_interval, uint16_t max_interva } } +void BLEClientBase::set_conn_params_(uint16_t min_interval, uint16_t max_interval, uint16_t latency, uint16_t timeout, + const char *param_type) { + // Set preferred connection parameters before connecting + // These will be used when establishing the connection + this->log_connection_params_(param_type); + esp_err_t err = esp_ble_gap_set_prefer_conn_params(this->remote_bda_, min_interval, max_interval, latency, timeout); + if (err != ESP_OK) { + this->log_gattc_warning_("esp_ble_gap_set_prefer_conn_params", err); + } +} + void BLEClientBase::set_fast_conn_params_() { // Switch to fast connection parameters for service discovery // This improves discovery speed for devices with short timeouts - this->set_conn_params_(FAST_MIN_CONN_INTERVAL, FAST_MAX_CONN_INTERVAL, 0, FAST_CONN_TIMEOUT, "fast"); + this->update_conn_params_(FAST_MIN_CONN_INTERVAL, FAST_MAX_CONN_INTERVAL, 0, FAST_CONN_TIMEOUT, "fast"); } void BLEClientBase::set_medium_conn_params_() { // Set medium connection parameters for balanced performance // This balances performance with bandwidth usage for normal operation - this->set_conn_params_(MEDIUM_MIN_CONN_INTERVAL, MEDIUM_MAX_CONN_INTERVAL, 0, MEDIUM_CONN_TIMEOUT, "medium"); + this->update_conn_params_(MEDIUM_MIN_CONN_INTERVAL, MEDIUM_MAX_CONN_INTERVAL, 0, MEDIUM_CONN_TIMEOUT, "medium"); +} + +void BLEClientBase::set_default_conn_params_() { + // Set default connection parameters before connecting + // These conservative values work well with most devices including weak signal ones + this->set_conn_params_(DEFAULT_MIN_CONN_INTERVAL, DEFAULT_MAX_CONN_INTERVAL, 0, DEFAULT_CONN_TIMEOUT, "default"); } bool BLEClientBase::gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t esp_gattc_if, diff --git a/esphome/components/esp32_ble_client/ble_client_base.h b/esphome/components/esp32_ble_client/ble_client_base.h index d6eea0ff93..4fd1b28f19 100644 --- a/esphome/components/esp32_ble_client/ble_client_base.h +++ b/esphome/components/esp32_ble_client/ble_client_base.h @@ -133,10 +133,13 @@ class BLEClientBase : public espbt::ESPBTClient, public Component { void log_event_(const char *name); void log_gattc_event_(const char *name); + void update_conn_params_(uint16_t min_interval, uint16_t max_interval, uint16_t latency, uint16_t timeout, + const char *param_type); void set_conn_params_(uint16_t min_interval, uint16_t max_interval, uint16_t latency, uint16_t timeout, const char *param_type); void set_fast_conn_params_(); void set_medium_conn_params_(); + void set_default_conn_params_(); void log_gattc_warning_(const char *operation, esp_gatt_status_t status); void log_gattc_warning_(const char *operation, esp_err_t err); void log_connection_params_(const char *param_type);