# Mass ESP32 Deployment Guide Complete guide for flashing 32+ ESP32 devices with unique static IPs. ## Overview This system allows you to: - Flash multiple ESP32/ESP32-S2/ESP32-S3 devices automatically - Assign unique static IP addresses to each device (192.168.1.50-192.168.1.81) - Configure WiFi credentials during build - Reconfigure WiFi after flashing via console ## Prerequisites ```bash # Install Python dependencies pip install pyserial # Ensure ESP-IDF is installed with all targets cd ~/Code/esp32/esp-idf ./install.sh esp32,esp32s2,esp32s3 # Activate ESP-IDF environment . ~/Code/esp32/esp-idf/export.sh ``` ## Method 1: Automated Mass Flash (Recommended) ### Prepare Your Devices 1. Connect all ESP32 devices to USB hubs 2. Verify detection: ```bash cd ~/Code/esp32/esp32-iperf python3 detect_esp32.py ``` ### Flash All Devices ```bash cd ~/Code/esp32/esp32-iperf # Dry run to see the plan python3 flash_all.py \ --ssid "YourWiFiSSID" \ --password "YourPassword" \ --start-ip 192.168.1.50 \ --gateway 192.168.1.1 \ --dry-run # Actually flash (this will take a while!) python3 flash_all.py \ --ssid "YourWiFiSSID" \ --password "YourPassword" \ --start-ip 192.168.1.50 \ --gateway 192.168.1.1 # With chip probing (slower but more accurate) python3 flash_all.py \ --ssid "YourWiFiSSID" \ --password "YourPassword" \ --start-ip 192.168.1.50 \ --probe ``` ### Script Options - `--ssid`: WiFi network name (required) - `--password`: WiFi password (required) - `--start-ip`: Starting IP address (default: 192.168.1.50) - `--gateway`: Gateway IP (default: 192.168.1.1) - `--probe`: Probe each device to detect exact chip type (slower) - `--dry-run`: Show plan without flashing - `--project-dir`: Custom project directory ### What the Script Does For each device: 1. Detects chip type (ESP32/ESP32-S2/ESP32-S3) 2. Calculates unique IP address (increments from start IP) 3. Creates custom sdkconfig.defaults with WiFi and IP settings 4. Sets the correct target (esp32/esp32s2/esp32s3) 5. Builds firmware with custom configuration 6. Flashes the device ## Method 2: Manual Configuration Per Device If you want to flash devices one at a time or need custom settings: ### Create sdkconfig.defaults ```bash cd ~/Code/esp32/esp32-iperf cat > sdkconfig.defaults << EOF # WiFi Configuration CONFIG_WIFI_SSID="YourSSID" CONFIG_WIFI_PASSWORD="YourPassword" CONFIG_WIFI_MAXIMUM_RETRY=5 # Static IP Configuration CONFIG_USE_STATIC_IP=y CONFIG_STATIC_IP_ADDR="192.168.1.50" CONFIG_STATIC_GATEWAY_ADDR="192.168.1.1" CONFIG_STATIC_NETMASK_ADDR="255.255.255.0" EOF ``` ### Build and Flash ```bash # Set target (choose one) idf.py set-target esp32 # for ESP32 idf.py set-target esp32s2 # for ESP32-S2 idf.py set-target esp32s3 # for ESP32-S3 # Build idf.py build # Flash to specific device idf.py -p /dev/ttyUSB0 flash monitor # For next device, edit sdkconfig.defaults with new IP # Then clean and rebuild idf.py fullclean # ... edit sdkconfig.defaults ... idf.py build idf.py -p /dev/ttyUSB1 flash ``` ## Method 3: Reconfigure After Flashing If devices are already flashed but need different WiFi credentials: ### Via Console ```bash # Connect to device idf.py -p /dev/ttyUSB0 monitor # At the prompt iperf> wifi -s "NewSSID" -p "NewPassword" ``` ### Via Script (Multiple Devices) Create a script to update all devices: ```bash #!/bin/bash for port in /dev/ttyUSB{0..31}; do echo "Updating $port..." # Send commands via screen or minicom screen -S esp_config $port 115200 -X stuff "wifi -s \"NewSSID\" -p \"NewPassword\"\n" done ``` ## IP Address Assignment Based on your 32 detected devices: ``` Device 1 -> /dev/ttyUSB0 -> 192.168.1.50 Device 2 -> /dev/ttyUSB1 -> 192.168.1.51 Device 3 -> /dev/ttyUSB2 -> 192.168.1.52 ... Device 32 -> /dev/ttyUSB31 -> 192.168.1.81 ``` ## Testing Your Deployment ### Check Device Connectivity ```bash # Ping all devices for i in {50..81}; do ping -c 1 -W 1 192.168.1.$i && echo "192.168.1.$i is UP" || echo "192.168.1.$i is DOWN" done ``` ### Run iperf Tests ```bash # Start all devices as iperf servers # (via console on each device) iperf> iperf -s # From your PC, test each device for i in {50..81}; do echo "Testing 192.168.1.$i" iperf -c 192.168.1.$i -t 5 done ``` ### Batch iperf Test Script ```python #!/usr/bin/env python3 import subprocess import sys start_ip = "192.168.1.50" end_ip = "192.168.1.81" base = start_ip.rsplit('.', 1)[0] start = int(start_ip.rsplit('.', 1)[1]) end = int(end_ip.rsplit('.', 1)[1]) results = [] for i in range(start, end + 1): ip = f"{base}.{i}" print(f"Testing {ip}...", end=' ', flush=True) result = subprocess.run( ['iperf', '-c', ip, '-t', '5', '-f', 'm'], capture_output=True, text=True, timeout=10 ) if result.returncode == 0: # Parse bandwidth from output for line in result.stdout.split('\n'): if 'Mbits/sec' in line: bandwidth = line.split()[-2] print(f"✓ {bandwidth} Mbits/sec") results.append((ip, bandwidth)) break else: print("✗ FAILED") print(f"\nTested {len(results)}/{end-start+1} devices successfully") ``` ## Troubleshooting ### Device Not Detected ```bash # Check USB connection lsusb # Check permissions sudo usermod -a -G dialout $USER # Log out and back in # Check if port exists ls -la /dev/ttyUSB* ``` ### Flash Failed ```bash # Try holding BOOT button during flash idf.py -p /dev/ttyUSB0 flash # Lower baud rate idf.py -p /dev/ttyUSB0 -b 115200 flash # Erase flash first idf.py -p /dev/ttyUSB0 erase-flash idf.py -p /dev/ttyUSB0 flash ``` ### WiFi Not Connecting ```bash # Monitor the device idf.py -p /dev/ttyUSB0 monitor # Check logs for WiFi errors # Try reconfiguring via console: iperf> wifi -s "YourSSID" -p "YourPassword" ``` ### IP Address Conflict ```bash # Check what's using the IP ping 192.168.1.50 arp -a | grep 192.168.1.50 # Reflash with different IP range python3 flash_all.py \ --ssid "YourSSID" \ --password "YourPassword" \ --start-ip 192.168.1.100 ``` ## Console Commands Reference ### WiFi Configuration ``` wifi -s -p ``` ### iperf Commands ```bash # TCP server iperf -s # TCP client iperf -c # UDP server iperf -s -u # UDP client iperf -c -u # Custom port iperf -s -p 5002 # Custom duration iperf -c -t 30 # Stop running test iperf -a ``` ## Advanced: Parallel Flashing To flash multiple devices simultaneously: ```bash #!/bin/bash # flash_parallel.sh # Flash 4 devices at once idf.py -p /dev/ttyUSB0 flash & idf.py -p /dev/ttyUSB1 flash & idf.py -p /dev/ttyUSB2 flash & idf.py -p /dev/ttyUSB3 flash & wait echo "Batch complete" ``` Note: Each device still needs its own build with unique IP. ## Production Deployment Workflow 1. **Prepare**: Connect all devices, verify detection 2. **Flash**: Run mass flash script with dry-run first 3. **Verify**: Ping all IPs to confirm connectivity 4. **Test**: Run iperf from PC to each device 5. **Deploy**: Mount devices in test locations 6. **Monitor**: Use iperf console to run tests ## File Structure ``` esp32-iperf/ ├── main/ │ ├── main.c # Main app with WiFi │ ├── iperf.c # iperf implementation │ ├── iperf.h # iperf header │ └── Kconfig.projbuild # Configuration options ├── CMakeLists.txt ├── README.md ├── flash_all.py # Mass flash script ├── detect_esp32.py # Device detection └── sdkconfig.defaults # Auto-generated config ```