364 lines
7.5 KiB
Markdown
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
|
|
```
|