================================================================================ ESP32-C5 CONFIGURATION DEVICE MANUAL config_device.py v2.0 ================================================================================ TABLE OF CONTENTS ----------------- 1. Overview 2. Installation Requirements 3. Quick Start 4. Command-Line Arguments 5. Usage Examples 6. Operating Modes 7. Configuration Parameters 8. Troubleshooting 9. Advanced Usage 10. Common Deployment Scenarios ================================================================================ 1. OVERVIEW ================================================================================ config_device.py is a Python script that configures ESP32-C5 devices via serial connection. It sets WiFi credentials, network parameters, operating mode (STA or MONITOR), and all other device settings which are stored in Non-Volatile Storage (NVS) for persistence across reboots. Key Features: • Static IP configuration with automatic DHCP disable • Operating mode selection (STA for iperf, MONITOR for WiFi analysis) • Monitor channel configuration • Power save mode control • WiFi band and bandwidth selection • Automatic device reboot after configuration • Comprehensive status feedback ================================================================================ 2. INSTALLATION REQUIREMENTS ================================================================================ Python Requirements: • Python 3.6 or later • pyserial module Install pyserial: $ pip install pyserial or $ pip3 install pyserial System Requirements: • Serial port access (Linux: /dev/ttyUSB*, macOS: /dev/cu.*, Windows: COM*) • User permissions for serial port access Linux serial port permissions: $ sudo usermod -a -G dialout $USER (then logout and login) Verify installation: $ python3 config_device.py --help ================================================================================ 3. QUICK START ================================================================================ Basic STA Mode Configuration: $ python3 config_device.py -p /dev/ttyUSB0 -i 192.168.1.81 Basic MONITOR Mode Configuration: $ python3 config_device.py -p /dev/ttyUSB0 -i 192.168.1.90 \\ -M MONITOR -mc 36 With verbose output: $ python3 config_device.py -p /dev/ttyUSB0 -i 192.168.1.81 -v ================================================================================ 4. COMMAND-LINE ARGUMENTS ================================================================================ REQUIRED ARGUMENTS ------------------ -p, --port PORT Serial port device Examples: /dev/ttyUSB0, /dev/ttyUSB1, COM3 Required: YES -i, --ip IP_ADDRESS Static IP address for the device DHCP is automatically disabled when using this script Examples: 192.168.1.81, 10.0.0.50 Required: YES OPTIONAL ARGUMENTS - WiFi Settings ----------------------------------- -s, --ssid SSID WiFi network name (SSID) Default: ClubHouse2G Example: -s "MyNetwork" -P, --password PASSWORD WiFi password Default: ez2remember Example: -P "MySecurePassword123" OPTIONAL ARGUMENTS - Network Settings -------------------------------------- -g, --gateway IP_ADDRESS Gateway IP address Default: 192.168.1.1 Example: -g 192.168.1.1 -m, --netmask NETMASK Network mask Default: 255.255.255.0 Example: -m 255.255.255.0 OPTIONAL ARGUMENTS - WiFi Configuration ---------------------------------------- -b, --band {2.4G,5G} WiFi frequency band Options: 2.4G - 2.4 GHz band (channels 1-11 in US) 5G - 5 GHz band (channels 36-165) Default: 2.4G Example: -b 5G -B, --bandwidth {HT20,HT40,VHT80} Channel bandwidth Options: HT20 - 20 MHz (2.4GHz or 5GHz) HT40 - 40 MHz (2.4GHz or 5GHz) VHT80 - 80 MHz (5GHz only) Default: HT20 Notes: • VHT80 requires 5GHz band (-b 5G) • Monitor mode forces 20MHz regardless of setting Example: -B HT40 -ps, --powersave {NONE,MIN,MIN_MODEM,MAX,MAX_MODEM} Power saving mode Options: NONE - No power saving (best for CSI, highest power) MIN - Minimum power save (alias for MIN_MODEM) MIN_MODEM - Minimum modem power save MAX - Maximum power save (alias for MAX_MODEM) MAX_MODEM - Maximum modem power save (lowest power) Default: NONE Recommendation: Use NONE for CSI capture and WiFi analysis Example: -ps NONE OPTIONAL ARGUMENTS - Operating Mode ------------------------------------ -M, --mode {STA,MONITOR} Operating mode Options: STA - Station mode (connect to AP, run iperf, CSI capture) MONITOR - Monitor mode (promiscuous WiFi packet capture) Default: STA Example: -M MONITOR -mc, --monitor-channel CHANNEL Monitor mode channel number Valid ranges: 2.4GHz: 1-11 (US) 5GHz: 36, 40, 44, 48 (UNII-1) 149, 153, 157, 161, 165 (UNII-3) Default: 36 Note: Only used when mode is MONITOR Example: -mc 149 OPTIONAL ARGUMENTS - Script Behavior ------------------------------------- -r, --no-reboot Do NOT reboot device after configuration Default: Device is rebooted automatically Use this flag to configure without rebooting Example: -r -v, --verbose Enable verbose output Shows detailed serial communication and debug information Example: -v -h, --help Show help message and exit ================================================================================ 5. USAGE EXAMPLES ================================================================================ BASIC EXAMPLES -------------- Example 1: Configure device for STA mode with defaults $ python3 config_device.py -p /dev/ttyUSB0 -i 192.168.1.81 Result: • SSID: ClubHouse2G • Password: ez2remember • IP: 192.168.1.81 • Mode: STA • Band: 2.4GHz • Bandwidth: 20MHz Example 2: Configure device for MONITOR mode on channel 36 $ python3 config_device.py -p /dev/ttyUSB0 -i 192.168.1.90 \\ -M MONITOR -mc 36 Result: • Device boots in STA mode to connect to WiFi • After GPS sync, auto-switches to MONITOR mode on channel 36 • Captures all WiFi traffic on channel 36 Example 3: 5GHz with 40MHz bandwidth, STA mode $ python3 config_device.py -p /dev/ttyUSB0 -i 192.168.1.81 \\ -s ClubHouse5G -b 5G -B HT40 Result: • Connects to ClubHouse5G SSID • Uses 5GHz band with 40MHz bandwidth • STA mode (default) Example 4: Custom WiFi credentials $ python3 config_device.py -p /dev/ttyUSB0 -i 192.168.1.81 \\ -s "MyNetwork" -P "MyPassword123" Result: • Connects to "MyNetwork" with password "MyPassword123" • Uses default 2.4GHz, 20MHz, STA mode Example 5: Configure without rebooting $ python3 config_device.py -p /dev/ttyUSB0 -i 192.168.1.81 -r Result: • Configuration saved to NVS • Device does NOT reboot • Must manually reboot to apply settings ADVANCED EXAMPLES ----------------- Example 6: MONITOR mode on 2.4GHz channel 6 $ python3 config_device.py -p /dev/ttyUSB0 -i 192.168.1.91 \\ -M MONITOR -mc 6 -b 2.4G Result: • Monitor mode on 2.4GHz channel 6 • Good for monitoring 2.4GHz WiFi collapse Example 7: Verbose output for debugging $ python3 config_device.py -p /dev/ttyUSB0 -i 192.168.1.81 -v Result: • Shows detailed serial communication • Displays all bytes sent/received • Useful for troubleshooting Example 8: Multiple channels for different devices $ python3 config_device.py -p /dev/ttyUSB0 -i 192.168.1.90 \\ -M MONITOR -mc 36 $ python3 config_device.py -p /dev/ttyUSB1 -i 192.168.1.91 \\ -M MONITOR -mc 40 $ python3 config_device.py -p /dev/ttyUSB2 -i 192.168.1.92 \\ -M MONITOR -mc 44 Result: • Device .90 monitors channel 36 • Device .91 monitors channel 40 • Device .92 monitors channel 44 • Comprehensive 5GHz band monitoring Example 9: Different network settings $ python3 config_device.py -p /dev/ttyUSB0 -i 10.0.0.100 \\ -g 10.0.0.1 -m 255.255.255.0 -s "OfficeWiFi" -P "Office2025" Result: • IP: 10.0.0.100 • Gateway: 10.0.0.1 • SSID: OfficeWiFi • Different network configuration ================================================================================ 6. OPERATING MODES ================================================================================ STA MODE (Station Mode) ----------------------- Purpose: Connect to WiFi access point as a client Use Cases: • iperf baseline testing • CSI (Channel State Information) capture • Network performance measurement • Standard WiFi connectivity Behavior: 1. Device connects to configured WiFi AP 2. Obtains configured static IP address 3. Runs iperf server on port 5001 4. Captures CSI data 5. Maintains WiFi connection 6. LED: Green (connected) Configuration: $ python3 config_device.py -p /dev/ttyUSB0 -i 192.168.1.81 -M STA Features Active in STA Mode: • WiFi connectivity • iperf server • CSI capture • GPS timestamping • Network services MONITOR MODE (Promiscuous Mode) -------------------------------- Purpose: Capture all WiFi packets on a specific channel Use Cases: • WiFi collapse detection • Network traffic analysis • Protocol debugging • Security research Behavior: 1. Device connects to WiFi AP initially (for GPS sync) 2. Gets static IP address 3. Waits for WiFi connection (LED: Green) 4. Waits 2 seconds for GPS sync 5. Switches to MONITOR mode on configured channel 6. Captures all WiFi packets on that channel 7. LED: Blue (monitoring) Configuration: $ python3 config_device.py -p /dev/ttyUSB0 -i 192.168.1.90 \\ -M MONITOR -mc 36 Features Active in MONITOR Mode: • Promiscuous packet capture • WiFi frame analysis (RTS/CTS/ACK/Beacon/Data) • GPS timestamping • CSI capture • No WiFi connectivity (after switch) Important Notes: • Monitor mode is read-only (no transmit) • Device disconnects from AP after switching to monitor • Monitor mode always uses 20MHz bandwidth (driver limitation) • Best for detecting WiFi collapse events ================================================================================ 7. CONFIGURATION PARAMETERS ================================================================================ STORED IN NVS (Non-Volatile Storage) ------------------------------------- The following parameters are stored in NVS and persist across reboots: | Parameter | NVS Key | Type | Default | Description | |------------|------------|---------|--------------|----------------------------| | SSID | ssid | string | ClubHouse2G | WiFi network name | | Password | pass | string | ez2remember | WiFi password | | IP Address | ip | string | (required) | Static IP address | | Netmask | mask | string | 255.255.255.0| Network mask | | Gateway | gw | string | 192.168.1.1 | Gateway IP | | DHCP | dhcp | bool | false | Always false (static IP) | | Band | band | string | 2.4G | WiFi band (2.4G or 5G) | | Bandwidth | bw | string | HT20 | Channel bandwidth | | PowerSave | powersave | string | NONE | Power save mode | | Mode | mode | string | STA | Operating mode | | Mon Ch | mon_ch | uint8_t | 36 | Monitor mode channel | BANDWIDTH OPTIONS ----------------- HT20 (20 MHz): • Compatible with: 2.4GHz and 5GHz • Maximum throughput: ~72 Mbps (802.11n) • Best for: Compatibility, monitor mode • Channels used: 1 channel HT40 (40 MHz): • Compatible with: 2.4GHz and 5GHz • Maximum throughput: ~150 Mbps (802.11n) • Best for: Higher throughput • Channels used: 2 adjacent channels • Note: Monitor mode forces to 20MHz VHT80 (80 MHz): • Compatible with: 5GHz only • Maximum throughput: ~433 Mbps (802.11ac) • Best for: Maximum throughput • Channels used: 4 adjacent channels • Note: Monitor mode forces to 20MHz • Requires: -b 5G CHANNEL SELECTION ----------------- 2.4GHz Channels (US): • Non-overlapping: 1, 6, 11 • All available: 1-11 • Bandwidth: 20MHz or 40MHz • Example: -mc 6 -b 2.4G 5GHz Channels (US): • UNII-1: 36, 40, 44, 48 (5.15-5.25 GHz) • UNII-2: 52, 56, 60, 64 (5.25-5.35 GHz, DFS) • UNII-2e: 100-144 (5.47-5.725 GHz, DFS) • UNII-3: 149, 153, 157, 161, 165 (5.725-5.85 GHz) • Bandwidth: 20MHz, 40MHz, or 80MHz • Example: -mc 36 -b 5G Recommended Monitor Channels: • 2.4GHz: 1, 6, 11 (non-overlapping) • 5GHz: 36, 149 (no DFS, always available) ================================================================================ 8. TROUBLESHOOTING ================================================================================ COMMON ISSUES ------------- Issue: "Serial error: [Errno 13] Permission denied: '/dev/ttyUSB0'" Solution: 1. Add user to dialout group: $ sudo usermod -a -G dialout $USER 2. Logout and login 3. Verify: $ groups | grep dialout Issue: "No response from device" Possible Causes: 1. Wrong serial port Solution: Check with: ls /dev/ttyUSB* 2. Another program using the port Solution: Close other programs (idf.py monitor, screen, minicom) 3. Wrong baud rate Solution: Script uses 115200 (correct for ESP32-C5) 4. Device not running config handler Solution: Flash latest firmware Issue: "Device got different IP than configured" Possible Causes: 1. DHCP still enabled (shouldn't happen with this script) Solution: Check device logs for "DHCP:0" 2. IP conflict on network Solution: Use different IP address 3. Router forcing DHCP Solution: Check router settings, reserve IP Issue: "VHT80 error" Message: "✗ Error: VHT80 (80MHz) is only supported on 5GHz band" Solution: • Use -b 5G with -B VHT80 • Or use -B HT20 or -B HT40 for 2.4GHz Issue: "Device not switching to MONITOR mode" Possible Causes: 1. WiFi not connected first Solution: Check logs for "WiFi CONNECTED" 2. GPS not syncing Solution: Wait 30-60 seconds for GPS lock 3. Wrong firmware version Solution: Flash latest firmware with auto_monitor_task Issue: "Configuration not persisting after reboot" Possible Causes: 1. NVS partition corrupted Solution: Erase flash and reconfigure: $ idf.py -p /dev/ttyUSB0 erase-flash $ idf.py -p /dev/ttyUSB0 flash $ python3 config_device.py -p /dev/ttyUSB0 -i 192.168.1.81 VERBOSE MODE DEBUGGING ---------------------- Enable verbose mode to see detailed information: $ python3 config_device.py -p /dev/ttyUSB0 -i 192.168.1.81 -v Verbose output shows: • Serial port settings • Bytes sent/received • Configuration message contents • Device response parsing • Error details with traceback SERIAL PORT VERIFICATION ------------------------- List available serial ports: Linux: $ ls -l /dev/ttyUSB* macOS: $ ls -l /dev/cu.* Windows: $ mode Test serial port communication: $ python3 -m serial.tools.miniterm /dev/ttyUSB0 115200 ================================================================================ 9. ADVANCED USAGE ================================================================================ BATCH CONFIGURATION ------------------- Configure multiple devices with a script: #!/bin/bash # configure_devices.sh # STA mode devices (.81-.89) for i in {81..89}; do port=$((i-81)) echo "Configuring device $i on /dev/ttyUSB$port (STA mode)" python3 config_device.py -p /dev/ttyUSB$port -i 192.168.1.$i -M STA sleep 2 done # MONITOR mode devices (.90-.98) for i in {90..98}; do port=$((i-81)) echo "Configuring device $i on /dev/ttyUSB$port (MONITOR mode)" python3 config_device.py -p /dev/ttyUSB$port -i 192.168.1.$i \\ -M MONITOR -mc 36 sleep 2 done Usage: $ chmod +x configure_devices.sh $ ./configure_devices.sh CONFIGURATION WITHOUT REBOOT ----------------------------- Use -r flag to configure without rebooting: $ python3 config_device.py -p /dev/ttyUSB0 -i 192.168.1.81 -r Then manually reboot later: • Press RESET button on device • Or use: idf.py -p /dev/ttyUSB0 monitor (then Ctrl+T, Ctrl+R) • Or power cycle MULTI-CHANNEL MONITORING ------------------------- Deploy devices across multiple channels: channels=(36 40 44 48 149 153 157 161) start_ip=90 for i in "${!channels[@]}"; do ch=${channels[$i]} ip=$((start_ip + i)) port=$i echo "Device $ip: Monitor channel $ch on /dev/ttyUSB$port" python3 config_device.py -p /dev/ttyUSB$port -i 192.168.1.$ip \\ -M MONITOR -mc $ch -b 5G done DIFFERENT POWER SAVE MODES --------------------------- Test different power save modes: # Device 1: No power save (best for CSI) python3 config_device.py -p /dev/ttyUSB0 -i 192.168.1.81 -ps NONE # Device 2: Minimum power save python3 config_device.py -p /dev/ttyUSB1 -i 192.168.1.82 -ps MIN # Device 3: Maximum power save python3 config_device.py -p /dev/ttyUSB2 -i 192.168.1.83 -ps MAX INTEGRATION WITH MONITORING SCRIPTS ------------------------------------ Configure device and start monitoring: #!/bin/bash # deploy_and_monitor.sh DEVICE_IP="192.168.1.90" PORT="/dev/ttyUSB0" # Configure device python3 config_device.py -p $PORT -i $DEVICE_IP -M MONITOR -mc 36 # Wait for reboot sleep 10 # Start monitoring idf.py -p $PORT monitor | tee device_90.log ================================================================================ 10. COMMON DEPLOYMENT SCENARIOS ================================================================================ SCENARIO 1: WIFI COLLAPSE DETECTION (32 devices) ------------------------------------------------- Goal: Detect WiFi collapse events and correlate with iperf degradation Setup: • 9 devices in STA mode (.81-.89) for iperf baseline • 9 devices in MONITOR mode (.90-.98) for collapse detection • All on 5GHz channel 36 Configuration: # STA devices for i in {81..89}; do python3 config_device.py -p /dev/ttyUSB$((i-81)) \\ -i 192.168.1.$i -M STA -b 5G -B HT20 -ps NONE done # MONITOR devices for i in {90..98}; do python3 config_device.py -p /dev/ttyUSB$((i-81)) \\ -i 192.168.1.$i -M MONITOR -mc 36 -b 5G done Data Collection: # Capture logs from all devices for i in {0..17}; do cat /dev/ttyUSB$i > logs/device_$((81+i)).log & done # Merge by GPS timestamp cat logs/*.log | sort -t'(' -k2 -n > merged.log SCENARIO 2: CHANNEL SURVEY (8 channels) ---------------------------------------- Goal: Monitor WiFi activity across multiple 5GHz channels Setup: • 8 devices in MONITOR mode on different channels • Comprehensive 5GHz band coverage Configuration: channels=(36 40 44 48 149 153 157 161) for i in "${!channels[@]}"; do python3 config_device.py -p /dev/ttyUSB$i \\ -i 192.168.1.$((90+i)) -M MONITOR -mc ${channels[$i]} -b 5G done SCENARIO 3: 2.4GHz vs 5GHz COMPARISON -------------------------------------- Goal: Compare WiFi behavior on 2.4GHz vs 5GHz Setup: • 4 devices on 2.4GHz channels 1, 6, 11 (MONITOR) • 4 devices on 5GHz channels 36, 149 (MONITOR) • 2 STA devices (1 on each band) Configuration: # 2.4GHz monitors for ch in 1 6 11; do python3 config_device.py -p /dev/ttyUSB$i \\ -i 192.168.1.$((90+i)) -M MONITOR -mc $ch -b 2.4G ((i++)) done # 5GHz monitors for ch in 36 149; do python3 config_device.py -p /dev/ttyUSB$i \\ -i 192.168.1.$((90+i)) -M MONITOR -mc $ch -b 5G ((i++)) done SCENARIO 4: POWER SAVE IMPACT TESTING -------------------------------------- Goal: Measure impact of power save modes on CSI quality Setup: • 3 devices with different power save modes • All in STA mode for CSI capture Configuration: python3 config_device.py -p /dev/ttyUSB0 -i 192.168.1.81 -ps NONE python3 config_device.py -p /dev/ttyUSB1 -i 192.168.1.82 -ps MIN python3 config_device.py -p /dev/ttyUSB2 -i 192.168.1.83 -ps MAX Compare CSI data quality across the three modes. ================================================================================ APPENDIX A: CONFIGURATION MESSAGE FORMAT ================================================================================ The script sends this message to the device over serial: CFG SSID:ClubHouse2G PASS:ez2remember IP:192.168.1.90 MASK:255.255.255.0 GW:192.168.1.1 DHCP:0 BAND:5G BW:HT20 POWERSAVE:NONE MODE:MONITOR MON_CH:36 END Device responds with: OK Then device logs: I (1234) wifi_cfg: Config saved to NVS: SSID=ClubHouse2G Mode=MONITOR MonCh=36... I (1234) wifi_cfg: Applying Wi-Fi config: ... ================================================================================ APPENDIX B: LED STATUS INDICATORS ================================================================================ | Color | Pattern | Meaning | |--------|----------|------------------------------------------| | Yellow | Solid | No WiFi config in NVS | | Blue | Blinking | Connecting to WiFi | | Green | Solid | Connected in STA mode | | Blue | Solid | MONITOR mode active | | Red | Blinking | Connection failed / Error | ================================================================================ APPENDIX C: QUICK REFERENCE CARD ================================================================================ Most Common Configurations: STA mode (default everything): $ python3 config_device.py -p /dev/ttyUSB0 -i 192.168.1.81 STA mode on 5GHz: $ python3 config_device.py -p /dev/ttyUSB0 -i 192.168.1.81 -b 5G MONITOR mode channel 36: $ python3 config_device.py -p /dev/ttyUSB0 -i 192.168.1.90 \\ -M MONITOR -mc 36 MONITOR mode 2.4GHz channel 6: $ python3 config_device.py -p /dev/ttyUSB0 -i 192.168.1.91 \\ -M MONITOR -mc 6 -b 2.4G Custom SSID/password: $ python3 config_device.py -p /dev/ttyUSB0 -i 192.168.1.81 \\ -s "MyWiFi" -P "MyPassword" Verbose debugging: $ python3 config_device.py -p /dev/ttyUSB0 -i 192.168.1.81 -v No reboot: $ python3 config_device.py -p /dev/ttyUSB0 -i 192.168.1.81 -r ================================================================================ END OF MANUAL ================================================================================ For more information and updates: • See NVS_MODE_CONFIGURATION_GUIDE.md • See QUICK_DEPLOYMENT_REFERENCE.md • See WIFI_CFG_CHANGES_DETAILED.md Version: 2.0 Last Updated: December 2025