{"id":63505,"date":"2024-06-11T08:06:00","date_gmt":"2024-06-11T08:06:00","guid":{"rendered":"http:\/\/randomnerdtutorials.com\/?p=63505"},"modified":"2024-06-11T14:40:57","modified_gmt":"2024-06-11T14:40:57","slug":"esp32-bluetooth-low-energy-ble-arduino-ide","status":"publish","type":"post","link":"https:\/\/randomnerdtutorials.com\/esp32-bluetooth-low-energy-ble-arduino-ide\/","title":{"rendered":"Getting Started with ESP32 Bluetooth Low Energy (BLE) on Arduino IDE"},"content":{"rendered":"\n<p>The ESP32 comes not only with Wi-Fi but also with Bluetooth and Bluetooth Low Energy (BLE). This post is a quick introduction to BLE with the ESP32. First, we&#8217;ll explore what&#8217;s BLE and what it can be used for, and then we&#8217;ll take a look at some examples with the ESP32 using Arduino IDE. For a simple introduction we&#8217;ll create an ESP32 BLE server, and an ESP32 BLE scanner to find that server.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img data-recalc-dims=\"1\" fetchpriority=\"high\" decoding=\"async\" width=\"1024\" height=\"576\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/06\/ESP32-BLE-Getting-Started-1.jpg?resize=1024%2C576&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Getting Started with ESP32 Bluetooth Low Energy (BLE) on Arduino IDE\" class=\"wp-image-158764\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/06\/ESP32-BLE-Getting-Started-1.jpg?resize=1024%2C576&amp;quality=100&amp;strip=all&amp;ssl=1 1024w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/06\/ESP32-BLE-Getting-Started-1.jpg?resize=300%2C169&amp;quality=100&amp;strip=all&amp;ssl=1 300w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/06\/ESP32-BLE-Getting-Started-1.jpg?resize=768%2C432&amp;quality=100&amp;strip=all&amp;ssl=1 768w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/06\/ESP32-BLE-Getting-Started-1.jpg?w=1280&amp;quality=100&amp;strip=all&amp;ssl=1 1280w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p class=\"rntbox rntclgray\"><em>Updated 11 June 2024<\/em><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Introducing Bluetooth Low Energy<\/h2>\n\n\n\n<p>For a quick introduction to BLE, you can watch the video below, or you can scroll down for a written explanation.<\/p>\n\n\n<p style=\"text-align:center\"><iframe width=\"720\" height=\"405\" src=\"https:\/\/www.youtube.com\/embed\/wkO-ytWVvC0?rel=0\" frameborder=\"0\" allowfullscreen><\/iframe><\/p>\n\n\n\n<p><strong>Recommended reading: <\/strong>learn how to use <a href=\"https:\/\/randomnerdtutorials.com\/esp32-bluetooth-classic-arduino-ide\/\">ESP32 Bluetooth Classic with Arduino IDE<\/a> to exchange data between an ESP32 and an Android smartphone.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">What is Bluetooth Low Energy?<\/h3>\n\n\n\n<p>Bluetooth Low Energy, BLE for short, is a power-conserving variant of Bluetooth. BLE\u2019s primary application is short distance transmission of small amounts of data (low bandwidth). Unlike Bluetooth that is always on, BLE remains in sleep mode constantly except for when a connection is initiated.<\/p>\n\n\n\n<p>This makes it consume very low power. BLE consumes approximately 100x less power than Bluetooth (depending on the use case).<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><img data-recalc-dims=\"1\" decoding=\"async\" width=\"1200\" height=\"363\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/06\/BLE-Intro.png?resize=1200%2C363&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"\" class=\"wp-image-63555\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/06\/BLE-Intro.png?w=1532&amp;quality=100&amp;strip=all&amp;ssl=1 1532w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/06\/BLE-Intro.png?resize=300%2C91&amp;quality=100&amp;strip=all&amp;ssl=1 300w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/06\/BLE-Intro.png?resize=768%2C233&amp;quality=100&amp;strip=all&amp;ssl=1 768w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/06\/BLE-Intro.png?resize=1024%2C310&amp;quality=100&amp;strip=all&amp;ssl=1 1024w\" sizes=\"(max-width: 1200px) 100vw, 1200px\" \/><\/figure><\/div>\n\n\n<p>Additionally, BLE supports not only point-to-point communication, but also broadcast mode, and mesh network.<\/p>\n\n\n\n<p>Take a look at the table below that compares BLE and <a href=\"https:\/\/randomnerdtutorials.com\/esp32-bluetooth-classic-arduino-ide\/\">Bluetooth Classic<\/a> in more detail.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><img data-recalc-dims=\"1\" decoding=\"async\" width=\"818\" height=\"650\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/06\/Bluetooth-vs-BLE.png?resize=818%2C650&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"\" class=\"wp-image-63553\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/06\/Bluetooth-vs-BLE.png?w=818&amp;quality=100&amp;strip=all&amp;ssl=1 818w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/06\/Bluetooth-vs-BLE.png?resize=300%2C238&amp;quality=100&amp;strip=all&amp;ssl=1 300w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/06\/Bluetooth-vs-BLE.png?resize=768%2C610&amp;quality=100&amp;strip=all&amp;ssl=1 768w\" sizes=\"(max-width: 818px) 100vw, 818px\" \/><\/figure><\/div>\n\n\n<p><a href=\"https:\/\/www.bluetooth.com\/bluetooth-technology\/radio-versions\" target=\"_blank\" rel=\"noreferrer noopener\">View Image Souce<\/a><\/p>\n\n\n\n<p>Due to its properties, BLE is suitable&nbsp;for applications that need to exchange small amounts of data periodically running on a coin cell. For example, BLE is of great use in healthcare, fitness, tracking, beacons, security, and home automation industries.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"750\" height=\"189\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/06\/ble-applications.png?resize=750%2C189&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"\" class=\"wp-image-63554\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/06\/ble-applications.png?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/06\/ble-applications.png?resize=300%2C76&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 750px) 100vw, 750px\" \/><\/figure><\/div>\n\n\n<h2 class=\"wp-block-heading\">BLE Server and Client<\/h2>\n\n\n\n<p>With Bluetooth Low Energy, there are two types of devices: the server and the client. The ESP32 can act either as a client or as a server.<\/p>\n\n\n\n<p>The server advertises its existence, so it can be found by other devices, and contains the data that the client can read. The client scans the nearby devices, and when it finds the server it is looking for, it establishes a connection and listens for incoming data. This is called point-to-point communication.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"1200\" height=\"244\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/06\/BLE-server-and-client.png?resize=1200%2C244&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"\" class=\"wp-image-63556\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/06\/BLE-server-and-client.png?w=1640&amp;quality=100&amp;strip=all&amp;ssl=1 1640w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/06\/BLE-server-and-client.png?resize=300%2C61&amp;quality=100&amp;strip=all&amp;ssl=1 300w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/06\/BLE-server-and-client.png?resize=768%2C156&amp;quality=100&amp;strip=all&amp;ssl=1 768w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/06\/BLE-server-and-client.png?resize=1024%2C209&amp;quality=100&amp;strip=all&amp;ssl=1 1024w\" sizes=\"(max-width: 1200px) 100vw, 1200px\" \/><\/figure><\/div>\n\n\n<p>As mentioned previously, BLE also supports broadcast mode and mesh network:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Broadcast mode<\/strong>: the server transmits data to many clients that are connected;<\/li>\n\n\n\n<li><strong>Mesh network<\/strong>: all the devices are connected, this is a many to many connection.<\/li>\n<\/ul>\n\n\n\n<p>Even though the broadcast and mesh network setups are possible to implement, they were developed very recently, so there aren\u2019t many examples implemented for the ESP32 at this moment.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">GATT<\/h2>\n\n\n\n<p>GATT stands for Generic Attributes and it defines an hierarchical data structure that is exposed to connected BLE devices. This means that GATT defines the way that two BLE devices send and receive standard messages.&nbsp;Understanding this hierarchy is important, because it will make it easier to understand how to use the BLE and write your applications.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"750\" height=\"421\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/06\/GATT-BLE-ESP32.png?resize=750%2C421&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"\" class=\"wp-image-63558\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/06\/GATT-BLE-ESP32.png?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/06\/GATT-BLE-ESP32.png?resize=300%2C168&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 750px) 100vw, 750px\" \/><\/figure><\/div>\n\n\n<h3 class=\"wp-block-heading\">BLE Service<\/h3>\n\n\n\n<p>The top level of the hierarchy is a profile, which is composed of one or more services. Usually, a BLE device contains more than one service.<\/p>\n\n\n\n<p>Every service contains at least one characteristic, or can also reference other services. A&nbsp;service is simply a collection of information, like sensor readings, for example. <\/p>\n\n\n\n<p>There are predefined services for several types of data defined by the SIG (Bluetooth Special Interest Group) like: Battery Level, Blood Pressure, Heart Rate, Weight Scale, etc. You can <a rel=\"noreferrer noopener\" href=\"https:\/\/www.bluetooth.com\/specifications\/gatt\/services\" target=\"_blank\">check here other defined services<\/a>.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"863\" height=\"596\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/06\/gatt-services.png?resize=863%2C596&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"\" class=\"wp-image-63560\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/06\/gatt-services.png?w=863&amp;quality=100&amp;strip=all&amp;ssl=1 863w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/06\/gatt-services.png?resize=300%2C207&amp;quality=100&amp;strip=all&amp;ssl=1 300w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/06\/gatt-services.png?resize=768%2C530&amp;quality=100&amp;strip=all&amp;ssl=1 768w\" sizes=\"(max-width: 863px) 100vw, 863px\" \/><\/figure><\/div>\n\n\n<p><a href=\"https:\/\/www.bluetooth.com\/specifications\/gatt\/services\" target=\"_blank\" rel=\"noreferrer noopener\">View Image Souce<\/a><\/p>\n\n\n\n<h3 class=\"wp-block-heading\">BLE Characteristic<\/h3>\n\n\n\n<p>The characteristic is always owned by a service, and it is where the actual data is contained in the hierarchy (value). The characteristic always has two attributes: characteristic declaration (that provides metadata about the data) and the characteristic value.<\/p>\n\n\n\n<p>Additionally, the characteristic value can be followed by descriptors, which further expand on the metadata contained in the characteristic declaration.<\/p>\n\n\n\n<p>The properties describe how the characteristic value can be interacted with. Basically, it contains the operations and procedures that can be used with the characteristic:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Broadcast<\/li>\n\n\n\n<li>Read<\/li>\n\n\n\n<li>Write without response<\/li>\n\n\n\n<li>Write<\/li>\n\n\n\n<li>Notify<\/li>\n\n\n\n<li>Indicate<\/li>\n\n\n\n<li>Authenticated Signed Writes<\/li>\n\n\n\n<li>Extended Properties<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">UUID<\/h3>\n\n\n\n<p>Each service, characteristic and descriptor have an UUID (Universally Unique Identifier). An UUID is a unique 128-bit (16 bytes) number. For example:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"><strong>55072829-bc9e-4c53-938a-74a6d4c78776<\/strong><\/pre>\n\n\n\n<p>There are shortened UUIDs for all types, services, and profiles specified in the <a href=\"https:\/\/www.bluetooth.com\/specifications\/gatt\/services\" target=\"_blank\" rel=\"noreferrer noopener\">SIG (Bluetooth Special Interest Group)<\/a>.<\/p>\n\n\n\n<p>But if your application needs its own UUID, you can generate it using this <a href=\"https:\/\/www.uuidgenerator.net\/\" target=\"_blank\" rel=\"noreferrer noopener\">UUID generator website<\/a>.<\/p>\n\n\n\n<p>In summary, the UUID is used to uniquely identify information. For example, it can identify a particular service provided by a Bluetooth device.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">BLE with ESP32<\/h2>\n\n\n\n<p>The ESP32 can act as a BLE server or as a BLE client. There are several BLE examples for the ESP32 in the&nbsp;<a href=\"https:\/\/github.com\/nkolban\/ESP32_BLE_Arduino\" target=\"_blank\" rel=\"noreferrer noopener\">ESP32 BLE library for Arduino IDE<\/a>. This library comes installed by default when you install the ESP32 on the Arduino IDE.<\/p>\n\n\n\n<p><strong>Note<\/strong>: You need to have the ESP32 add-on installed on the Arduino IDE. Follow the next tutorial to prepare your Arduino IDE to work with the ESP32, if you haven\u2019t already.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/randomnerdtutorials.com\/installing-esp32-arduino-ide-2-0\/\" title=\"\">Installing ESP32 Board in Arduino IDE 2 (Windows, Mac OS X, Linux)<\/a><\/li>\n<\/ul>\n\n\n\n<p>In your Arduino IDE, you can go to&nbsp;<strong>File<\/strong> &gt; <strong>Examples<\/strong> &gt; <strong>BLE<\/strong> and explore the examples that come with the BLE library.<\/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=\"750\" height=\"713\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2019\/05\/ESP32-File-Examples-BLE-Arduino.png?resize=750%2C713&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"ESP32 Bluetooth Low Energy examples in the Arduino IDE\" class=\"wp-image-158761\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2019\/05\/ESP32-File-Examples-BLE-Arduino.png?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2019\/05\/ESP32-File-Examples-BLE-Arduino.png?resize=300%2C285&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 750px) 100vw, 750px\" \/><\/figure><\/div>\n\n\n<p><strong>Note:<\/strong> to see the ESP32 examples, you must have the ESP32 board selected on&nbsp;<strong>Tools<\/strong> &gt;&nbsp;<strong>Board<\/strong>.<\/p>\n\n\n\n<p>For a brief introduction to the ESP32 with BLE on the Arduino IDE, we&#8217;ll create an ESP32 BLE server, and then an ESP32 BLE scanner to find that server. We&#8217;ll use and explain the examples that come with the BLE library.<\/p>\n\n\n\n<p>To follow this example, you need two ESP32 development boards. We&#8217;ll be using the&nbsp;<a href=\"https:\/\/makeradvisor.com\/tools\/esp32-dev-board-wi-fi-bluetooth\/\" target=\"_blank\" rel=\"noreferrer noopener\">ESP32 DOIT DEVKIT V1 Board<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">ESP32 BLE Server<\/h2>\n\n\n\n<p>To create an ESP32 BLE Server, open your Arduino IDE and go to&nbsp;<strong>File<\/strong> &gt; <strong>Examples<\/strong> &gt; <strong>BLE<\/strong> and select the <strong>Server<\/strong> example. The following code should load:<\/p>\n\n\n<pre style=\"max-height: 40em; margin-bottom: 20px;\"><code class=\"language-c\">\/*\n  Complete Getting Started Guide: https:\/\/RandomNerdTutorials.com\/esp32-bluetooth-low-energy-ble-arduino-ide\/\n  Based on Neil Kolban example for IDF: https:\/\/github.com\/nkolban\/esp32-snippets\/blob\/master\/cpp_utils\/tests\/BLE%20Tests\/SampleServer.cpp\n  Ported to Arduino ESP32 by Evandro Copercini\n*\/\n\n#include &lt;BLEDevice.h&gt;\n#include &lt;BLEUtils.h&gt;\n#include &lt;BLEServer.h&gt;\n\n\/\/ See the following for generating UUIDs:\n\/\/ https:\/\/www.uuidgenerator.net\/\n\n#define SERVICE_UUID        &quot;4fafc201-1fb5-459e-8fcc-c5c9c331914b&quot;\n#define CHARACTERISTIC_UUID &quot;beb5483e-36e1-4688-b7f5-ea07361b26a8&quot;\n\nvoid setup() {\n  Serial.begin(115200);\n  Serial.println(&quot;Starting BLE work!&quot;);\n\n  BLEDevice::init(&quot;MyESP32&quot;);\n  BLEServer *pServer = BLEDevice::createServer();\n  BLEService *pService = pServer-&gt;createService(SERVICE_UUID);\n  BLECharacteristic *pCharacteristic = pService-&gt;createCharacteristic(\n                                         CHARACTERISTIC_UUID,\n                                         BLECharacteristic::PROPERTY_READ |\n                                         BLECharacteristic::PROPERTY_WRITE\n                                       );\n\n  pCharacteristic-&gt;setValue(&quot;Hello World says Neil&quot;);\n  pService-&gt;start();\n  \/\/ BLEAdvertising *pAdvertising = pServer-&gt;getAdvertising();  \/\/ this still is working for backward compatibility\n  BLEAdvertising *pAdvertising = BLEDevice::getAdvertising();\n  pAdvertising-&gt;addServiceUUID(SERVICE_UUID);\n  pAdvertising-&gt;setScanResponse(true);\n  pAdvertising-&gt;setMinPreferred(0x06);  \/\/ functions that help with iPhone connections issue\n  pAdvertising-&gt;setMinPreferred(0x12);\n  BLEDevice::startAdvertising();\n  Serial.println(&quot;Characteristic defined! Now you can read it in your phone!&quot;);\n}\n\nvoid loop() {\n  \/\/ put your main code here, to run repeatedly:\n  delay(2000);\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_server.ino\" target=\"_blank\">View raw code<\/a><\/p>\n\n\n\n<p>For creating a BLE server, the code should follow the next steps:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Create a BLE Server. In this case, the ESP32 acts as a BLE server.<\/li>\n\n\n\n<li>Create a BLE Service.<\/li>\n\n\n\n<li>&nbsp;Create a BLE Characteristic on the Service.<\/li>\n\n\n\n<li>Create a BLE Descriptor on the Characteristic.<\/li>\n\n\n\n<li>Start the Service.<\/li>\n\n\n\n<li>&nbsp;Start advertising, so it can be found by other devices.<\/li>\n<\/ol>\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 BLE server example code works.<\/p>\n\n\n\n<p>It starts by importing the necessary libraries for the BLE capabilities.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>#include &lt;BLEDevice.h&gt;\n#include &lt;BLEUtils.h&gt;\n#include &lt;BLEServer.h&gt;<\/code><\/pre>\n\n\n\n<p>Then, you need to define a UUID for the Service and Characteristic.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>#define SERVICE_UUID \"4fafc201-1fb5-459e-8fcc-c5c9c331914b\"\n#define CHARACTERISTIC_UUID \"beb5483e-36e1-4688-b7f5-ea07361b26a8\"<\/code><\/pre>\n\n\n\n<p>You can leave the default UUIDs, or you can go to&nbsp;<a href=\"https:\/\/www.uuidgenerator.net\/\" target=\"_blank\" rel=\"noreferrer noopener\">uuidgenerator.net<\/a>&nbsp;to create random UUIDs for your services and characteristics.<\/p>\n\n\n\n<p>In the <span class=\"rnthl rntliteral\">setup()<\/span>, it starts the serial communication at a baud rate of 115200.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>Serial.begin(115200);<\/code><\/pre>\n\n\n\n<p>Then, you create a BLE device called \u201c<strong>MyESP32<\/strong>\u201d. You can change this name to whatever you like.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>\/\/ Create the BLE Device\nBLEDevice::init(\"MyESP32\");<\/code><\/pre>\n\n\n\n<p>In the following line, you set the BLE device as a server.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>BLEServer *pServer = BLEDevice::createServer();<\/code><\/pre>\n\n\n\n<p>After that, you create a service for the BLE server with the UUID defined earlier.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code> BLEService *pService = pServer-&gt;createService(SERVICE_UUID);<\/code><\/pre>\n\n\n\n<p>Then, you set the characteristic for that service. As you can see, you also use the UUID defined earlier, and you need to pass as arguments the characteristic&#8217;s properties. In this case, it\u2019s: READ and WRITE.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>BLECharacteristic *pCharacteristic = pService-&gt;createCharacteristic(\n                                     CHARACTERISTIC_UUID,\n                                     BLECharacteristic::PROPERTY_READ |\n                                     BLECharacteristic::PROPERTY_WRITE\n                                     );<\/code><\/pre>\n\n\n\n<p>After creating the characteristic, you can set its value with the <span class=\"rnthl rntliteral\">setValue()<\/span> method.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>pCharacteristic-&gt;setValue(\"Hello World says Neil\");<\/code><\/pre>\n\n\n\n<p>In this case we&#8217;re setting the value to the text &#8220;Hello World says Neil&#8221;. You can change this text to whatever your like. In future projects, this text can be a sensor reading, or the state of a lamp, for example.<\/p>\n\n\n\n<p>Finally, you can start the service, and the advertising, so other BLE devices can scan and find this BLE device.<\/p>\n\n\n\n<pre class=\"wp-block-code language-c\"><code>BLEAdvertising *pAdvertising = pServer-&gt;getAdvertising();\npAdvertising-&gt;start();<\/code><\/pre>\n\n\n\n<p>This is just a simple example on how to create a BLE server. In this code nothing is done in the <span class=\"rnthl rntliteral\">loop()<\/span>, but you can add what happens when a new client connects (check the <em>Notify <\/em>example for some guidance).<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">ESP32 BLE Scanner<\/h2>\n\n\n\n<p>Creating an ESP32 BLE scanner is simple. Grab another ESP32 (while the other is running the BLE server sketch). In your Arduino IDE, go to&nbsp;<strong>File &gt;&nbsp;Examples<\/strong> &gt;&nbsp;<strong>BLE<\/strong> and select the <strong>Scan<\/strong> example. The following code should load.<\/p>\n\n\n<pre style=\"max-height: 40em; margin-bottom: 20px;\"><code class=\"language-c\">\/*\n  Complete Getting Started Guide: https:\/\/RandomNerdTutorials.com\/esp32-bluetooth-low-energy-ble-arduino-ide\/\n  Based on Neil Kolban example for IDF: https:\/\/github.com\/nkolban\/esp32-snippets\/blob\/master\/cpp_utils\/tests\/BLE%20Tests\/SampleScan.cpp\n  Ported to Arduino ESP32 by Evandro Copercini\n*\/\n\n#include &lt;BLEDevice.h&gt;\n#include &lt;BLEUtils.h&gt;\n#include &lt;BLEScan.h&gt;\n#include &lt;BLEAdvertisedDevice.h&gt;\n\nint scanTime = 5; \/\/ in seconds\nBLEScan* pBLEScan;\n\nclass MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks {\n  void onResult(BLEAdvertisedDevice advertisedDevice) {\n    Serial.printf(&quot;Advertised Device: %s \\n&quot;, advertisedDevice.toString().c_str());\n  }\n};\n\nvoid setup() {\n  Serial.begin(115200);\n  Serial.println(&quot;Scanning...&quot;);\n\n  BLEDevice::init(&quot;&quot;);\n  pBLEScan = BLEDevice::getScan(); \/\/create new scan\n  pBLEScan-&gt;setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());\n  pBLEScan-&gt;setActiveScan(true); \/\/active scan uses more power, but get results faster\n  pBLEScan-&gt;setInterval(100);\n  pBLEScan-&gt;setWindow(99);  \/\/ less or equal setInterval value\n}\n\nvoid loop() {\n  \/\/ put your main code here, to run repeatedly:\n  BLEScanResults *foundDevices = pBLEScan-&gt;start(scanTime, false);\n  Serial.print(&quot;Devices found: &quot;);\n  Serial.println(foundDevices-&gt;getCount());\n  Serial.println(&quot;Scan done!&quot;);\n  pBLEScan-&gt;clearResults();   \/\/ delete results fromBLEScan buffer to release memory\n  delay(2000);\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_scan.ino\" target=\"_blank\">View raw code<\/a><\/p>\n\n\n\n<p>This code initializes the ESP32 as a BLE device and scans for nearby devices. Upload this code to your ESP32. You might want to temporarily disconnect the other ESP32 from your computer, so you\u2019re sure that you\u2019re uploading the code to the right ESP32 board.<\/p>\n\n\n\n<p>Once the code is uploaded and you should have the two ESP32 boards powered on:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>One ESP32 with the \u201cBLE_server\u201d sketch;<\/li>\n\n\n\n<li>Other with ESP32 \u201cBLE_scan\u201d sketch.<\/li>\n<\/ul>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"750\" height=\"393\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/06\/scan-server-esp32.jpg?resize=750%2C393&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"ESP32 Board BLE Scanner and Server communication\" class=\"wp-image-63601\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/06\/scan-server-esp32.jpg?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/06\/scan-server-esp32.jpg?resize=300%2C157&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 750px) 100vw, 750px\" \/><\/figure><\/div>\n\n\n<p>Go to the Serial Monitor with the ESP32 running the \u201cBLE_scan\u201d example, press the ESP32 (with the \u201cBLE_scan\u201d sketch) ENABLE button to restart and wait a few seconds while it scans.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"750\" height=\"690\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/06\/esp32-scan-enable-button.jpg?resize=750%2C690&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"ESP32 Board BLE Scanner and Server communication demonstration\" class=\"wp-image-63597\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/06\/esp32-scan-enable-button.jpg?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/06\/esp32-scan-enable-button.jpg?resize=300%2C276&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 750px) 100vw, 750px\" \/><\/figure><\/div>\n\n\n<p>The scanner found two devices: one is the ESP32 (it has the name &#8220;<strong>MyESP32<\/strong>&#8220;), and the other is a smart watch.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"753\" height=\"443\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/06\/esp32-scan.jpg?resize=753%2C443&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"ESP32 Board BLE Scanner and Server communication demonstration Arduino IDE\" class=\"wp-image-63595\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/06\/esp32-scan.jpg?w=753&amp;quality=100&amp;strip=all&amp;ssl=1 753w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/06\/esp32-scan.jpg?resize=300%2C176&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 753px) 100vw, 753px\" \/><\/figure><\/div>\n\n\n<h2 class=\"wp-block-heading\">Testing the ESP32 BLE Server with Your Smartphone<\/h2>\n\n\n\n<p>Most modern smartphones should have BLE capabilities. I was using a\u00a0<a href=\"https:\/\/makeradvisor.com\/oneplus-5-review-best-value-smartphone\/\" target=\"_blank\" rel=\"noreferrer noopener\">OnePlus<\/a>, but most smartphones should also work.<\/p>\n\n\n\n<p>You can scan your ESP32 BLE server with your smartphone and see its services and characteristics. For that, we&#8217;ll&nbsp;be using a free app called&nbsp;<strong>nRF Connect for Mobile<\/strong>&nbsp;from Nordic, it works on&nbsp;<a href=\"https:\/\/play.google.com\/store\/apps\/details?id=no.nordicsemi.android.mcp\" target=\"_blank\" rel=\"noreferrer noopener\">Android (Google Play Store)<\/a>&nbsp;and&nbsp;<a href=\"https:\/\/itunes.apple.com\/us\/app\/nrf-connect\/id1054362403?mt=8\" target=\"_blank\" rel=\"noreferrer noopener\">iOS (App Store)<\/a>.<\/p>\n\n\n\n<p>Go to Google Play Store or App Store and search for \u201cnRF Connect for Mobile\u201d. Install the app and open it.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><img data-recalc-dims=\"1\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/rntlab.com\/wp-content\/uploads\/2018\/02\/nRF-connect.jpg?w=1200&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"nRF Connect for Mobile\u00a0from Nordic\" class=\"wp-image-7291\"\/><\/figure><\/div>\n\n\n<p>Don\u2019t forget go to the Bluetooth settings and enable Bluetooth adapter in your smartphone. You may also want to make it visible to other devices to test other sketches later on.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><img data-recalc-dims=\"1\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/rntlab.com\/wp-content\/uploads\/2018\/02\/enable-bluetooth-nrf-e1519725728543.jpg?w=1200&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"nRF Connect for Mobile\u00a0from Nordic enable\" class=\"wp-image-7285\"\/><\/figure><\/div>\n\n\n<p>Once everything is ready in your smartphone and the ESP32 is running the BLE server sketch, in the app, tap the scan button to scan for nearby devices. You should find an ESP32 with the name \u201c<strong>MyESP32<\/strong>\u201d.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"750\" height=\"672\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/06\/ble-server-found.jpg?resize=750%2C672&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"nRF Connect for Mobile\u00a0from Nordic connect to myESP32\" class=\"wp-image-63605\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/06\/ble-server-found.jpg?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/06\/ble-server-found.jpg?resize=300%2C269&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 750px) 100vw, 750px\" \/><\/figure><\/div>\n\n\n<p>Click the \u201c<strong>Connect<\/strong>\u201d button.<\/p>\n\n\n\n<p>As you can see in the figure below, the ESP32 has a service with the UUID that you\u2019ve defined earlier. If you tap the service, it expands the menu and shows the Characteristic with the UUID that you\u2019ve also defined.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"450\" height=\"599\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/06\/BLE-server-service.jpg?resize=450%2C599&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"nRF Connect for Mobile\u00a0from Nordic check UUID\" class=\"wp-image-63607\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/06\/BLE-server-service.jpg?w=450&amp;quality=100&amp;strip=all&amp;ssl=1 450w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/06\/BLE-server-service.jpg?resize=225%2C300&amp;quality=100&amp;strip=all&amp;ssl=1 225w\" sizes=\"(max-width: 450px) 100vw, 450px\" \/><\/figure><\/div>\n\n\n<p>The characteristic has the READ and WRITE properties, and the value is the one you&#8217;ve previously defined in the BLE server sketch. So, everything is working fine.<\/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 the basic principles of Bluetooth Low Energy and shown you some examples with the ESP32. We&#8217;ve explored the BLE server sketch and the BLE scan sketch. These are simple examples to get you started with BLE.<\/p>\n\n\n\n<p>The idea is using BLE to send or receive sensor readings from other devices.<\/p>\n\n\n\n<p>Other Bluetooth-related tutorials that you may like:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/randomnerdtutorials.com\/esp32-bluetooth-guide\/\">ESP32 with Bluetooth and Bluetooth Low Energy: The Ultimate Guide<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/randomnerdtutorials.com\/esp32-ble-server-client\/\">ESP32 BLE Server and Client (Bluetooth Low Energy)<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/randomnerdtutorials.com\/esp32-wi-fi-provisioning-ble-arduino\/\">ESP32 Wi-Fi Provisioning via BLE (Bluetooth Low Energy) \u2013 Arduino IDE<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/randomnerdtutorials.com\/esp32-web-bluetooth\/\">ESP32 Web Bluetooth (BLE): Getting Started Guide<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/randomnerdtutorials.com\/esp32-bluetooth-classic-arduino-ide\/\">ESP32 Bluetooth Classic with Arduino IDE \u2013 Getting Started<\/a><\/li>\n<\/ul>\n\n\n\n<p><em>This is an excerpt from our course:&nbsp;<a href=\"https:\/\/randomnerdtutorials.com\/learn-esp32-with-arduino-ide\/\">Learn ESP32 with Arduino IDE<\/a>. If you like ESP32 and you want to learn more about it, we recommend enrolling in&nbsp;<a href=\"https:\/\/randomnerdtutorials.com\/learn-esp32-with-arduino-ide\/\">Learn ESP32 with Arduino IDE course<\/a>.<\/em><\/p>\n\n\n\n<p><strong>You might also like reading:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong><a href=\"https:\/\/randomnerdtutorials.com\/learn-esp32-with-arduino-ide\/\">Learn ESP32 with Arduino IDE<\/a><\/strong><\/li>\n\n\n\n<li><a href=\"https:\/\/randomnerdtutorials.com\/esp32-bluetooth-classic-arduino-ide\/\">ESP32 Bluetooth Classic with Arduino IDE \u2013 Getting Started<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/randomnerdtutorials.com\/esp32-data-logging-temperature-to-microsd-card\/\">ESP32 Data Logging Temperature to MicroSD Card<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/randomnerdtutorials.com\/esp32-dc-motor-l298n-motor-driver-control-speed-direction\/\">ESP32 with DC Motor and L298N Motor Driver \u2013 Control Speed and Direction<\/a><\/li>\n<\/ul>\n\n\n\n<p>Thanks for reading.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>The ESP32 comes not only with Wi-Fi but also with Bluetooth and Bluetooth Low Energy (BLE). This post is a quick introduction to BLE with the ESP32. First, we&#8217;ll explore &#8230; <\/p>\n<p class=\"read-more-container\"><a title=\"Getting Started with ESP32 Bluetooth Low Energy (BLE) on Arduino IDE\" class=\"read-more button\" href=\"https:\/\/randomnerdtutorials.com\/esp32-bluetooth-low-energy-ble-arduino-ide\/#more-63505\" aria-label=\"Read more about Getting Started with ESP32 Bluetooth Low Energy (BLE) on Arduino IDE\">CONTINUE READING \u00bb<\/a><\/p>\n","protected":false},"author":5,"featured_media":158764,"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-63505","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\/06\/ESP32-BLE-Getting-Started-1.jpg?fit=1280%2C720&quality=100&strip=all&ssl=1","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/posts\/63505","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=63505"}],"version-history":[{"count":5,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/posts\/63505\/revisions"}],"predecessor-version":[{"id":158778,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/posts\/63505\/revisions\/158778"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/media\/158764"}],"wp:attachment":[{"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/media?parent=63505"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/categories?post=63505"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/tags?post=63505"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}