Close this search box.


How to use BLE in ESP32? ESP32 BLE (Bluetooth Low Energy) Tutorial

In this tutorial, we will learn about the BLE feature in ESP32. ESP32 has Bluetooth low Energy or BLE feature along with Classic Bluetooth. ESP32 BLE is aimed at battery operated, low-power wireless communication between different BLE Devices. We will learn all the essentials in order to use BLE in ESP32 and configure it as both a Server and a Client. We will also see how can we connect a smart phone with ESP32 BLE Server.


A Brief Note on BLE (Bluetooth Low Energy)

The main feature of the Bluetooth 4.0 Specification was the integration of Bluetooth Low Energy or simply BLE. BLE (previously marketed as Bluetooth Smart) is a highly optimized version of Classic Bluetooth designed specifically for low power wireless communication.

While the Classic Bluetooth (often described as Basic Rate and Enhanced Dara Rate in technical documents referring to its data speeds) was designed as a replacement to wired communication with short-range wireless communication. It was designed with data speeds in mind and the applications include large file transfers, wireless audio, etc.

BLE on the other hand is optimized for low power consumption instead of higher data rates and is designed with IoT and battery-operated applications in mind. Some of the popular applications of BLE are smart watches, fitness trackers, health monitoring devices, radio beacons, etc.


Unlike Classic Bluetooth, which is always connected, the BLE is usually in standby (idle) mode and wakes up if and only if required. Hence, the ultra-low power consumption.

Bluetooth Low Energy also works on the same 2.4 GHz ISM frequency band. What this means is that a single antenna can be used for Wi-Fi and both the versions of Bluetooth.

Different Layers in BLE

A BLE device consists of three layers:

  • Controller
  • Host
  • Application


The controller contains the following:

  • PHY – The Physical Layer
  • LL – The Link Layer
  • HCI – Controller side Host-Controller Interface

The host contains the following:

  • HCI – Host side Host-Controller Interface
  • L2CAP – Logical Link Control and Application Protocol
  • SM – Security Manager
  • ATT – Attribute Protocol
  • GAP – Generic Access Profile
  • GATT – Generic Attribute Profile

The application layer is the highest layer which contains user interface, data handling and logical aspects of the application.

Important Terms in BLE

Let us briefly see some of the important terms associated with BLE.

  • GATT: It is short for Generic Attribute Profile. It defines the specifications for data transfer between BLE devices using Service and Characteristics.
  • Characteristic: Characteristic is a group of information called Attribute and Attribute is a group of information transferred between devices. A characteristic usually contains the following attributes:
  • Value: Data value of the characteristic
  • Declaration: Properties of the characteristic (location, type like read, write, notify, indicate etc.)
  • Description: ASCII String describing the characteristic.
  • Service: A collection of characteristics is called a Service. Each Service has a unique 16-bit or 128-bit ID called UUID.
  • UUID: Universally Unique Identifier is a 128-bit ID given to each service and characteristic in a profile. Use the website UUIDGenerator to generate unique IDs. Each service and characteristic has a unique 16-bit or 128-bit ID called UUID. A sample UUID looks something like this:
    •  583f8b30-74b4-4757-8143-56048fd88b25 

BLE States

A BLE device can have 5 possible states:

  • Standby
  • Advertising
  • Scanning
  • Initiating
  • Connected


BLE Network Topologies

The communication between two BLE devices can be either a Broadcast Type or a Connection Type. In broadcasting, the ‘broadcaster’ BLE Device sends data to any ‘observer’ BLE Device. It is a one-way data transfer.

For two-way communication, you need a ‘Connection’ between the BLE Devices. A Central (Master) BLE Device repeatedly scans for advertising data packets from Peripheral (Slave) BLE Device which sends the packets.

BLE in ESP32

We know that the main feature of ESP32 is Wi-Fi. But additionally, the ESP32 SoC also has Bluetooth support as well. ESP32 Bluetooth is a dual-mode system. This means ESP32 supports both Classic Bluetooth as well as Bluetooth Low Energy (BLE).

Specifically, the Bluetooth system in ESP32 is compliant with Bluetooth v4.2 Classic Bluetooth (BR/EDR) and BLE specifications. In the previous tutorial, we already explored how to use the ESP32 Classic Bluetooth with a couple of examples. We will explore the BLE feature of ESP32 in this tutorial.

ESP32 BLE Server Client Model

Any BLE Device can be configured as a Server or a Client. ESP32 is no exception to this i.e., ESP32 can be either a Server, which advertises its presence so that clients can read its data or as a Client, which scans for servers and makes a connection to receive data from the server.

In this project, we will use two ESP32 Boards, one programmed as BLE Server and the other as BLE Slave.[ESP32 Projects for Beginners]

ESP32 BLE Server

First, we will see how to setup an ESP32 as a BLE Server. Take an ESP32 Board and connect it to the computer. We will call this board as ‘ESP32-BLE_Server’. Open Arduino IDE and make sure that proper ESP32 Development Board and COM port is selected.


This is a slightly modified code of the ‘BLE_server’ example. I commented the code to explain all the necessary things.

Upload this code to the Server ESP32 Device.

ESP32 BLE Client

Take another ESP32 Board (which we will call ESP32-BLE_Client) and connect it to the computer. In the Arduino IDE, select the COM port for this board.


There is an example called ‘BLE_client’ as a part of the ESP32 BLE Library. I used the same code here (with small modifications). Upload this code to Client ESP32 Device.


After uploading codes to both the ESP32 Boards, you need to monitor the serial ports of both the boards to see the communication. For this, I am using the Arduino IDE’s Serial Monitor to open the COM port of the ESP32 BLE Client Device and another software (like Putty or Terminal) to open the serial port of ESP32 BLE Server Device.

After opening the respective serial port terminals for both ESP32 BLE Server and Client, reset both the boards by pressing respective ENABLE (EN) buttons.


The ESP32 BLE Server device will start the BLE Server and starts advertising its services. If you observe the Client ESP32’s Code, we used the Server ESP32’s Service UUID and Characteristic UUID. What this means is that the Client ESP32 scans for BLE devices and if the BLE with the particular UUIDs is found, then it makes a connection.

Once the connection is established, the ESP32 BLE Client first reads the characteristic value from the server (we set this as ‘Hello, World!’ in the Server’s code) and prints it on the terminal.

After that, the client tries to set the characteristic value of the server with a new value every couple of seconds. You can see the client’s terminal in the following image.

Coming to the Server, once it starts the BLE Server, it reads its own characteristic value every couple of seconds. You can see the following image that the Server’s characteristic value is updated by the client and is read by the server.


Testing ESP32 BLE Server with Smart Phone

Let us now see how can we connect our smart phones to an ESP32 BLE Server. Upload the following code to the ESP32 Board, which we will call ESP32 BLE Server and open the serial monitor in Arduino IDE.

In the smart phone, go to play store and install ‘BLE Scanner’ application by Bluepixel Technologies. After installing, open the app (if ESP32 Bluetooth is already paired before, then there is no need pair once again). Enable Bluetooth and Location (both are needed for scanning BLE devices) in the phone (the app will prompt the same). Click on the ‘scan’ icon on the top right corner.

The app will start scanning for BLE Devices and lists them out. You can see ‘ESP32-BLE-Server’ in the list.


Click on ‘CONNECT’ and smart phone starts connection with ESP32 BLE Server. Once connected, it will display the list of services and its characteristics. Since we have initialized ESP32 with only one service, you can see the Service UUID and also the Characteristic UUID under the ‘CUSTOM SERVICE’ section.


To read the initial characteristic value of the service, tap on the ‘R’ icon in the ‘CUSTOM SERVICE’ section. The app reads the value from the server and displays it in the ‘Value’ option.


Since we set the properties of the characteristic as both read and write, we can set the value of the characteristic just by tapping on the ‘W’ icon. A text box pops up to write the value. After entering the value, click on ‘OK’. The value is set in Server.


If you open the Serial Monitor of the Server, you can see the server prints out newly set value. Instead of continuously monitoring the ‘value’ field like we did in the previous example, we are actually using the callback feature of BLE Library, which will be called if and only if a ‘write’ option is initiated.



A complete beginner’s guide on understanding BLE in ESP32. You learn some basic features of Bluetooth Low Energy, how to use ESP32 BLE feature, how to setup ESP32 as BLE Server and Client and also how to connect a smart phone to ESP32 BLE Server.

This is just an introductory project with regards to ESP32 Bluetooth Low Energy. In the future, we will make use of BLE in ESP32 to implement several IoT related applications.

3 Responses

  1. First of all, congratulations on the article.
    I had previously tested with the Arduino IDE scketches, but your article makes it easier to understand.

    The reason for writing you is because I would like to be able to control the ESP32 via BLE from Alexa.
    I would like to be able to control about 5 LEDs with an ESP32, which understands the commands turn on led, turn off led, brightness at 25%.
    I don’t want to do the control via WIFI

    Thanks in advance for any comments on how to approach this project in a simple way.

  2. This example is great. I am interested in managing the connections for more than one device(server). Do I need more than one BLEClientCallbacks()? If not, how do I distinguish between different servers in the onDisconnect() and onConnect()? Is the pclient argument a pointer to the client or to the connected device? Any explanation of how these are used in a multiconnection environment would be appreciated.

  3. I am making an android app which will connect esp32 through ble the problem is that its not scanning because of not scanning i cant read and write ??ANY HELP?

Leave a Reply

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