WiFi Provisioning

Quick Start

  1. Power on ESP32 with no stored WiFi credentials

  2. Device starts SoftAP called ESP32-Setup (open network)

  3. Connect your laptop/phone to ESP32-Setup WiFi

  4. Open browser to http://192.168.4.1/

  5. Enter your WiFi SSID and password

  6. Device saves credentials and restarts

  7. Next boot: automatically connects to your configured WiFi

System Overview

The provisioning system eliminates the need for:

  • Hardcoded WiFi credentials in source code

  • Manual menuconfig every build

  • Terminal-based setup procedures

  • Editing code for different WiFi networks

Instead, users provision via a simple web form on first boot.

How It Works

Boot Detection

PowerOn
  ↓
NVS Init (read from flash)
  ↓
Check SSID/Password in NVS
  ├─ EMPTY? → Start SoftAP + HTTP server
  └─ FOUND? → Connect to WiFi (normal operation)

The system checks if WiFi credentials exist in the NVS flash partition before attempting to connect. If empty, provisioning mode is activated.

SoftAP (Access Point Mode)

When credentials are missing, the device becomes a WiFi access point:

  • SSID: ESP32-Setup

  • Security: Open (no password required)

  • IP Range: 192.168.4.0/24

  • Gateway: 192.168.4.1 (device IP)

Clients automatically receive an IP via DHCP.

HTTP Provisioning Server

A lightweight HTTP server hosts a provisioning form:

GET / Returns HTML form with two inputs: - WiFi SSID (text field, max 32 chars) - WiFi Password (password field, max 63 chars)

POST /provision Accepts form submission with: - ssid parameter: Network name - password parameter: Network password

Server validates input and saves to NVS if successful.

NVS Storage

Credentials are stored persistently in the NVS (Non-Volatile Storage) partition:

  • Namespace: "wifi_creds"

  • SSID Key: "ssid"

  • Password Key: "password"

  • Persistence: Survives power cycles, resets, and reboots

Once stored, credentials are automatically loaded on boot and used for normal WiFi station mode.

Fallback to Kconfig

If NVS is empty or doesn’t exist, the system falls back to compile-time defaults:

#ifdef CONFIG_ESP_WIFI_SSID
#define WIFI_SSID CONFIG_ESP_WIFI_SSID
#else
#define WIFI_SSID ""
#endif

This allows a default configuration while maintaining the provisioning system.

For End Users

First Time Setup

  1. Plug in device (ESP32 board)

  2. Wait 10 seconds for boot to complete

  3. On your phone/laptop, look for WiFi network ESP32-Setup

  4. Connect to it (no password needed)

  5. Open web browser and navigate to http://192.168.4.1/

  6. Fill in your home WiFi name and password

  7. Click “Connect”

  8. Device will restart and connect to your WiFi

  9. Done! Device is now ready to use

Resetting Credentials

To erase stored credentials and start provisioning again:

# From host with device plugged in:
cd /micro_ros_ws/firmware/freertos_apps/microros_esp32_extensions
source /micro_ros_ws/firmware/toolchain/esp-idf/export.sh
idf.py erase-flash      # Erases entire flash, including NVS
idf.py flash            # Re-flashes firmware
# Device boots with empty credentials → starts provisioning mode again

Changing WiFi Networks

Method 1 (Easiest): Erase and reflash (see above)

Method 2 (Advanced): Manually erase NVS partition only:

idf.py erase-flash NVS  # Erases just the NVS partition
# Device boots with empty credentials → starts provisioning mode again

For Developers

Integration Points

The provisioning system is implemented in appMain() with these key functions:

nvs_read_wifi_creds()

Reads stored SSID and password from NVS

nvs_write_wifi_creds()

Writes SSID and password to NVS

start_softap()

Initializes WiFi in AP mode with SSID ESP32-Setup

start_provisioning_server()

Launches HTTP server with GET and POST handlers

stop_provisioning_server()

Cleanly shuts down HTTP server after provisioning

HTTP Handlers

get_handler()

Serves HTML form for SSID/password input

post_handler()

Parses form data, validates, writes to NVS, restarts device

Customization

Default SoftAP SSID (in start_softap()):

.ssid = "ESP32-Setup",

Change this to customize the network name visible to users.

HTML form styling and layout (in get_handler()):

const char* html_form = "<!DOCTYPE html>...";

Modify this string to customize the provisioning UI.

Post-provisioning timeout (in appMain()):

for (int i = 0; i < 60; i++) {  // 60 seconds
    if (provisioning_server == NULL) break;
    vTaskDelay(pdMS_TO_TICKS(1000));
}

Increase the loop count to allow more time for user input.

Testing Provisioning Manually

Simulate the provisioning flow without hardware:

  1. Erase credentials to start provisioning mode

  2. Monitor serial output to see SoftAP startup

  3. Connect to ESP32-Setup with a mobile device

  4. Open HTTP form in browser

  5. Supply test credentials and verify POST data in logs

  6. Confirm NVS write via nvs_read_wifi_creds() on next boot

Security Considerations

Open Access Point

The SoftAP has no password to simplify first-time setup for non-technical users. Deploy this only in trusted networks (e.g., lab, personal use).

Plaintext Credentials Over HTTP

Provisioning form is transmitted over plain HTTP (no HTTPS/TLS). For sensitive deployments, consider adding: - Basic authentication on GET / - HTTPS with self-signed certificate - Time-limited provisioning window (already implemented: 60s timeout)

NVS Storage

Credentials are stored in flash without encryption. Access is controlled by file permissions on the NVS partition. For high-security applications: - Use ESP32 secure boot and flash encryption - Store encrypted credentials in partition

Network Isolation

The SoftAP runs in open mode. Isolate the provisioning phase: - Keep provisioning timeout short (60 seconds default) - Disable SoftAP after credentials are saved - Use firewalls to restrict device access post-provisioning

Common Issues

No SoftAP visible on first boot
  • Device only starts SoftAP if credentials are empty or missing

  • Check NVS earlier boot has stored credentials

  • Verify WiFi radio is functional

Can’t reach http://192.168.4.1/
  • Ensure you’re connected to the correct network: ESP32-Setup

  • Try http://192.168.4.1:80/ explicitly

  • Check device IP: some phones assign different IPs (check Settings)

Credentials saved but device won’t connect
  • Verify WiFi is 2.4 GHz (not 5 GHz)

  • Confirm no extra spaces in SSID or password

  • Check network uses WPA2, not legacy WEP or open

Form submission hangs or times out
  • Check device logs for POST handler errors

  • Ensure NVS partition has space (not full)

  • Try clearing all NVS and rebooting

API Reference

// Read credentials from NVS
esp_err_t nvs_read_wifi_creds(char *ssid_out, char *pass_out);
// Parameters:
//   ssid_out: pointer to buffer (64 bytes), receives stored SSID
//   pass_out: pointer to buffer (64 bytes), receives stored password
// Returns: ESP_OK on success, error code otherwise
// Write credentials to NVS
esp_err_t nvs_write_wifi_creds(const char *ssid, const char *password);
// Parameters:
//   ssid: SSID to store (max 32 chars)
//   password: password to store (max 63 chars)
// Returns: ESP_OK on success, error code otherwise
// Start SoftAP for provisioning
void start_softap(void);
// Initializes WiFi in AP mode, starts SSID "ESP32-Setup"
// Must be called before start_provisioning_server()
// Start HTTP provisioning server
void start_provisioning_server(void);
// Registers GET / and POST /provision handlers
// Requires SoftAP to be running
// Stop HTTP provisioning server
void stop_provisioning_server(void);
// Cleanly shuts down httpd and frees resources