ESP32 Wi-Fi Provisioning via BLE: Easy to change WiFi credentials

ESP32 Wi-Fi Provisioning via BLE Easy to change WiFi credentials ESP32 Wi-Fi Provisioning via BLE Easy to change WiFi credentials

Setting up Wi-Fi connectivity on ESP32 devices has traditionally required hardcoding network credentials or implementing complex configuration interfaces. ESP32 Wi-Fi provisioning via Bluetooth Low Energy (BLE) revolutionizes this process, offering a seamless, user-friendly solution that eliminates the need for manual configuration files or web-based setup portals.

In this comprehensive guide, you’ll learn everything about implementing BLE-based Wi-Fi provisioning on ESP32 devices, from basic concepts to advanced implementation techniques that professional IoT developers use in production environments.

Check our another method using WiFi Manager: Change WiFi Credentials without uploading code again

What is ESP32 Wi-Fi Provisioning?

ESP32 Wi-Fi provisioning is the process of securely configuring network credentials on ESP32 devices without requiring hardcoded Wi-Fi settings. This dynamic configuration method allows end-users to connect their IoT devices to any Wi-Fi network through a simple mobile app interface, eliminating the technical complexity traditionally associated with IoT device setup.

The provisioning process transforms the ESP32 into a temporarily accessible device that can receive network configuration data through various communication channels, with Bluetooth Low Energy being the most efficient and user-friendly option available in 2025.

Key Benefits of Wi-Fi Provisioning

Simplified User Experience: End-users can configure devices without technical knowledge or accessing configuration files.

Enhanced Security: Credentials are transmitted securely using encryption protocols, preventing unauthorized access during the setup process.

Scalability: Manufacturers can deploy thousands of devices without pre-configuring each unit for specific networks.

Flexibility: Devices can be easily reconfigured for different networks without firmware modifications.

Cost Reduction: Eliminates the need for physical configuration interfaces like LCD screens or button combinations.

The Traditional Problem

Before Wi-Fi provisioning, developers faced several challenges:

  • Hard-coded credentials: Network information was permanently embedded in the code
  • Inflexible deployment: Devices couldn’t adapt to different network environments
  • Security vulnerabilities: Credentials were visible in source code
  • Maintenance nightmares: Changing networks required firmware updates

Why Choose BLE Over Other Provisioning Methods?

When comparing ESP32 provisioning methods, Bluetooth Low Energy stands out as the superior choice for modern IoT applications. Here’s a detailed comparison of available options:

BLE vs. SoftAP Provisioning

SoftAP Method Limitations:

  • Requires users to manually switch Wi-Fi networks on their devices
  • Creates temporary network congestion
  • Limited range and connection stability
  • Potential security vulnerabilities during the setup process
  • Poor user experience with multiple network switching steps

BLE Advantages:

  • No network switching required on user devices
  • Lower power consumption during provisioning
  • More reliable connection establishment
  • Enhanced security with built-in encryption
  • Seamless integration with modern mobile applications
  • Superior range and stability compared to SoftAP

Power Consumption Analysis

BLE provisioning consumes approximately 40% less power than SoftAP methods during the configuration process. This efficiency gain is crucial for battery-powered IoT devices where every milliwatt matters.

Method Average Power Draw Provisioning Time User Steps
BLE 45mA 15-30 seconds 3 steps
SoftAP 75mA 45-90 seconds 7 steps
Serial 35mA Manual process Technical expertise required

How Wi-Fi Provisioning via BLE Works

The ESP32 acts as a BLE server, broadcasting a provisioning service. A smartphone app (client) connects to the ESP32, sends the SSID and password, and triggers the device to join the Wi-Fi network. Here’s a breakdown:

  1. ESP32 Initialization: The board boots in BLE mode, awaiting credentials.

  2. Smartphone Pairing: A user connects via an app (e.g., Espressif’s Provisioning App).

  3. Credential Transfer: The app sends encrypted SSID/password data over BLE.

  4. Wi-Fi Connection: ESP32 uses the credentials to connect to the network.

  5. Persistent Storage: Credentials are saved in Non-Volatile Storage (NVS) for future use.

Step-by-Step Implementation Guide

Prerequisites

Before starting, gather these components:

  • Hardware:

    • ESP32 development board (e.g., ESP32 DevKit V1, ESP32 C3, ESP32 S3).

    • USB cable for power and programming.

    • Smartphone (Android/iOS) with BLE support.

  • Software:

    • Arduino IDE (v2.0+ recommended).

    • ESP32 Board Package (installed via Arduino Board Manager).

    • WiFiProv library (included in ESP32 core).

Step 1: Arduino IDE Code Setup

Open Arduino IDE: Create a new sketch, you can import the default examples from the Arduino IDE from File->Examples->WiFiProV or copy our customized code below which remembers the Wi-Fi credentials and connect to it automatically after booting. It only opens Provision service when Wi-Fi network is not connected.

Note: This sketch takes up a lot of space for the app and may not be able to flash with default setting on some chips. If you see Error like this: “Sketch too big”.

In Arduino IDE go to: Tools > Partition scheme > chose anything that has more than 1.4MB APP – for example “No OTA (2MB APP/2MB SPIFFS)”

#include <WiFi.h>
#include "WiFiProv.h"
#include "WiFi.h"

const char * pop = "abcd1234"; // Proof of possession - BLE PIN - string provided by the device, entered by user in the phone app
const char * service_name = "PROV_123"; // Name of your device to be displayed on BLE
const char * service_key = NULL; // Password used for SofAP method (NULL = no password needed)
bool reset_provisioned = false; // When true the library will automatically delete previously provisioned data.
bool wifi_connected = 0;

void SysProvEvent(arduino_event_t *sys_event)
{
  switch (sys_event->event_id) {
    case ARDUINO_EVENT_WIFI_STA_GOT_IP:
      Serial.print("\nConnected IP address : ");
      Serial.println(IPAddress(sys_event->event_info.got_ip.ip_info.ip.addr));
      wifi_connected = 1;
      break;
    case ARDUINO_EVENT_WIFI_STA_DISCONNECTED:
      Serial.println("\nDisconnected. Connecting to the AP again... ");
      wifi_connected = 0;
      break;
    case ARDUINO_EVENT_PROV_START:
      Serial.println("\nProvisioning started\nGive Credentials of your access point using smartphone app");
      break;
    case ARDUINO_EVENT_PROV_CRED_RECV: {
        Serial.println("\nReceived Wi-Fi credentials");
        Serial.print("\tSSID : ");
        Serial.println((const char *) sys_event->event_info.prov_cred_recv.ssid);
        Serial.print("\tPassword : ");
        Serial.println((char const *) sys_event->event_info.prov_cred_recv.password);
        break;
      }
    case ARDUINO_EVENT_PROV_CRED_FAIL: {
        Serial.println("\nProvisioning failed!\nPlease reset to factory and retry provisioning\n");
        if (sys_event->event_info.prov_fail_reason == WIFI_PROV_STA_AUTH_ERROR)
          Serial.println("\nWi-Fi AP password incorrect");
        else
          Serial.println("\nWi-Fi AP not found....Add API \" nvs_flash_erase() \" before beginProvision()");
        break;
      }
    case ARDUINO_EVENT_PROV_CRED_SUCCESS:
      Serial.println("\nProvisioning Successful");
      break;
    case ARDUINO_EVENT_PROV_END:
      Serial.println("\nProvisioning Ends");
      break;
    default:
      break;
  }
}

void setup()
{
  Serial.begin(115200);
  delay(10);

  WiFi.onEvent(SysProvEvent);
  pinMode(0, INPUT);

  Serial.println("Begin Provisioning using BLE");
  // Sample uuid that user can pass during provisioning using BLE
  uint8_t uuid[16] = {0xb4, 0xdf, 0x5a, 0x1c, 0x3f, 0x6b, 0xf4, 0xbf,
                      0xea, 0x4a, 0x82, 0x03, 0x04, 0x90, 0x1a, 0x02
                     };
  WiFiProv.beginProvision(WIFI_PROV_SCHEME_BLE, WIFI_PROV_SCHEME_HANDLER_FREE_BTDM, WIFI_PROV_SECURITY_1, pop, service_name, service_key, uuid, reset_provisioned);

  log_d("ble qr");
  WiFiProv.printQR(service_name, pop, "ble");
}

void loop() {
 

  if (wifi_connected)
  {
    Serial.println("connected to wifi and program running");
    //enter the code below to work when Wi-Fi is connected
  }

  else
  {
    Serial.println("Waiting For WiFi");
    delay(1000);
  }

  if (digitalRead(0) == LOW)
  {
    Serial.println("Reset Button Pressed");
    delay(5000);

    if (digitalRead(0) == LOW) {
      Serial.println("Resetting");
      wifi_prov_mgr_reset_provisioning();
      ESP.restart();
    }
  }
}

Code Breakdown:

1. Includes & Global Variables

  • WiFiProv.hWiFi.h: Libraries for Wi-Fi and provisioning.
  • pop: BLE PIN (Proof of Possession) for secure provisioning.
  • service_name: BLE device name shown on phone.
  • reset_provisioned = false: Keeps previously saved credentials.
  • wifi_connected: Tracks Wi-Fi connection status.

2. SysProvEvent()

Handles various Wi-Fi and provisioning events:

  • Prints IP when connected.
  • Shows status messages for provisioning start, success, fail.
  • On credential fail, advises erasing NVS (nvs_flash_erase()).
  • Sets wifi_connected flag accordingly.

3. setup()

  • Starts Serial output.
  • Attaches the event handler SysProvEvent.
  • Sets pin 0 as input (used as reset button).
  • Starts BLE provisioning with a UUID.
  • Prints a QR code for the phone app to scan and begin provisioning.

4. loop()

  • Checks Wi-Fi connection:
    • If connected: prints “connected” and space for main program logic.
    • If not connected: prints “waiting” every second.
  • Monitors pin 0 (usually boot button on ESP32):
    • If pressed for 5 seconds → calls wifi_prov_mgr_reset_provisioning() and restarts to erase Wi-Fi credentials and re-provision.

Step 2: Upload the Code

  1. Connect the ESP32 to your computer.
  2. Select Tools > Board > ESP32 Dev Module.
  3. Choose the correct Port.
  4. Select Tools > Partition scheme > No OTA (2MB APP/2MB SPIFFS)
  5. Click Upload.

Troubleshooting Tip: If upload fails, hold the BOOT button while clicking Upload.


Step 3: Install the Wi-Fi Provisioning App

Espressif’s official app simplifies the process:

Alternative: Advanced users can build custom apps using Web Bluetooth or libraries like Flutter.


Step 4: Provision via Smartphone App

ESP BLE provision app connection steps

  1. Open the ESP BLE Provisioning App.
  2. Scan for Devices: Tap “Scan” and select your ESP32 (e.g., “Prov_123”).
  3. Enter POP: Input the Proof-of-Provisioning (e.g., “abcd1234”).
  4. Select Wi-Fi Network: Choose your network from the list or manually enter SSID/password.
  5. Provision: Tap “Start” to send credentials.

ESP BLE provision app connection steps 2


Step 5: Validate Connectivity

After provisioning, the ESP32 automatically connects to Wi-Fi. Verify via:

  • Serial Monitor: Displays SSID, IP address, and connection status.

esp provision output on serial monitor


Advanced Customization

Custom Service Name: Modify service_name in the code for unique identification.

POP Security: Use complex, unique POPs to prevent unauthorized access.

  • ESP32 BLE provisioning supports three security levels:
  • Security Level 0 (Open): No encryption or authentication required. Suitable only for development environments.
  • Security Level 1 (PoP-based): Uses Proof of Possession for authentication. Recommended for most applications.
  • Security Level 2 (Certificate-based): Implements full certificate-based authentication. Required for high-security applications.

Post-Connection Logic: Add MQTT, HTTP, or OTA updates in the loop().


Troubleshooting Common Issues

  1. Device Not Found:
    • Ensure BLE is enabled on the smartphone.
    • Check ESP32’s power supply and code upload.
  2. Provisioning Failure:
    • Verify SSID/password accuracy.
    • Ensure the network is 2.4 GHz (ESP32 doesn’t support 5 GHz).
  3. Connection Drops:
    • Monitor signal strength; reposition the ESP32 if needed.

Frequently Asked Questions

Q1: Can I reprovision the ESP32 to a new network?
Yes! Reset the board or press BOOT button on ESP for 5 seconds to restart BLE mode.

Q2: How secure is BLE provisioning?
Espressif’s protocol uses AES-256 encryption, making it secure for most IoT applications.

Q3: What if I lose the POP?
Without the POP, reprovisioning requires reflashing the firmware.

Q4: Is BLE provisioning secure for enterprise environments?

Yes, when properly implemented with Security Level 1 or 2, BLE provisioning provides enterprise-grade security suitable for corporate and industrial applications.

Q5: Can I customize the provisioning mobile app?

Espressif provides open-source mobile app examples that you can customize for your specific branding and functionality requirements.


Conclusion

Wi-Fi provisioning via BLE transforms how ESP32 devices connect to networks, combining security, convenience, and scalability. By following this guide, you’ve eliminated hardcoded credentials and embraced a user-friendly setup process—essential for commercial IoT deployments.

Ready to take your project further? Explore integrating MQTT for real-time data or enabling Over-the-Air (OTA) updates to manage devices remotely. The ESP32’s versatility, paired with robust provisioning, opens endless possibilities for smart homes, industrial automation, and beyond.

Add a Comment

Leave a Reply

Your email address will not be published. Required fields are marked *