ESP32/doc/MASS_DEPLOY.md

364 lines
7.5 KiB
Markdown

# 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 <ssid> -p <password>
```
### iperf Commands
```bash
# 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:
```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
```