6.7 KiB
Bandwidth: Configured vs Negotiated Display
New Feature
The WiFi connection info now shows both configured and negotiated bandwidth, making it easy to spot when the connection didn't get the bandwidth you requested.
Example Output
Perfect Match (80MHz)
I (13022) main: WiFi CONNECTED - BLUE LED solid
I (13022) main: SSID: 'ClubHouse'
I (13032) main: Band: 5GHz
I (13032) main: Bandwidth: 80MHz (VHT80) (negotiated) - configured: VHT80 ← Match!
I (13032) main: Channel: 120
I (13042) main: RSSI: -32 dBm
Mismatch (Configured 80MHz, Got 20MHz)
I (13022) main: WiFi CONNECTED - BLUE LED solid
I (13022) main: SSID: 'ClubHouse'
I (13032) main: Band: 5GHz
I (13032) main: Bandwidth: 20MHz (HT20) (negotiated) - configured: VHT80 ← MISMATCH!
W (13032) main: ⚠ Bandwidth mismatch! Configured VHT80 but negotiated 20MHz (HT20)
W (13032) main: Check: router channel width setting, channel selection, RF interference
I (13032) main: Channel: 120
I (13042) main: RSSI: -32 dBm
Match (40MHz)
I (13022) main: WiFi CONNECTED - BLUE LED solid
I (13022) main: SSID: 'ClubHouse'
I (13032) main: Band: 5GHz
I (13032) main: Bandwidth: 40MHz (HT40) (negotiated) - configured: HT40 ← Match!
I (13032) main: Channel: 44
I (13042) main: RSSI: -35 dBm
What It Shows
| Field | Description |
|---|---|
| Negotiated | What bandwidth the device actually connected at |
| Configured | What bandwidth you requested via config_device.py |
| Warning | Appears when there's a mismatch |
Why Mismatches Happen
Configured VHT80 → Negotiated HT20
Common causes:
- Router channel width - Router set to 20MHz or "Auto" picked 20MHz
- Channel not 80MHz capable - Some channels don't support 80MHz width
- DFS channel issues - Dynamic Frequency Selection interference
- Interference - RF environment forced downgrade
- Router doesn't support 802.11ac/ax - Old router (802.11n only)
Fix:
# Check router settings:
# - Channel width: 80MHz (not Auto or 20/40MHz)
# - Channel: 36, 44, 52, 100, 108, 116, 149, 157
# - Mode: 802.11ac or 802.11ax
# Try non-DFS channel
# Set router to channel 36 or 44 (most reliable for 80MHz)
# Then reconnect
./config_device.py -p /dev/ttyUSB1 -i 192.168.1.81 \
-s ClubHouse -b 5G -B VHT80
Configured HT40 → Negotiated HT20
Common causes:
- Router channel width - Router set to 20MHz only
- Interference - Adjacent channels occupied
- 2.4GHz congestion - Too many overlapping networks
Fix:
# On router:
# - Channel width: 40MHz
# - Channel: 1, 6, or 11 (2.4GHz) or any 5GHz channel
# Reconnect
./config_device.py -p /dev/ttyUSB1 -i 192.168.1.81 \
-s ClubHouse -b 5G -B HT40
Troubleshooting Guide
Step 1: Check WiFi Driver Log
The most reliable indicator is in the WiFi driver log:
I (12652) wifi:connected with ClubHouse, aid = 3, channel 120, BW20(BELOW, C1)
^^^^
BW20= 20MHzBW40= 40MHzBW80= 80MHz
This is what actually happened (ground truth).
Step 2: Check Our Display
Our display gets this from the API:
I (13032) main: Bandwidth: 20MHz (HT20) (negotiated) - configured: VHT80
Should match the WiFi driver log.
Step 3: If Mismatch, Check Router
For 80MHz on 5GHz:
- Router channel width = 80MHz (not Auto)
- Channel = 36, 44, 52, 100, 108, 116, 149, or 157
- No DFS interference (try channel 36 or 44)
- 802.11ac or 802.11ax enabled
For 40MHz:
- Router channel width = 40MHz minimum
- Adjacent channels available
- Low interference
For 20MHz:
- This is the fallback - always works
- Good for congested areas
- Best for stability
Bandwidth Performance
| Bandwidth | Throughput (5GHz) | Use Case |
|---|---|---|
| 20MHz (HT20) | ~130 Mbps | Congested areas, maximum range |
| 40MHz (HT40) | ~270 Mbps | Good throughput, less congestion |
| 80MHz (VHT80) | ~530 Mbps | Maximum throughput, clean RF |
Testing Procedure
Test VHT80 (80MHz)
# 1. Configure router for 80MHz
# Channel: 36 or 44 (non-DFS)
# Width: 80MHz
# Mode: 802.11ac or 802.11ax
# 2. Configure ESP32-C5
./config_device.py -p /dev/ttyUSB1 -i 192.168.1.81 \
-s ClubHouse -b 5G -B VHT80
# 3. Check connection
idf.py -p /dev/ttyUSB1 monitor
# Look for:
# I (13032) main: Bandwidth: 80MHz (VHT80) (negotiated) - configured: VHT80
# No warning should appear!
# 4. Test throughput
iperf -c 192.168.1.81 -t 30
# Expected: ~500 Mbps
Test HT40 (40MHz)
# 1. Configure router for 40MHz
# Width: 40MHz
# 2. Configure ESP32-C5
./config_device.py -p /dev/ttyUSB1 -i 192.168.1.81 \
-s ClubHouse -b 5G -B HT40
# 3. Check connection
# Should see: Bandwidth: 40MHz (HT40) (negotiated) - configured: HT40
# 4. Test throughput
iperf -c 192.168.1.81 -t 30
# Expected: ~270 Mbps
Implementation Details
New API Function
wifi_cfg.h:
bool wifi_cfg_get_bandwidth(char *buf, size_t buf_size);
Returns the bandwidth string from NVS ("HT20", "HT40", "VHT80").
Display Logic
main.c:
// Get configured from NVS
char configured_bw[16] = {0};
wifi_cfg_get_bandwidth(configured_bw, sizeof(configured_bw));
// Get negotiated from WiFi API
wifi_bandwidth_t bw = /* from esp_wifi_get_bandwidths() */;
// Compare and warn if mismatch
if (strcmp(configured_bw, "VHT80") == 0 && bw != WIFI_BW80) {
ESP_LOGW(TAG, "⚠ Bandwidth mismatch!");
}
Warning Conditions
A warning appears when:
- Configured VHT80 but negotiated HT20 or HT40
- Configured HT40 but negotiated HT20
- Configured HT20 but negotiated HT40 or VHT80 (rare)
Files Modified
wifi_cfg.h:
- Added
wifi_cfg_get_bandwidth()function declaration
wifi_cfg.c:
- Implemented
wifi_cfg_get_bandwidth()to read "bw" from NVS
main.c:
- Updated bandwidth display to show both configured and negotiated
- Added mismatch detection and warning
- Added troubleshooting hints in warning
Benefits
- ✅ Immediate visibility - See if bandwidth negotiation failed
- ✅ Troubleshooting - Mismatch warning points to configuration issue
- ✅ Verification - Confirm router settings are correct
- ✅ Debugging - Know if problem is config vs negotiation
- ✅ Production - Catch deployment issues (wrong router settings)
Perfect for your WiFi analyzer product - you'll immediately know if the connection isn't using optimal bandwidth!
Build and Test
cd ~/Code/esp32/esp32-iperf
idf.py build flash monitor
After connecting, you'll see both configured and negotiated bandwidth, with warnings if they don't match.