Symptom
BLE scans miss advertisements, connections time out or notifications stall while Wi-Fi is busy (OTA download, MQTT bursts, SoftAP provisioning). Everything works when Wi-Fi is idle.
Why
The ESP32 has one 2.4 GHz RF module shared by Wi-Fi, Bluetooth and (on some chips) 802.15.4. Only one can use it at a time. The coexistence module time-slices the radio between Wi-Fi, BT and BLE and assigns priorities by state (idle, scanning, connecting, connected). Every millisecond Wi-Fi gets, BLE doesn't.
Espressif's coexistence table marks most Wi-Fi station + BLE connected combinations as stable, but SoftAP connecting/connected scenarios as unstable.
What to do
- Enable software coexistence:
CONFIG_ESP_COEX_SW_COEXIST_ENABLE. - Pin Wi-Fi and Bluetooth tasks to different CPU cores on dual-core chips.
- Keep the default Wi-Fi power-save settings when using coexistence.
- If BLE scanning must not be interrupted, look at
CONFIG_BTDM_CTRL_FULL_SCAN_SUPPORTED. - Design the protocol for it:
- Avoid BLE provisioning and SoftAP at the same time; pick one.
- Use longer BLE supervision timeouts during heavy Wi-Fi phases (OTA).
- Pause BLE scanning during large Wi-Fi transfers, or accept missed advertisements and repeat important ones.
- Reduce memory pressure (dynamic buffers, smaller Wi-Fi buffer counts); coexistence plus TLS is memory-hungry, and NimBLE helps here.