Esp32

ESP32 BLE (Bluetooth Low Energy) Tutorial Using Arduino IDE

ESP32 is an IOT based microcontroller board that comes with pre-installed WiFi and dual Bluetooth. Both WiFi and Bluetooth play a crucial role while exchanging data between devices over wireless communication.

ESP32 has support for both Bluetooth Classic and Bluetooth Low Energy. Here we will focus on Bluetooth Low Energy. Let’s see it in detail.

What is Bluetooth Low Energy

BLE or Bluetooth Low Energy is a power saving mode of Bluetooth. Its prime application includes data transfer over short distances such as door entry, smart watches, wearables, blood pressure monitor, security, and home automations. BLE can transfer limited data.

Unlike Bluetooth Classic which remains turned on for the whole time BLE remains in sleep mode except when it is called or connection is initiated. This makes the BLE very power efficient and consumes 100 times less power than the classic one.

Here is a brief comparison of Bluetooth Classic with Bluetooth Low Energy:

Specification Bluetooth Classic Bluetooth Low Energy/BLE
Data Transfer Rate 2-3Mbps 1Mbps
Range ~10-100m ~50m
Operating Frequency 79 RF 40 RF
Peak Current Consumption ~30mA <15mA
Power Consumption 1W 0.01-0.5W
Total Time to Send data 100ms 3ms
Applications Audio, music streaming Sensor, wearables

For a more detailed comparison click here to visit the official Bluetooth site.

BLE Server and Client

Bluetooth Low Energy supports the device in two different ways: server and client. ESP32 can act as server as well as client for Low Energy Bluetooth.

BLE support following modes of communication:

  • Point to Point: Communication between two points or nodes that is server and client.
  • Broadcast Mode: Server transmits data to many devices.
  • Mesh Network: Multiple devices connected also known as many to many connections.

When acting as a server, ESP32 advertises its existence to nearby client devices. Once the client devices scan for available Bluetooth devices the server establishes connection between them and transfers the data from server to client device. This communication is called point to point.

In this tutorial, we will take an example of point-to-point communication between two ESP32 boards.

Important Terms in BLE

Here are some important terms which one should know while working with ESP32 BLE applications:

GATT: GATT or Generic attributes which defines a hierarchical structure for data transfers between BLE devices using Service and Characteristic. It defines the way two devices communicate data between them.

BLE Service: Top level inside the GATT hierarchy is a profile which contains one or more services. BLE contains more than a single service. Each of these services have their own Characteristics which can also act as reference for other services.

BLE Characteristic: Characteristic is a group of information always owned by Service; it is where actual data is stored in hierarchy (value). It always contains two attributes:

  • Declaration: Characteristic properties such as location, type, read, write, and notify.
  • Characteristic Value: Data value of Characteristic.

UUID: UUID (Universally Unique Identifier) is a unique ID given to a service and Characteristic. It is a unique 128-bit ID which can be generated using any online UUID generator. Check this free UUID generator. A sample UUID looks like this:

583f8b30-74b4-4757-8143-56048fd88b25

Graphical user interface, text, website Description automatically generated

A universal Bluetooth Special Interest Group (SIG) has predefined some of the shortened UUIDs for different types of services and profile to read them click here.

Set up BLE in ESP32 with Arduino IDE

To understand the working of BLE we will be using two different ESP32 boards one of them will act as server and advertise a Bluetooth signal while the other ESP32 which is acting as a client will try to connect the server Bluetooth.

Arduino IDE has separate examples for both Scanner and Server.

To see how to install an ESP32 with Arduino IDE in windows click here.

ESP32 BLE Server

First, we will upload server example code inside our first ESP32 board which is acting as a server.

To open BLE server example Go to: File>Examples>ESP32 BLE Arduino>BLE_server:

The below given code will be opened in Arduino IDE.

Server Code

Upload the below code in ESP32 board using Arduino IDE. But make sure to disconnect the second board for a while to avoid uploading the same code to a single board.

#include <BLEDevice.h>

#include <BLEUtils.h>

#include <BLEServer.h>

#define SERVICE_UUID        "4fafc201-1fb5-459e-8fcc-c5c9c331914b"
#define CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a8"
void setup() {
  Serial.begin(115200);
  Serial.println("Starting BLE work!");
  BLEDevice::init("ESP32");
  BLEServer *pServer = BLEDevice::createServer();
  BLEService *pService = pServer->createService(SERVICE_UUID);
  BLECharacteristic *pCharacteristic = pService->createCharacteristic(
  CHARACTERISTIC_UUID,
  BLECharacteristic::PROPERTY_READ |
  BLECharacteristic::PROPERTY_WRITE
  );
  pCharacteristic->setValue("HELLO Say Linuxhint.com");
  pService->start();
  // BLEAdvertising *pAdvertising = pServer->getAdvertising();/*backward compatibility*/
  BLEAdvertising *pAdvertising = BLEDevice::getAdvertising();
  pAdvertising->addServiceUUID(SERVICE_UUID);
  pAdvertising->setScanResponse(true);
  pAdvertising->setMinPreferred(0x06);  // functions for iphone connection
  pAdvertising->setMinPreferred(0x12);
  BLEDevice::startAdvertising();
  Serial.println("Characteristic defined! BLE Server Ready");
}
void loop() {
  delay(2000);
}

Code starts with including necessary Bluetooth library files. Then UUID is defined for both SERVICE and CHARACTERISTIC. You can go with the default UUID or can generate using the free UUID generator. Next serial communication is initialized by defining baud rate.

Next, we created a BLE device named ESP32. After that we defined the BLE device as a server using the createServer() function and later we set the Characteristic value. At the final step we started the service by advertising it so other devices can search for it.

ESP32 BLE Scanner

Now we will upload an ESP32 scan example in the second ESP32 board. To do this Go to: File>Examples>ESP32 BLE Arduino>BLE_scan

The code below will be open in Arduino IDE editor.

Scanner Code

#include <BLEDevice.h>

#include <BLEUtils.h>

#include <BLEScan.h>

#include <BLEAdvertisedDevice.h>

int scanTime = 5; //In seconds
BLEScan* pBLEScan;
class MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks {
void onResult(BLEAdvertisedDevice advertisedDevice) {
Serial.printf("Advertised Device: %s \n", advertisedDevice.toString().c_str());
}
};
void setup() {
  Serial.begin(115200);
  Serial.println("Scanning...");
  BLEDevice::init("");
  pBLEScan = BLEDevice::getScan(); //create new scan
  pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());
  pBLEScan->setActiveScan(true); //fast scan but more power used
  pBLEScan->setInterval(100);
  pBLEScan->setWindow(99);  
}
void loop() {
  // put your main code here, to run repeatedly:
  BLEScanResults foundDevices = pBLEScan->start(scanTime, false);
  Serial.print("Devices found: ");
  Serial.println(foundDevices.getCount());
  Serial.println("Scan done!");
  pBLEScan->clearResults();   // delete results to free memory
  delay(2000);
}

Above code will search for the number of total available devices for BLE and display their total count with addresses. After uploading the code in the ESP32 scanner board press the Enable button, ESP32 board will automatically search for available devices.

Output

Once the ESP32 scans the available devices the following result will appear. Here ESP32 scanned 9 devices among which one is an ESP32 board with BLE_server code and another device is MI band 6. Rest of all the devices are available near my ESP32.

How to Fix ESP32 BLE Scan Library Not Counting Devices

The ESP32 scan library example has a bug of not counting the total number of devices. To rectify this problem, go to the mentioned location and replace the code given below.

C:\Users\username\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.6\libraries\BLE\src\BLEScan.cpp

Remember to unhide all the folders because the AppData folder inside the C directory remains hidden by default. After opening the BLE_scan source file .cpp replace the below given condition inside the code.

if (m_pAdvertisedDeviceCallbacks) {
m_pAdvertisedDeviceCallbacks->onResult(*advertisedDevice);
}
if (!m_wantDuplicates && !found) {  
m_scanResults.m_vectorAdvertisedDevices.insert(std::pair(advertisedAddress.toString(), advertisedDevice));
shouldDelete = false;
}

Testing ESP32 BLE Server with Smart Phone

Most of the modern smartphones work with BLE technology to communicate with different devices such as smartwatch, wearables, sensors, and other home automation devices. Here the ESP32 board will act as an access point. So, we will connect an Android phone with an ESP32 board.

BLE Server Code for ESP32 Smartphone Access

Upload the below given code in ESP32 board.

#include <BLEDevice.h> /*Bluetooth library included*/

#include <BLEUtils.h>

#include <BLEServer.h>

#define SERVICE_UUID        "a484a399-7272-4282-91cf-9018e075fc35"
#define CHARACTERISTIC_UUID "c7e084bd-5279-484d-8319-fff7d917537d"
class MyCallbacks: public BLECharacteristicCallbacks
{
  void onWrite(BLECharacteristic *pCharacteristic)
  {
    std::string value = pCharacteristic->getValue();
    if (value.length() > 0)
    {
      Serial.print("Updated Characteristic Value: ");
      for (int i = 0; i createService(SERVICE_UUID);
  BLECharacteristic *pCharacteristic = pService->createCharacteristic(
CHARACTERISTIC_UUID,
BLECharacteristic::PROPERTY_READ |
BLECharacteristic::PROPERTY_WRITE
);
pCharacteristic->setCallbacks(new MyCallbacks());
pCharacteristic->setValue("LINUXHINT.COM");
pService->start();
BLEAdvertising *pAdvertising = pServer->getAdvertising();
pAdvertising->start();
}
void loop()
{
  delay(2000);
}

Installing BLE Application in Android Smartphone

Following steps will guide you to installing BLE applications in smartphones and help to interface mobile devices with ESP32 boards.

Step 1: Open Google Play Store install BLE scanner application.

Graphical user interface, application Description automatically generated

Step 2: After installing, open the application and allow all the required permission and remember to turn on mobile Bluetooth.

Graphical user interface, application Description automatically generated

Step 3: Now scan for the available Bluetooth devices. Connect ESP32 board.

Graphical user interface Description automatically generated with medium confidence

Step 4: Once ESP32 board is connected to smartphone following specification of ESP32 board will appear. Here we can see the UUID addresses and can READ and WRITE new Characteristic values.

Graphical user interface, application Description automatically generated

Step 5: To read the saved Characteristic value click R. Result will be displayed.

Step 6: To write any new Characteristic value click W.

Graphical user interface, application Description automatically generated

Step 7: A new popup will appear here we can write any Characteristic value and click Ok.

Step 8: New value which is written will appear.

Graphical user interface, text, application Description automatically generated

Step 9: Also, we can see the same new Characteristic value printed on the serial monitor of Arduino IDE.

Text Description automatically generated with medium confidence

We have successfully connected a device with ESP32 BLE.

Conclusion

ESP32 comes with dual Bluetooth that is Classic and Low Energy. Here in this article, we discussed BLE and its various applications and working. Later we configured BLE with two different ESP32 boards with one acting as server and other as scanner. At last, we connected our smartphone with the ESP32 server and wrote a new Characteristic value.

About the author

Kashif

I am an Electrical Engineer. I love to write about electronics. I am passionate about writing and sharing new ideas related to emerging technologies in the field of electronics.