7.5 KiB
7.5 KiB
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
# 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
- Connect all ESP32 devices to USB hubs
- Verify detection:
cd ~/Code/esp32/esp32-iperf python3 detect_esp32.py
Flash All Devices
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:
- Detects chip type (ESP32/ESP32-S2/ESP32-S3)
- Calculates unique IP address (increments from start IP)
- Creates custom sdkconfig.defaults with WiFi and IP settings
- Sets the correct target (esp32/esp32s2/esp32s3)
- Builds firmware with custom configuration
- 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
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
# 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
# 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:
#!/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
# 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
# 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
#!/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
# 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
# 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
# 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
# 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 <ssid> -p <password>
iperf Commands
# TCP server
iperf -s
# TCP client
iperf -c <ip>
# UDP server
iperf -s -u
# UDP client
iperf -c <ip> -u
# Custom port
iperf -s -p 5002
# Custom duration
iperf -c <ip> -t 30
# Stop running test
iperf -a
Advanced: Parallel Flashing
To flash multiple devices simultaneously:
#!/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
- Prepare: Connect all devices, verify detection
- Flash: Run mass flash script with dry-run first
- Verify: Ping all IPs to confirm connectivity
- Test: Run iperf from PC to each device
- Deploy: Mount devices in test locations
- 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