diff --git a/components/wifi_cfg/wifi_cfg.c b/components/wifi_cfg/wifi_cfg.c index 08c5a46..25aba97 100644 --- a/components/wifi_cfg/wifi_cfg.c +++ b/components/wifi_cfg/wifi_cfg.c @@ -285,6 +285,24 @@ bool wifi_cfg_apply_from_nvs(void) { } #endif + // Set power save mode based on configuration + wifi_ps_type_t ps_mode = WIFI_PS_NONE; // Default: no power save (best for CSI) + + if (strcmp(powersave, "MIN") == 0 || strcmp(powersave, "MIN_MODEM") == 0) { + ps_mode = WIFI_PS_MIN_MODEM; + ESP_LOGI(TAG, "Setting power save mode: MIN_MODEM"); + } else if (strcmp(powersave, "MAX") == 0 || strcmp(powersave, "MAX_MODEM") == 0) { + ps_mode = WIFI_PS_MAX_MODEM; + ESP_LOGI(TAG, "Setting power save mode: MAX_MODEM"); + } else { + ESP_LOGI(TAG, "Setting power save mode: NONE (best for CSI)"); + } + + err2 = esp_wifi_set_ps(ps_mode); + if (err2 != ESP_OK) { + ESP_LOGW(TAG, "Failed to set power save mode: %s", esp_err_to_name(err2)); + } + err2 = esp_wifi_connect(); if (err2 != ESP_OK && err2 != ESP_ERR_WIFI_NOT_INIT && err2 != ESP_ERR_INVALID_STATE) { ESP_ERROR_CHECK(err2); } return true; diff --git a/config_device.py b/config_device.py index 17e0b5c..2a4b58f 100755 --- a/config_device.py +++ b/config_device.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 """ -ESP32 WiFi Configuration Tool - With verbose mode +ESP32 WiFi Configuration Tool - With verbose mode and 80MHz support """ import serial @@ -91,7 +91,7 @@ def config_device(port, ip, ssid="ClubHouse2G", password="ez2remember", print(f"Sent {bytes_written} bytes") print("Waiting for response...") - time.sleep(3) # Give more time for response + time.sleep(3) # Read response if ser.in_waiting: @@ -102,7 +102,7 @@ def config_device(port, ip, ssid="ClubHouse2G", password="ez2remember", print("\nDevice response:") print("-" * 70) - for line in response.split('\n')[:30]: # Show first 30 lines + for line in response.split('\n')[:30]: if line.strip(): print(f" {line}") print("-" * 70) @@ -117,7 +117,6 @@ def config_device(port, ip, ssid="ClubHouse2G", password="ez2remember", success_indicators.append("✓ Config saved to NVS") if "got ip:" in response.lower(): success_indicators.append("✓ Device connected to WiFi!") - # Extract IP from response import re ip_match = re.search(r'got ip:(\d+\.\d+\.\d+\.\d+)', response, re.IGNORECASE) if ip_match: @@ -153,27 +152,25 @@ def config_device(port, ip, ssid="ClubHouse2G", password="ez2remember", print("="*70) log_verbose("Performing hardware reset via DTR/RTS", verbose) - # Standard ESP32 reset sequence - ser.dtr = False # DTR low - ser.rts = True # RTS high (EN low) + ser.dtr = False + ser.rts = True time.sleep(0.1) - ser.rts = False # RTS low (EN high) + ser.rts = False time.sleep(0.1) - ser.dtr = True # DTR high + ser.dtr = True print("✓ Reset signal sent - waiting for boot...") - # Wait for boot messages - time.sleep(3) # Longer wait for full boot + time.sleep(3) if ser.in_waiting: boot_msg = ser.read(ser.in_waiting).decode('utf-8', errors='ignore') print("\nBoot messages:") print("-" * 70) - for line in boot_msg.split('\n')[:40]: # Show more lines + for line in boot_msg.split('\n')[:40]: if line.strip(): print(f" {line}") print("-" * 70) @@ -185,7 +182,7 @@ def config_device(port, ip, ssid="ClubHouse2G", password="ez2remember", if "WiFi config loaded from NVS" in boot_msg: boot_success.append("✓ Config successfully loaded from NVS") elif "No WiFi config" in boot_msg or "YELLOW LED" in boot_msg: - boot_warnings.append("✗ NO CONFIG found in NVS - this is the problem!") + boot_warnings.append("✗ NO CONFIG found in NVS") boot_warnings.append(" Device does not see saved config") if "got ip:" in boot_msg.lower(): @@ -198,13 +195,6 @@ def config_device(port, ip, ssid="ClubHouse2G", password="ez2remember", if "WiFi CONNECTED" in boot_msg: boot_success.append("✓ WiFi connection confirmed") - if "BLUE LED solid" in boot_msg or "BLUE solid" in boot_msg: - boot_success.append("✓ LED should be BLUE (connected)") - elif "YELLOW solid" in boot_msg or "YELLOW LED" in boot_msg: - boot_warnings.append("⚠ LED is YELLOW (no config)") - elif "RED" in boot_msg and "blink" in boot_msg: - boot_warnings.append("⚠ LED is RED (connection failed)") - if boot_success: print("\nBoot Status - SUCCESS:") for msg in boot_success: @@ -218,7 +208,6 @@ def config_device(port, ip, ssid="ClubHouse2G", password="ez2remember", print("\n⚠ No boot messages received") print(" Device may still be booting...") - # Get final port stats if verbose: log_verbose(f"Input buffer: {ser.in_waiting} bytes", verbose) log_verbose(f"Output buffer empty: {ser.out_waiting == 0}", verbose) @@ -237,25 +226,16 @@ def config_device(port, ip, ssid="ClubHouse2G", password="ez2remember", print(f"PowerSave: {powersave}") print(f"{'='*70}") print("\nNext steps:") - print(f" 1. Check LED color:") - print(f" - GREEN = Connected ✓") - print(f" - YELLOW = No config saved ✗") - print(f" - RED blinking = Connection failed") - print(f" 2. Test connection:") + print(f" 1. Test connection:") print(f" ping {ip}") print(f" iperf -c {ip}") - print(f"\nIf LED is YELLOW:") - print(f" - Config is NOT being saved to NVS") - print(f" - Check if wifi_cfg.c is handling BAND: and BW: fields") - print(f" - Try running: idf.py monitor") - print(f" to see what the device is actually receiving") return True except serial.SerialException as e: print(f"\n✗ Serial error: {e}") log_verbose(f"Serial exception details: {type(e).__name__}", verbose) - print(" Is another program using this port? (idf.py monitor, screen, etc.)") + print(" Is another program using this port?") return False except KeyboardInterrupt: print("\n\nConfiguration cancelled by user") @@ -277,32 +257,26 @@ def main(): formatter_class=argparse.RawDescriptionHelpFormatter, epilog=""" Examples: - # Basic configuration (2.4GHz) with auto-reboot + # Basic configuration (2.4GHz, 20MHz) with auto-reboot %(prog)s -p /dev/ttyUSB0 -i 192.168.1.51 - # 5GHz with HT40 bandwidth and auto-reboot + # 5GHz with 40MHz bandwidth %(prog)s -p /dev/ttyUSB0 -i 192.168.1.81 -s ClubHouse5G -b 5G -B HT40 + # 5GHz with 80MHz bandwidth (ESP32-C5 only, 802.11ac/ax) + %(prog)s -p /dev/ttyUSB0 -i 192.168.1.81 -s ClubHouse5G -b 5G -B VHT80 + # Disable power save for best CSI quality (default) %(prog)s -p /dev/ttyUSB0 -i 192.168.1.51 -ps NONE - # Enable minimum power save (useful for battery-powered devices) + # Enable minimum power save %(prog)s -p /dev/ttyUSB0 -i 192.168.1.51 -ps MIN - # Enable maximum power save (lowest power consumption) - %(prog)s -p /dev/ttyUSB0 -i 192.168.1.51 -ps MAX - - # Configure without rebooting (manual reboot required) + # Configure without rebooting %(prog)s -p /dev/ttyUSB0 -i 192.168.1.51 -r - # With verbose output to see boot messages + # With verbose output %(prog)s -p /dev/ttyUSB0 -i 192.168.1.51 -v - - # Custom WiFi credentials on 2.4GHz - %(prog)s -p /dev/ttyUSB0 -i 192.168.1.52 -s MyWiFi -P mypass - - # Custom gateway - %(prog)s -p /dev/ttyUSB0 -i 10.0.0.100 -g 10.0.0.1 """ ) @@ -321,18 +295,24 @@ Examples: parser.add_argument('-b', '--band', default='2.4G', choices=['2.4G', '5G'], help='WiFi band: 2.4G or 5G (default: 2.4G)') parser.add_argument('-B', '--bandwidth', default='HT20', - choices=['HT20', 'HT40'], - help='Channel bandwidth: HT20 or HT40 (default: HT20)') + choices=['HT20', 'HT40', 'VHT80'], + help='Channel bandwidth: HT20 (20MHz), HT40 (40MHz), VHT80 (80MHz, 5GHz only) (default: HT20)') parser.add_argument('-ps', '--powersave', default='NONE', choices=['NONE', 'MIN', 'MIN_MODEM', 'MAX', 'MAX_MODEM'], help='Power save mode: NONE (no PS, best for CSI), MIN/MIN_MODEM, MAX/MAX_MODEM (default: NONE)') parser.add_argument('-r', '--no-reboot', action='store_true', - help='Do NOT reboot device after configuration (default: will reboot)') + help='Do NOT reboot device after configuration') parser.add_argument('-v', '--verbose', action='store_true', - help='Enable verbose output (show detailed debug info)') + help='Enable verbose output') args = parser.parse_args() + # Validate bandwidth selection + if args.bandwidth == 'VHT80' and args.band == '2.4G': + print("\n✗ Error: VHT80 (80MHz) is only supported on 5GHz band") + print(" Either use -b 5G or choose HT20/HT40 bandwidth") + sys.exit(1) + success = config_device( port=args.port, ip=args.ip, @@ -343,7 +323,7 @@ Examples: band=args.band, bandwidth=args.bandwidth, powersave=args.powersave, - reboot=not args.no_reboot, # Invert since flag is --no-reboot + reboot=not args.no_reboot, verbose=args.verbose )