ESP32 WiFi provisioning with SmartConfig and Bluetooth setup solves a critical problem for deployed IoT products: how does a device in a customer’s home connect to their WiFi without a screen or keyboard? This tutorial covers ESP32’s SmartConfig, BLE provisioning, and SoftAP methods with complete Arduino code.
Table of Contents
- Why WiFi Provisioning Matters
- SmartConfig (ESP-Touch)
- BLE WiFi Provisioning
- SoftAP Provisioning
- Saving Credentials in NVS
- Indian IoT Product Context
- Frequently Asked Questions
Why WiFi Provisioning Matters
Every Indian household has a unique WiFi SSID and password. A deployed IoT product (smart plug, sensor, home automation relay) cannot be hard-coded with these credentials — it must be configured in the field. The provisioning experience (how easy it is for an Indian consumer to set up your device) directly affects product ratings, returns, and support calls.
ESP32 offers three built-in provisioning methods: SmartConfig (smartphone app sends SSID/password over WiFi), BLE provisioning (credentials via Bluetooth app), and SoftAP (device creates a temporary WiFi hotspot for configuration).
SmartConfig (ESP-Touch)
SmartConfig works by having the smartphone app send WiFi credentials via UDP broadcast packets. The ESP32 listens in monitor mode and extracts credentials from packet timing patterns.
#include "WiFi.h"
void startSmartConfig() {
WiFi.mode(WIFI_STA);
WiFi.beginSmartConfig();
Serial.println("Waiting for SmartConfig...");
// Timeout after 5 minutes
unsigned long timeout = millis();
while (!WiFi.smartConfigDone()) {
delay(500);
Serial.print(".");
if (millis() - timeout > 300000) {
Serial.println("SmartConfig timeout");
WiFi.stopSmartConfig();
return;
}
}
Serial.println("SmartConfig complete!");
// Wait for actual WiFi connection
while (WiFi.status() != WL_CONNECTED) {
delay(500);
}
Serial.print("Connected! IP: ");
Serial.println(WiFi.localIP());
// Save credentials to NVS
saveCredentials(WiFi.SSID(), WiFi.psk());
}
Indian users need the ESP-Touch app (Espressif’s official app, available on Play Store and App Store free) to use SmartConfig. Works on Android and iOS.
BLE WiFi Provisioning
Espressif’s WiFi Provisioning component uses BLE to send credentials. This method is more reliable than SmartConfig and doesn’t depend on WiFi monitor mode (which doesn’t work with some 5 GHz only networks).
#include <wifi_provisioning/manager.h>
#include <wifi_provisioning/scheme_ble.h>
// This uses ESP-IDF component, easier via PlatformIO/ESP-IDF
void start_ble_provisioning() {
wifi_prov_mgr_config_t config = {
.scheme = wifi_prov_scheme_ble,
.scheme_event_handler = WIFI_PROV_SCHEME_BLE_EVENT_HANDLER_FREE_BTDM
};
wifi_prov_mgr_init(config);
bool provisioned = false;
wifi_prov_mgr_is_provisioned(&provisioned);
if (!provisioned) {
// Generate BLE device name: "PROV_XXXX"
uint8_t mac[6];
esp_wifi_get_mac(WIFI_IF_STA, mac);
char service_name[12];
snprintf(service_name, 12, "PROV_%02X%02X", mac[4], mac[5]);
wifi_prov_mgr_start_provisioning(
WIFI_PROV_SECURITY_1, // Encrypted
"abcd1234", // POP (Proof of Possession) - like a PIN
service_name,
NULL
);
} else {
wifi_prov_mgr_deinit();
// Connect with saved credentials
}
}
SoftAP Provisioning
SoftAP is the most universally compatible method — ESP32 creates a temporary WiFi hotspot, user connects with smartphone, opens a web page, enters WiFi credentials. No special app needed.
#include <WiFi.h>
#include <WebServer.h>
WebServer server(80);
const char* AP_SSID = "ESP32-Setup-12AB"; // Unique per device
const char* AP_PASS = "setup1234";
void startSoftAPProvisioning() {
WiFi.mode(WIFI_AP);
WiFi.softAP(AP_SSID, AP_PASS);
server.on("/", []() {
server.send(200, "text/html", R"(
WiFi Setup
SSID:
Password:
)");
});
server.on("/save", HTTP_POST, []() {
String ssid = server.arg("ssid");
String pass = server.arg("pass");
saveCredentials(ssid, pass);
server.send(200, "text/plain", "Saved! Rebooting...");
delay(1000);
ESP.restart();
});
server.begin();
}
Saving Credentials in NVS
#include <Preferences.h>
Preferences prefs;
void saveCredentials(String ssid, String pass) {
prefs.begin("wifi", false);
prefs.putString("ssid", ssid);
prefs.putString("pass", pass);
prefs.end();
}
bool loadAndConnect() {
prefs.begin("wifi", true); // Read-only
String ssid = prefs.getString("ssid", "");
String pass = prefs.getString("pass", "");
prefs.end();
if (ssid.length() == 0) return false;
WiFi.begin(ssid.c_str(), pass.c_str());
unsigned long timeout = millis();
while (WiFi.status() != WL_CONNECTED && millis() - timeout < 15000)
delay(500);
return WiFi.status() == WL_CONNECTED;
}
Indian IoT Product Context
For Indian consumer IoT products (smart switches, smart bulbs, air quality monitors), SoftAP provisioning is most reliable because Indian consumers are familiar with connecting to a WiFi network. BLE provisioning is growing with app-based products. SmartConfig is less popular due to app download requirement and occasional 5 GHz compatibility issues with newer Indian routers.
Frequently Asked Questions
Does SmartConfig work with 5 GHz WiFi?
No. ESP32’s WiFi is 2.4 GHz only. SmartConfig requires the phone and ESP32 to be on the same WiFi network type. If your router broadcasts 2.4 GHz and 5 GHz as the same SSID (band steering), ensure your phone is on 2.4 GHz during SmartConfig setup.
How do I reset WiFi credentials on a deployed ESP32?
A long-press button on GPIO 0 (or any dedicated reset button) that erases NVS WiFi namespace and restarts into provisioning mode is standard. Expose this in product instructions for Indian customer support.
Can I use WPS (WiFi Protected Setup) on ESP32?
WPS support was removed from ESP32 Arduino due to security concerns. Use SoftAP or BLE provisioning instead for Indian consumer products.
Add comment