{"id":150108,"date":"2024-04-11T13:15:58","date_gmt":"2024-04-11T13:15:58","guid":{"rendered":"https:\/\/randomnerdtutorials.com\/?p=150108"},"modified":"2024-04-11T13:36:59","modified_gmt":"2024-04-11T13:36:59","slug":"esp32-wi-fi-provisioning-ble-arduino","status":"publish","type":"post","link":"https:\/\/randomnerdtutorials.com\/esp32-wi-fi-provisioning-ble-arduino\/","title":{"rendered":"ESP32 Wi-Fi Provisioning via BLE (Bluetooth Low Energy) &#8211; Arduino IDE"},"content":{"rendered":"\n<p>In this tutorial, you&#8217;ll learn how to set up Wi-Fi provisioning via BLE on the ESP32. The Wi-Fi provisioning service allows you to configure Wi-Fi credentials over Bluetooth Low Energy. This is a great option for IoT projects that require Wi-Fi credentials to connect to the internet, without the need to hard-code them on the Arduino sketch while developing.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" fetchpriority=\"high\" decoding=\"async\" width=\"1200\" height=\"675\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/03\/ESP32-Wi-Fi-Provisioning-via-BLE-f.jpg?resize=1200%2C675&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"ESP32 Wi-Fi Provisioning via BLE Arduino IDE\" class=\"wp-image-150270\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/03\/ESP32-Wi-Fi-Provisioning-via-BLE-f.jpg?w=1920&amp;quality=100&amp;strip=all&amp;ssl=1 1920w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/03\/ESP32-Wi-Fi-Provisioning-via-BLE-f.jpg?resize=300%2C169&amp;quality=100&amp;strip=all&amp;ssl=1 300w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/03\/ESP32-Wi-Fi-Provisioning-via-BLE-f.jpg?resize=1024%2C576&amp;quality=100&amp;strip=all&amp;ssl=1 1024w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/03\/ESP32-Wi-Fi-Provisioning-via-BLE-f.jpg?resize=768%2C432&amp;quality=100&amp;strip=all&amp;ssl=1 768w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/03\/ESP32-Wi-Fi-Provisioning-via-BLE-f.jpg?resize=1536%2C864&amp;quality=100&amp;strip=all&amp;ssl=1 1536w\" sizes=\"(max-width: 1200px) 100vw, 1200px\" \/><\/figure><\/div>\n\n\n<p><strong>Table of Contents:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"#wifi-provisioning\" title=\"\">Wi-Fi Provisioning<\/a><\/li>\n\n\n\n<li><a href=\"#provisioning-ble\" title=\"\">Provisioning over BLE<\/a><\/li>\n\n\n\n<li><a href=\"#wi-fi-provisioning-app\" title=\"\">Wi-Fi Provisioning App<\/a><\/li>\n\n\n\n<li><a href=\"#esp32-wifi-provisioning-ble-arduino-code\" title=\"\">ESP32 WiFi Provisioning via BLE &#8211; Code<\/a><\/li>\n\n\n\n<li><a href=\"#uploading\" title=\"\">Instructions for Uploading the Code<\/a><\/li>\n\n\n\n<li><a href=\"#testing\" title=\"\">Testing the Code<\/a><\/li>\n\n\n\n<li><a href=\"#application\" title=\"\">How to Apply the Wi-Fi Provisioning to Your Wi-Fi Projects<\/a><\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"wifi-provisioning\">Wi-Fi Provisioning<\/h2>\n\n\n\n<p>Wi-Fi provisioning is&nbsp;the process of connecting a new Wi-Fi device (station) to a Wi-Fi network (access point). In this case, we want to connect an ESP32 to a Wi-Fi network. The provisioning process involves loading the ESP32 with the name of the network (SSID) and password that we want to connect to.<\/p>\n\n\n\n<p>The ESP32 supports Wi-Fi provisioning over SoftAP (access point) or via Bluetooth Low Energy. In this tutorial, we&#8217;ll cover Wi-Fi provisioning via Bluetooth.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"provisioning-ble\">Provisioning over BLE<\/h3>\n\n\n\n<p>To provision the ESP32 via BLE, we need to use another BLE-enabled device, usually a smartphone to connect to the ESP32 via BLE and send the Wi-Fi credentials. We can use an Android or iOS app or a Web Bluetooth app.<\/p>\n\n\n\n<p>Espressif developed Android and iOS apps that support Wi-Fi provisioning for its devices like the ESP32 boards. Alternatively, you can create your own BLE app.<\/p>\n\n\n\n<p>After the provisioning process, the ESP32 can connect to the desired Wi-Fi network with the provided network credentials.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-large\"><img data-recalc-dims=\"1\" decoding=\"async\" width=\"1024\" height=\"530\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/03\/ESP32-Wi-Fi-Provisioning-via-BLE-How-it-Works.png?resize=1024%2C530&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"ESP32 Wi-Fi Provisioning over BLE\" class=\"wp-image-150276\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/03\/ESP32-Wi-Fi-Provisioning-via-BLE-How-it-Works.png?resize=1024%2C530&amp;quality=100&amp;strip=all&amp;ssl=1 1024w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/03\/ESP32-Wi-Fi-Provisioning-via-BLE-How-it-Works.png?resize=300%2C155&amp;quality=100&amp;strip=all&amp;ssl=1 300w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/03\/ESP32-Wi-Fi-Provisioning-via-BLE-How-it-Works.png?resize=768%2C398&amp;quality=100&amp;strip=all&amp;ssl=1 768w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/03\/ESP32-Wi-Fi-Provisioning-via-BLE-How-it-Works.png?w=1280&amp;quality=100&amp;strip=all&amp;ssl=1 1280w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><figcaption class=\"wp-element-caption\">ESP32 Wi-Fi Provisioning over BLE<\/figcaption><\/figure><\/div>\n\n\n<p>Here&#8217;s a quick summary of how it works:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>You have a new device that you want to connect to a known network. In our case, an ESP32.<\/li>\n\n\n\n<li>You connect to the ESP32 via BLE. On the Wi-Fi provisioning app, you enter and send the SSID and password of the network you want your ESP32 to connect to.<\/li>\n\n\n\n<li>Finally, the ESP32 connects to the network using the provided credentials. From this moment, it can do any other Wi-Fi-related tasks it needs.<\/li>\n<\/ol>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"wi-fi-provisioning-app\">Wi-Fi Provisioning App<\/h2>\n\n\n\n<p>To connect and send the credentials to the ESP32 via BLE, we&#8217;ll use the Wi-Fi Provisioning App developed by Espressif (alternatively, you can create your own BLE app).<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Installing the Wi-Fi Provisioning App<\/h3>\n\n\n\n<p>Before proceeding, make sure you install the Wi-Fi provisioning app on your smartphone:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/play.google.com\/store\/apps\/details?id=com.espressif.provble\" target=\"_blank\" rel=\"noopener\" title=\"\">Wi-Fi Provisioning App for Android devices<\/a>  &#8211; (<a href=\"https:\/\/github.com\/espressif\/esp-idf-provisioning-android\" target=\"_blank\" rel=\"noopener\" title=\"\">App source code<\/a>)<\/li>\n\n\n\n<li><a href=\"https:\/\/apps.apple.com\/in\/app\/esp-ble-provisioning\/id1473590141\" target=\"_blank\" rel=\"noopener\" title=\"\">Wi-Fi Provisioning App for iOS devices<\/a> &#8211; (<a href=\"https:\/\/github.com\/espressif\/esp-idf-provisioning-ios\" target=\"_blank\" rel=\"noopener\" title=\"\">App source code<\/a>)<\/li>\n<\/ul>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" decoding=\"async\" width=\"679\" height=\"236\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/03\/WiFi_provisioning_app_espressif.png?resize=679%2C236&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Wi-Fi provisioning App - espressif\" class=\"wp-image-150109\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/03\/WiFi_provisioning_app_espressif.png?w=679&amp;quality=100&amp;strip=all&amp;ssl=1 679w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/03\/WiFi_provisioning_app_espressif.png?resize=300%2C104&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 679px) 100vw, 679px\" \/><\/figure><\/div>\n\n\n<h2 class=\"wp-block-heading\" id=\"esp32-wifi-provisioning-ble-arduino-code\">ESP32 WiFi Provisioning via BLE &#8211; Code<\/h2>\n\n\n\n<p>The following code will prepare the ESP32 for Wi-Fi provisioning via BLE. This is the minimal code required to do that. We adapted this code slightly from the <a href=\"https:\/\/github.com\/espressif\/arduino-esp32\/blob\/master\/libraries\/WiFiProv\/examples\/WiFiProv\/WiFiProv.ino\" target=\"_blank\" rel=\"noopener\" title=\"\">official example<\/a> that also supports WiFi provisioning via an access point.<\/p>\n\n\n\n<p>Copy the following code to the Arduino IDE.<\/p>\n\n\n<pre style=\"max-height: 40em; margin-bottom: 20px;\"><code class=\"language-c\">\/*********\n  Rui Santos &amp; Sara Santos - Random Nerd Tutorials\n  Complete project details at https:\/\/RandomNerdTutorials.com\/esp32-wi-fi-provisioning-ble-arduino\/\n\n  Please read README.md file in this folder, or on the web: https:\/\/github.com\/espressif\/arduino-esp32\/tree\/master\/libraries\/WiFiProv\/examples\/WiFiProv\n  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.\n  If you see Error like this: &quot;Sketch too big&quot;\n  In Arduino IDE go to: Tools &gt; Partition scheme &gt; chose anything that has more than 1.4MB APP\n   - for example &quot;No OTA (2MB APP\/2MB SPIFFS)&quot;\n*********\/\n\n#include &quot;WiFiProv.h&quot;\n#include &quot;WiFi.h&quot;\n\nconst char * pop = &quot;abcd1234&quot;; \/\/ Proof of possession - otherwise called a PIN - string provided by the device, entered by the user in the phone app\nconst char * service_name = &quot;PROV_123&quot;; \/\/ Name of your device (the Espressif apps expects by default device name starting with &quot;Prov_&quot;)\nconst char * service_key = NULL; \/\/ Password used for SofAP method (NULL = no password needed)\nbool reset_provisioned = true; \/\/ When true the library will automatically delete previously provisioned data.\n\n\/\/ WARNING: SysProvEvent is called from a separate FreeRTOS task (thread)!\nvoid SysProvEvent(arduino_event_t *sys_event) {\n  switch (sys_event-&gt;event_id) {\n    case ARDUINO_EVENT_WIFI_STA_GOT_IP:\n      Serial.print(&quot;\\nConnected IP address : &quot;);\n      Serial.println(IPAddress(sys_event-&gt;event_info.got_ip.ip_info.ip.addr));\n      break;\n    case ARDUINO_EVENT_WIFI_STA_DISCONNECTED: Serial.println(&quot;\\nDisconnected. Connecting to the AP again... &quot;); break;\n    case ARDUINO_EVENT_PROV_START:            Serial.println(&quot;\\nProvisioning started\\nGive Credentials of your access point using smartphone app&quot;); break;\n    case ARDUINO_EVENT_PROV_CRED_RECV:\n    {\n      Serial.println(&quot;\\nReceived Wi-Fi credentials&quot;);\n      Serial.print(&quot;\\tSSID : &quot;);\n      Serial.println((const char *)sys_event-&gt;event_info.prov_cred_recv.ssid);\n      Serial.print(&quot;\\tPassword : &quot;);\n      Serial.println((char const *)sys_event-&gt;event_info.prov_cred_recv.password);\n      break;\n    }\n    case ARDUINO_EVENT_PROV_CRED_FAIL:\n    {\n      Serial.println(&quot;\\nProvisioning failed!\\nPlease reset to factory and retry provisioning\\n&quot;);\n      if (sys_event-&gt;event_info.prov_fail_reason == NETWORK_PROV_WIFI_STA_AUTH_ERROR) {\n        Serial.println(&quot;\\nWi-Fi AP password incorrect&quot;);\n      } else {\n        Serial.println(&quot;\\nWi-Fi AP not found....Add API \\&quot; nvs_flash_erase() \\&quot; before beginProvision()&quot;);\n      }\n      break;\n    }\n    case ARDUINO_EVENT_PROV_CRED_SUCCESS: Serial.println(&quot;\\nProvisioning Successful&quot;); break;\n    case ARDUINO_EVENT_PROV_END:          Serial.println(&quot;\\nProvisioning Ends&quot;); break;\n    default:                              break;\n  }\n}\n\nvoid setup() {\n  Serial.begin(115200);\n  WiFi.onEvent(SysProvEvent);\n\n  Serial.println(&quot;Begin Provisioning using BLE&quot;);\n  \/\/ Sample uuid that user can pass during provisioning using BLE\n  uint8_t uuid[16] = {0xb4, 0xdf, 0x5a, 0x1c, 0x3f, 0x6b, 0xf4, 0xbf,\n                      0xea, 0x4a, 0x82, 0x03, 0x04, 0x90, 0x1a, 0x02 };\n  WiFiProv.beginProvision(\n    NETWORK_PROV_SCHEME_BLE, NETWORK_PROV_SCHEME_HANDLER_FREE_BLE, NETWORK_PROV_SECURITY_1, pop, service_name, service_key, uuid, reset_provisioned\n  );\n  log_d(&quot;ble qr&quot;);\n  WiFiProv.printQR(service_name, pop, &quot;ble&quot;);\n}\n\nvoid loop() {\n  \n}\n<\/code><\/pre>\n\t<p style=\"text-align:center\"><a class=\"rntwhite\" href=\"https:\/\/github.com\/RuiSantosdotme\/Random-Nerd-Tutorials\/raw\/master\/Projects\/ESP32\/BLE\/ESP32_WiFi_Provisioning_BLE.ino\" target=\"_blank\">View raw code<\/a><\/p>\n\n\n\n<h3 class=\"wp-block-heading\">How the Code Works<\/h3>\n\n\n\n<p>Let&#8217;s take a quick look at how the code works (or <a href=\"#uploading\" title=\"\">skip to the next section<\/a>).<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Including Libraries<\/h4>\n\n\n\n<p>First, you include the required libraries, the <span class=\"rnthl rntliteral\">WiFiProv.h<\/span> for Wi-Fi provisioning and the <span class=\"rnthl rntliteral\">WiFi.h<\/span> for Wi-Fi related functions.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>#include \"WiFiProv.h\"\n#include \"WiFi.h\"<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Provisioning Details<\/h4>\n\n\n\n<p>Then, we declare some variables to hold details for the provisioning service. <\/p>\n\n\n\n<p>The <span class=\"rnthl rntliteral\">pop<\/span> variable is the proof of possession, it&#8217;s like a password so that you can connect the smartphone to this specific device. For testing, we&#8217;ll use the default value.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>const char * pop = \"abcd1234\"; \/\/ Proof of possession - otherwise called a PIN - string provided by the device, entered by the user in the phone app<\/code><\/pre>\n\n\n\n<p>The <span class=\"rnthl rntliteral\">service_name<\/span> is the name of our BLE device. If you&#8217;re using the Espressif app, like we&#8217;ll do in this tutorial, the service name must start with the prefix <span class=\"rnthl rntliteral\">PROV_<\/span>.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>const char * service_name = \"PROV_123\"; \/\/ Name of your device (the Espressif apps expects by default device name starting with \"Prov_\")<\/code><\/pre>\n\n\n\n<p>The <span class=\"rnthl rntliteral\">service_key<\/span> is used when using Wi-Fi Provisioning via Access Point (not included in this guide). Set it to <span class=\"rnthl rntliteral\">NULL<\/span> because it&#8217;s not needed.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>const char * service_key = NULL; \/\/ Password used for SofAP method (NULL = no password needed)<\/code><\/pre>\n\n\n\n<p>The <span class=\"rnthl rntliteral\">reset_provisioned<\/span> is a boolean variable indicating whether the library should delete previously provisioned data.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>bool reset_provisioned = true; \/\/ When true the library will automatically delete previously provisioned data.<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Wi-Fi Event Callback Function<\/h4>\n\n\n\n<p>In the <span class=\"rnthl rntliteral\">setup()<\/span>, set a function that will run when a Wi-Fi event occurs. In this case, it will call the <span class=\"rnthl rntliteral\">SysProvEvent()<\/span> function when any Wi-Fi event occurs. Then, on the <span class=\"rnthl rntliteral\">SysProvEvent()<\/span> function we&#8217;ll decide what happens according to the Wi-Fi event detected.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>WiFi.onEvent(SysProvEvent);<\/code><\/pre>\n\n\n\n<p class=\"rntbox rntclgreen\">You may also like: <a href=\"https:\/\/randomnerdtutorials.com\/esp32-useful-wi-fi-functions-arduino\/\">ESP32 Useful Wi-Fi Library Functions (Arduino IDE)<\/a><\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Starting WiFi Provisioning<\/h4>\n\n\n\n<p>Starting the Wi-Fi provisioning process is as easy as using <span class=\"rnthl rntliteral\">WiFiProv.beginProvision()<\/span> with the proper arguments.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>WiFiProv.beginProvision(WIFI_PROV_SCHEME_BLE, WIFI_PROV_SCHEME_HANDLER_FREE_BTDM, WIFI_PROV_SECURITY_1, pop, service_name, service_key, uuid, reset_provisioned);<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Print QR Code<\/h4>\n\n\n\n<p>We also print the BLE provision details in a QR code that can be detected by the Wi-Fi Provisioning app.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>log_d(\"ble qr\");\nWiFiProv.printQR(service_name, pop, \"ble\");<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Detecting WiFi Events<\/h4>\n\n\n\n<p>The different Wi-Fi events will be passed to the <span class=\"rnthl rntliteral\">SysProvEenvent()<\/span>.<\/p>\n\n\n\n<h5 class=\"wp-block-heading\"><strong>ARDUINO_EVENT_WIFI_STA_GOT_IP<\/strong><\/h5>\n\n\n\n<p>When the ESP32 connects to a network and is assigned an IP address, it detects the <span class=\"rnthl rntliteral\">ARDUINO_EVENT_WIFI_STA_GOT_IP<\/span> event. When this happens, we print the ESP32 IP address (you can run other tasks as needed, or add a flag variable to indicate that the ESP32 is connected to WiFi and that we can run wifi-related tasks in the <span class=\"rnthl rntliteral\">loop()<\/span>).<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>case ARDUINO_EVENT_WIFI_STA_GOT_IP:\n    Serial.print(\"\\nConnected IP address : \");\n    Serial.println(IPAddress(sys_event-&gt;event_info.got_ip.ip_info.ip.addr));\n    break;<\/code><\/pre>\n\n\n\n<h5 class=\"wp-block-heading\"><strong>ARDUINO_EVENT_PROV_START<\/strong><\/h5>\n\n\n\n<p>The <span class=\"rnthl rntliteral\">ARDUINO_EVENT_PROV_START<\/span> event happens when the provisioning process starts. This happens when we call the <span class=\"rnthl rntliteral\">WiFiProv.beginProvision()<\/span> function in the <span class=\"rnthl rntliteral\">setup()<\/span>.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>case ARDUINO_EVENT_PROV_START:\n    Serial.println(\"\\nProvisioning started\\nGive Credentials of your access point using smartphone app\");\n    break;<\/code><\/pre>\n\n\n\n<h5 class=\"wp-block-heading\"><strong>ARDUINO_EVENT_PROV_CRED_RECV<\/strong><\/h5>\n\n\n\n<p>This event is triggered when the board receives the credentials via Wi-Fi provisioning. In this case, we print the received SSID and password. Alternatively, you can save the credentials permanently to a file if that&#8217;s useful for your project.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>case ARDUINO_EVENT_PROV_CRED_RECV: {\n    Serial.println(\"\\nReceived Wi-Fi credentials\");\n    Serial.print(\"\\tSSID : \");\n    Serial.println((const char *) sys_event-&gt;event_info.prov_cred_recv.ssid);\n    Serial.print(\"\\tPassword : \");\n    Serial.println((char const *) sys_event-&gt;event_info.prov_cred_recv.password);\n    break;\n}<\/code><\/pre>\n\n\n\n<h5 class=\"wp-block-heading\"><strong>ARDUINO_EVENT_PROV_CRED_FAIL<\/strong><\/h5>\n\n\n\n<p>This event will run if the credentials provided via Wi-Fi provisioning will fail to connect to the network.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>case ARDUINO_EVENT_PROV_CRED_FAIL: {\n    Serial.println(\"\\nProvisioning failed!\\nPlease reset to factory and retry provisioning\\n\");\n    if(sys_event-&gt;event_info.prov_fail_reason == WIFI_PROV_STA_AUTH_ERROR)\n        Serial.println(\"\\nWi-Fi AP password incorrect\");\n    else\n        Serial.println(\"\\nWi-Fi AP not found....Add API \\\" nvs_flash_erase() \\\" before beginProvision()\");\n    break;\n}<\/code><\/pre>\n\n\n\n<h5 class=\"wp-block-heading\"><strong>ARDUINO_EVENT_PROV_CRED_SUCCESS<\/strong><\/h5>\n\n\n\n<p>The <span class=\"rnthl rntliteral\">ARDUINO_EVEN_PROV_CRED_SUCCESS<\/span> event will run if the ESP32 successfully connects to the network using the credentials provided via Wi-Fi provisioning.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>case ARDUINO_EVENT_PROV_CRED_SUCCESS:\n    Serial.println(\"\\nProvisioning Successful\");\n    break;<\/code><\/pre>\n\n\n\n<h5 class=\"wp-block-heading\"><strong>ARDUINO_EVENT_PROV_END<\/strong><\/h5>\n\n\n\n<p>Finally, when the provisioning process ends, the <span class=\"rnthl rntliteral\">ARDUINO_EVENT_PROV_END<\/span> is triggered.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>case ARDUINO_EVENT_PROV_END:\n    Serial.println(\"\\nProvisioning Ends\");\n    break;<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"uploading\">Instructions for Uploading the Code<\/h2>\n\n\n\n<p>This code takes up a lot of space and may not be able to flash with the default settings on some chips.<\/p>\n\n\n\n<p>If you see an Error like this: &#8220;Sketch too big&#8221; during the uploading process, in Arduino IDE go to <strong>Tools <\/strong>> <strong>Partition scheme<\/strong> > choose anything that has more than 1.4MB APP, for example: &#8220;<strong>Huge APP (3MB No OTA\/1MB SPIFFS<\/strong>&#8220;.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"468\" height=\"511\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/03\/ESP32-selecting-different-partition-scheme.png?resize=468%2C511&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"ESP32 Selecting Different Partition Scheme\" class=\"wp-image-150111\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/03\/ESP32-selecting-different-partition-scheme.png?w=468&amp;quality=100&amp;strip=all&amp;ssl=1 468w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/03\/ESP32-selecting-different-partition-scheme.png?resize=275%2C300&amp;quality=100&amp;strip=all&amp;ssl=1 275w\" sizes=\"(max-width: 468px) 100vw, 468px\" \/><\/figure><\/div>\n\n\n<p>If you don&#8217;t have the partition scheme option on your <strong>Tools <\/strong>menu, you need to select a different ESP32 board model\u2014for example, the ESP32 Wrover Module.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"testing\">Testing the Code<\/h2>\n\n\n\n<p>After uploading the code to the ESP32, open the Serial Monitor at a baud rate of 115200. Press the ESP32 RST button, so it starts running the code.<\/p>\n\n\n\n<p><strong>Note:<\/strong> you may get a PSRAM error. You can ignore it.<\/p>\n\n\n\n<p>You&#8217;ll get something similar on your Serial Monitor.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Begin Provisioning using BLE\n\nProvisioning started\nGive Credentials of your access point using smartphone app<\/code><\/pre>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"666\" height=\"539\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/03\/ESP32-start-wi-fi-provisioning.png?resize=666%2C539&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"ESP32 Start Wi-Fi Provisioning via BLE Serial Monitor\" class=\"wp-image-150113\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/03\/ESP32-start-wi-fi-provisioning.png?w=666&amp;quality=100&amp;strip=all&amp;ssl=1 666w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/03\/ESP32-start-wi-fi-provisioning.png?resize=300%2C243&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 666px) 100vw, 666px\" \/><\/figure><\/div>\n\n\n<p>Now, open the Espressif WiFi Provisioning App on your smartphone and click on <strong>Provision Device<\/strong>. It has the option to scan the QR code, but I couldn&#8217;t make it work. Click on &#8220;<strong>I don&#8217;t have a QR code<\/strong>&#8220;.<\/p>\n\n\n\n<p>It will list all Bluetooth Devices within its range with the &#8220;<strong>PROV_<\/strong>&#8221; prefix. Our code sets the ESP32 as a BLE Device called &#8220;<strong>PROV_123<\/strong>&#8220;\u2014click on that device.<\/p>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-9d6595d7 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n<figure class=\"wp-block-image size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"358\" height=\"722\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/03\/1-Wifi-provisioning-scan-devices-e.png?resize=358%2C722&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Wifi Provisioning App - Provision Device\" class=\"wp-image-150121\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/03\/1-Wifi-provisioning-scan-devices-e.png?w=358&amp;quality=100&amp;strip=all&amp;ssl=1 358w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/03\/1-Wifi-provisioning-scan-devices-e.png?resize=149%2C300&amp;quality=100&amp;strip=all&amp;ssl=1 149w\" sizes=\"(max-width: 358px) 100vw, 358px\" \/><\/figure>\n<\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n<figure class=\"wp-block-image size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"358\" height=\"722\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/03\/2-Wifi-provisioning-find-devices-e.png?resize=358%2C722&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Wi-Fi provision via BLE - finding BLE devices\" class=\"wp-image-150122\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/03\/2-Wifi-provisioning-find-devices-e.png?w=358&amp;quality=100&amp;strip=all&amp;ssl=1 358w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/03\/2-Wifi-provisioning-find-devices-e.png?resize=149%2C300&amp;quality=100&amp;strip=all&amp;ssl=1 149w\" sizes=\"(max-width: 358px) 100vw, 358px\" \/><\/figure>\n<\/div>\n<\/div>\n\n\n\n<p>Then, you need to enter the proof of possession\u2014it must be the same used in the code. We&#8217;re using the default values, so it will be <em>abcd1234<\/em>. After, it will list all Wi-Fi networks within its range (if it doesn&#8217;t list your network, you may need to enter it manually by clicking on &#8220;Join Other Network&#8221;).<\/p>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-9d6595d7 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\"><div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"357\" height=\"722\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/03\/3-Wifi-provisioning-proof-of-possession-e.png?resize=357%2C722&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Espressif Wi-Fi provisioning enter proof of possession\" class=\"wp-image-150123\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/03\/3-Wifi-provisioning-proof-of-possession-e.png?w=357&amp;quality=100&amp;strip=all&amp;ssl=1 357w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/03\/3-Wifi-provisioning-proof-of-possession-e.png?resize=148%2C300&amp;quality=100&amp;strip=all&amp;ssl=1 148w\" sizes=\"(max-width: 357px) 100vw, 357px\" \/><\/figure><\/div><\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n<figure class=\"wp-block-image size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"356\" height=\"722\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/03\/4-Wifi-provisioning-find-networks-e.png?resize=356%2C722&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Wi-Fi provisioning app - listing Wi-Fi networks.\" class=\"wp-image-150124\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/03\/4-Wifi-provisioning-find-networks-e.png?w=356&amp;quality=100&amp;strip=all&amp;ssl=1 356w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/03\/4-Wifi-provisioning-find-networks-e.png?resize=148%2C300&amp;quality=100&amp;strip=all&amp;ssl=1 148w\" sizes=\"(max-width: 356px) 100vw, 356px\" \/><\/figure>\n<\/div>\n<\/div>\n\n\n\n<p>Finally, enter the password for your Wi-Fi network and click Connect. The Wi-Fi credentials should be sent to the ESP32 after a few seconds.<\/p>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-9d6595d7 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\"><div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"358\" height=\"722\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/03\/5-Wifi-provisioning-insert-SSID-password-e.png?resize=358%2C722&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"ESP32 WiFi Provisioning via BLE inserting SSID and password\" class=\"wp-image-150138\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/03\/5-Wifi-provisioning-insert-SSID-password-e.png?w=358&amp;quality=100&amp;strip=all&amp;ssl=1 358w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/03\/5-Wifi-provisioning-insert-SSID-password-e.png?resize=149%2C300&amp;quality=100&amp;strip=all&amp;ssl=1 149w\" sizes=\"(max-width: 358px) 100vw, 358px\" \/><\/figure><\/div><\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\"><div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"358\" height=\"720\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/03\/7-wifi-provisioning-success-e.png?resize=358%2C720&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"WiFi Provisioning Sucessfull ESP32\" class=\"wp-image-150139\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/03\/7-wifi-provisioning-success-e.png?w=358&amp;quality=100&amp;strip=all&amp;ssl=1 358w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/03\/7-wifi-provisioning-success-e.png?resize=149%2C300&amp;quality=100&amp;strip=all&amp;ssl=1 149w\" sizes=\"(max-width: 358px) 100vw, 358px\" \/><\/figure><\/div><\/div>\n<\/div>\n\n\n\n<p>On the Serial monitor, you can see that the ESP32 received the Wi-Fi credentials and connected successfully to the network (it printed its IP address on the network it connected to).<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"666\" height=\"321\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/03\/ESP32-Wi-fi-provisioning-via-BLE-Serial-Monitor.png?resize=666%2C321&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"ESP32 WiFi Provisioning Successful Serial Monitor\" class=\"wp-image-150140\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/03\/ESP32-Wi-fi-provisioning-via-BLE-Serial-Monitor.png?w=666&amp;quality=100&amp;strip=all&amp;ssl=1 666w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/03\/ESP32-Wi-fi-provisioning-via-BLE-Serial-Monitor.png?resize=300%2C145&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 666px) 100vw, 666px\" \/><\/figure><\/div>\n\n\n<p> That&#8217;s it. Wi-Fi provisioning was successfully implemented on the ESP32.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"application\">How to Apply the Wi-Fi Provisioning to Your Wi-Fi Projects<\/h2>\n\n\n\n<p>To add this feature to your projects that use Wi-Fi, I suggest creating a global variable that indicates whether the ESP32 is already connected to the internet. That variable will change to <span class=\"rnthl rntliteral\">true<\/span> when the <span class=\"rnthl rntliteral\">ARDUINO_EVENT_WIFI_STA_GOT_IP<\/span> is triggered.<\/p>\n\n\n\n<p>Then, in the <span class=\"rnthl rntliteral\">loop()<\/span>, check the state of that variable. If it&#8217;s true, run your Wi-Fi-related tasks. If not, simply wait for the board to establish a connection.<\/p>\n\n\n\n<p>We&#8217;ll create a web server example with this feature soon, so stay tuned.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Wrapping Up<\/h2>\n\n\n\n<p>In this tutorial, we&#8217;ve shown you how to add Wi-Fi Provisioning via BLE to your ESP32 devices. Using this feature is simple and easy thanks to the <span class=\"rnthl rntliteral\">WiFiProv<\/span> library and the Espressif Provisioning app.<\/p>\n\n\n\n<p>This is a great option for IoT projects that require Wi-Fi credentials to connect to the internet, without the need to hard-code them while developing, which makes the project much more versatile.<\/p>\n\n\n\n<p>We&#8217;ll create more tutorials about this subject soon, so stay tuned. You may also like reading:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/randomnerdtutorials.com\/esp32-wi-fi-manager-asyncwebserver\/\">ESP32: Create a Wi-Fi Manager (AsyncWebServer library)<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/randomnerdtutorials.com\/esp32-wifimulti\/\">ESP32 WiFiMulti: Connect to the Strongest Wi-Fi Network (from a list of networks)<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/randomnerdtutorials.com\/esp32-useful-wi-fi-functions-arduino\/\">ESP32 Useful Wi-Fi Library Functions (Arduino IDE)<\/a><\/li>\n<\/ul>\n\n\n\n<p>We hope you&#8217;ve found this tutorial useful. Learn more about the ESP32 with our resources.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/randomnerdtutorials.com\/learn-esp32-with-arduino-ide\/\">Learn ESP32 with Arduino IDE (eBook)<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/randomnerdtutorials.com\/smart-home-ebook\/\" title=\"\">SMART HOME with Raspberry Pi, ESP32, and ESP8266<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/randomnerdtutorials.com\/build-web-servers-esp32-esp8266-ebook\/\">Build Web Servers with ESP32 and ESP8266 (eBook)<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/randomnerdtutorials.com\/projects-esp32\/\">Free ESP32 Projects and Tutorials\u2026<\/a><\/li>\n<\/ul>\n\n\n\n<p>                                                                                                                                                                                                                                                                               <\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this tutorial, you&#8217;ll learn how to set up Wi-Fi provisioning via BLE on the ESP32. The Wi-Fi provisioning service allows you to configure Wi-Fi credentials over Bluetooth Low Energy. &#8230; <\/p>\n<p class=\"read-more-container\"><a title=\"ESP32 Wi-Fi Provisioning via BLE (Bluetooth Low Energy) &#8211; Arduino IDE\" class=\"read-more button\" href=\"https:\/\/randomnerdtutorials.com\/esp32-wi-fi-provisioning-ble-arduino\/#more-150108\" aria-label=\"Read more about ESP32 Wi-Fi Provisioning via BLE (Bluetooth Low Energy) &#8211; Arduino IDE\">CONTINUE READING \u00bb<\/a><\/p>\n","protected":false},"author":5,"featured_media":150270,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[281,276,277,299,264],"tags":[],"class_list":["post-150108","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-esp32-project","category-esp32","category-esp32-arduino-ide","category-0-esp32","category-project"],"aioseo_notices":[],"jetpack_featured_media_url":"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/03\/ESP32-Wi-Fi-Provisioning-via-BLE-f.jpg?fit=1920%2C1080&quality=100&strip=all&ssl=1","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/posts\/150108","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/users\/5"}],"replies":[{"embeddable":true,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/comments?post=150108"}],"version-history":[{"count":21,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/posts\/150108\/revisions"}],"predecessor-version":[{"id":152128,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/posts\/150108\/revisions\/152128"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/media\/150270"}],"wp:attachment":[{"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/media?parent=150108"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/categories?post=150108"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/tags?post=150108"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}