-
-
Notifications
You must be signed in to change notification settings - Fork 66
ESPHome Configurations
| Chip | Compat | Notes |
|---|---|---|
| ESP32 | Good | Original esp32 chip, such as the ESP-WROOM-32 etc. BT4.2 |
| ESP32-S2 | NO | Has no Bluetooth, single core. |
| ESP32-S3 | Good | BT5, Dual-core. No integrated Ethernet MAC |
| ESP32-C2 | ?? | Single-core RISC-V |
| ESP32-C3 | Good, see below | Single core RISC-V, BT5 |
| ESP32-C6 | Experimental - see discussion | One 160MHz core, one 20MHz co-pro. Both RISC-V, BT5.3, Thread, Zigbee |
| ESP32-H2 | ?? | Single-core RISC-V, BT5.3, NO WIFI |
| ESP32-C5 | ?? | Single-core RISC-V, BT5, WIFI6 (2.4GHz + 5GHz) |
| ESP32-P4 | NO | Triple-core RISC-V, NO WIFI OR BT |
- Please let me know if you have first-hand experience of bluetooth-proxy working on any of the above where I don't have "Good" noted. The "??" entries don't mean "it doesn't work well" it literally means that I, personally, aren't sure - probably because I've been too lazy to check properly. Corrections welcomed!
I dunno. Currently (still in 2025) I tend to buy cheap clones of the Wemos, named D1mini32. These have a "classic" esp32 chip (so dual-core) and a printed on-board antenna (so not the little "chip" antennas, which is good, but also without an external antenna connector, which is less good). They seem to go for around AU$4 on AliExpress, which I've been fairly happy with. I'm highly cost-motivated though!
Ethernet-equipped ESP32 boards may be attractive to you, depending on your cost sensitivity and whether you might already have PoE equipment. At nearly 8 times the cost of a standalone ESP32 board however, for the options I've seen I expect you would get FAR better Bermuda performance by throwing a few more WiFi versions into the mix, at less cost. Two radios independently spending 93% of their time listening beats one radio spending 98% of its time listening.
-
Bluetooth proxying is a significant amount of work for an ESP32. Adding more jobs like Audio or Camera processing will likely have disappointing results. Trying to do so won't brick your device, it may just be very unstable (crash a lot, drop lots of adverts) or it could get completely stuck boot-looping. If it's particularly unstable (or doesn't boot at all) you'll simply need to re-flash using a USB cable - after paring back your config a bit.
-
Use the
esp-idfframework, as thearduinoframework is less memory-efficient and doesn't perform as well at bluetooth proxying.
esp32:
variant: esp32 # Make sure you choose *your* esp type here (eg: esp32c3, esp32s3 etc)
framework:
type: esp-idf-
Make sure you have flashed using USB at least once since Nov 2023. This is because there are ESPHome flash partition changes that can't be applied by OTA (Over The Air) updates, and they improve bluetooth performance (nvs caching of GATT data, probably other stuff). Subsequent updates can be done OTA just fine.
-
I turn off serial logging because I think it uses more memory and cpu time. I don't know if that's entirely true or not. With this setting you still get debug logging via wireless connection.
logger:
baud_rate: 0 # disable serial uart logging
#level: VERBOSEThe default ESPHome setup works well for general device discovery and outbound connections, but it is fairly conservative with the advert listening, which works for most use-cases but we want the esp32 to be hearing every possible advert.
The default setup listens for advertisements for 30ms every 320ms. This means that for 90% of the time, it isn't receiving adverts!
The BLE advert protocol is designed to handle this by adding random delays in various places, so that users can usually "find" the devices they want to connect to, but for our purposes we want to see every advert we can.
This is worth experimenting with, but my current suggestion is to use the following:
esp32_ble_tracker:
scan_parameters:
active: True # Whether to send scan-request packets to devices to gather more info (like devicename)
interval: 320ms # default 320ms
window: 300ms # default 30msOther interval/window timings to try are 1000/900. You can experiment with these, but bear in mind:
-
the difference between invterval and window is where esphome gets to do everything else it needs to do, including managing the wifi connection and actually sending data back to Home Assistant.
-
If the interval and window values are too close together, your esp will crash, the wifi will drop, timeouts with HA etc.
-
A BLE device will typically send an advertisement on each of the three advertising channels, in rapid succession, wait for its own interval time, then repeat.
-
setting
active: Falsemight give better performance, I am not sure. The downside with active mode is that the esp will be spending some of its time sending requests to devices to discover their names. This might impact receive performance, I am not sure. The up-side of active mode is that you are more likely to get the name of devices showing up in Bermuda when configuring things, but this isn't hugely useful since you can simply name your entities however you like anyway. -
If, and ONLY IF you have an esp32 connected via Ethernet, you could use interval/window timings of 1:1 (so,
1000and1000, say). -
ESPHome 2025.04 brings some new options,
max_connectionsonesp32_ble_trackerandconnection_slotson thebluetooth_proxycomponent. I haven't tested these parameters' effects on advert scanning for Bermuda, but I expect that increasing these beyond their default values may possibly have negative effects for advert scanning. At ~1KB of ram per slot it would reduce the amount available for other processing. If you need more connections for your controlled devices though, give it a go! At worst, you might just find that you'll need to throw another proxy into that location to handle the extra duties (and you could choose to turnbluetooth_proxy'sactivemode on for only one of them, so the other will always be available for doing advert scans).
The C3 variant of the ESP32 has a single cpu, rather than two cores per the other variants. This seems to result in there being more cases where the sharing of bluetooth and wifi between the one radio causes more difficulties with the software.
- Any time the firmware is doing "bluetooth stuff" it can't do any "wifi stuff". So if the
intervalis too long wifi things will time out. - If
windowis too close tointervalthen it won't have enough time to perform the wifi (or other) things it needs to do.
A solid config for C3 devices is provided below. Thanks to @grigi's report for pulling this together and providing additional testing. Particularly important are the esp32, api and scan_paramaters parts.
The currently suggested ESP32-C3 config:
esp32:
variant: esp32c3
framework:
type: esp-idf # This is important: the "arduino" framework does not perform well.
sdkconfig_options:
# @grigi found in testing that these options resulted in better responsiveness.
# BLE 4.2 is supported by ALL ESP32 boards that have bluetooth, the original and derivatives.
CONFIG_BT_BLE_42_FEATURES_SUPPORTED: y
# Also enable this on any derivative boards (S2, C3 etc) but not the original ESP32.
CONFIG_BT_BLE_50_FEATURES_SUPPORTED: y
# Extend the watchdog timeout, so the device reboots if the device appears locked up for over 10 seconds.
CONFIG_ESP_TASK_WDT_TIMEOUT_S: "10"
logger:
baud_rate: 0 # 0 Enables logging, but disables serial-port logging to free CPU and memory
ota:
platform: esphome
password: !secret ota_password
api:
# Only enable BLE tracking when wifi is up and api is connected
# Gives single-core ESP32-C3 devices time to manage wifi and authenticate with api
on_client_connected:
- esp32_ble_tracker.start_scan:
continuous: true
# Disable BLE tracking when there are no api connections live
on_client_disconnected:
if:
condition:
not:
api.connected:
then:
- esp32_ble_tracker.stop_scan:
esp32_ble_tracker:
scan_parameters:
# Don't auto start BLE scanning, we control it in the `api` block's automation.
continuous: False
active: True # send scan-request packets to gather more info, like device name for some devices.
interval: 320ms # default 320ms - how long to spend on each advert channel
window: 300ms # default 30ms - how long to actually "listen" in each interval. Reduce this if device is unstable.
# If the device cannot keep up or becomes unstable, reduce the "window" setting. This may be
# required if your device is controlling other sensors or doing PWM for lights etc.
bluetooth_proxy:
active: true # allows outbound connections from HA to devices.
sensor:
- platform: uptime
# The uptime sensor is extremely helpful to know if your device is rebooting
# when it shouldn't be. This might indicate your interval-to-window timing is
# too tight, and the window needs to be reduced.
name: "Uptime Sensor"
update_interval: 60s- Improvements and testing by @gigi
- This post for providing the original automation to disable BLE scanning while the wifi is not connected (the example on this page was improved by @gigi, see #299).
- digiblurDIY for the initial sdkconfig options