Esp32

ESP32 Bluetooth – Ultimate Guide

ESP32 is a microcontroller-based board that comes with Wi-Fi and Bluetooth support. It is an IoT based board that can be integrated with multiple sensors to execute instructions. ESP32 board has a wide application where wireless communication is required.

ESP32 supports dual Bluetooth containing Bluetooth Classic and the Bluetooth Low Energy (BLE). In this article we will be discussing the working of both these Bluetooth.

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.

Following are the two Bluetooth modes available in ESP32 board:

1: ESP32 Bluetooth Classic with Arduino IDE

The ESP32 board comes with dual Bluetooth support one is Bluetooth Classic and the second one is BLE (Bluetooth Low Energy). Today we will be discussing Bluetooth Classic only. Only difference which exists between both of them is that Bluetooth Classic can handle a lot of data transfer but consumes battery at higher rate, however Bluetooth Low Energy is power conserving variant which is used for short distance communication. BLE stays in sleep mode until it is initialized for data transfer.

ESP32 Bluetooth Classic Serial Communication

ESP32 comes with built-in Bluetooth modules which first receive data and then forward it to the Xtensa processor. So, to establish this communication “BluetoothSerial” library is used which is similar to Arduino serial library, but it is just within ESP32. Following are some functions offered by Bluetooth serial library:

  • begin()
  • available()
  • write()
  • read()

Bluetooth Controlled LED using ESP32

Let’s write a simple code that can control a LED using mobile Bluetooth over Bluetooth wireless communication. Following is the hardware required to control LED using Bluetooth serial communication:

  • ESP32
  • LED
  • Breadboard
  • Android device
  • Serial Bluetooth Terminal Application

A picture containing text, wall, indoor, electronics Description automatically generated

Circuit

Connect LED at digital pin 15 of ESP32 with negative terminal connected at GND of ESP32 board. For a safe current limit we can also connect the resistor (220 ohms) between them:

A picture containing graphical user interface Description automatically generated

Code

Open Arduino IDE and select the ESP32 board in the Board Manager to see how to install ESP32 board in Arduino IDE click here. After selecting the board write the code below in the editor window:

#include <BluetoothSerial.h>  /*Bluetooth serial communication library*/

#define LED_PIN 15  /*led pin initialized*/
BluetoothSerial SerialBT;  
byte BT_INP;
#if !defined(CONFIG_BT_ENABLED) || !defined(CONFIG_BLUEDROID_ENABLED)/*Check for bluetooth in SDK*/
#error Bluetooth off--Run `make menuconfig` to enable it
#endif
void setup()
{
  pinMode(LED_PIN, OUTPUT);   /*led pin set as output*/
  Serial.begin(115200);  /*baud rate for serial communication*/
  SerialBT.begin();   /*Bluetooth communication begins*/
  Serial.println("Bluetooth is ready to Pair..."); /*when Bluetooth turn on*/
}
void loop()
{
  if(SerialBT.available())    /*check for Bluetooth data availability*/
  {
    BT_INP = SerialBT.read();  /*read Bluetooth data from device*/
    Serial.write(BT_INP);     /*print the read data*/
  }
  if(BT_INP == '1')     /*if condition for led state*/
  {
    digitalWrite(LED_PIN, HIGH);  /*turn on led if 1 input is received*/
  }
  if(BT_INP == '0')
  {
    digitalWrite(LED_PIN, LOW);/*turn off led if 0 input is received*/
  }
}

Here in the above code, we started by including the Bluetooth serial library for ESP32. Next we have included Bluetooth serial library functions that will enable the ESP32 Bluetooth.

Next LED pin 15 is initialized and using the pinMode() function LED pin is set as output.

In loop part of the code the program will check for serial Bluetooth data availability. If the input data is 1 LED will turn ON and if the received data is 0 LED will turn off.

Once the code is uploaded. Bluetooth of the ESP32 board will turn on and the following message will appear on the serial monitor:

Installing Serial Bluetooth Terminal on Smartphone

We need a Bluetooth device that can send instructions to ESP32 so we will be using an Android smartphone to interface it with ESP32 Bluetooth. First, we need to install a serial terminal in an Android phone. Follow the steps given below to interface Android phone with ESP32:

Step 1: Open Google Play Store on your smartphone and search Serial Bluetooth Terminal. Install the below shown application:

Graphical user interface, application Description automatically generated

Step 2: After installing, open mobile phone Bluetooth settings. Search for ESP32 Bluetooth and click to start pairing it with your smartphone by clicking on Pair:

Graphical user interface, text, application, chat or text message Description automatically generated

Step 3: After tapping on a Pair, the mobile phone will start pairing with ESP32 Bluetooth:

Graphical user interface, text, application, chat or text message Description automatically generated

Step 4: Now open the Serial Bluetooth Terminal Application and go to Devices from the side menu:

Graphical user interface, text, application Description automatically generated

Step 5: Once the device option is opened it will ask for some permissions or press the REFRESH button at top right corner:

Text Description automatically generated with low confidence

Step 6: Following pop-up will come click on Settings and allow the permission it asks for:

Graphical user interface, application Description automatically generated

Step 7: Now ESP32 board is ready to take instructions over Bluetooth. Under Bluetooth Classic option select ESP32 board:

Text Description automatically generated with low confidence

Step 8: Once ESP32 is selected it will start connecting and if successful, a Connected message will appear:

A picture containing shape Description automatically generated

Step 9: Now we can send any instruction by typing it here. Type 1 and click the send button, LED on ESP32 board will turn On. Similarly, by typing 0 LED will turn OFF:

A picture containing shape Description automatically generated

Similarly, we can see the output on the serial monitor of the Arduino IDE what it is receiving:

Graphical user interface, text Description automatically generated

Output

LED turns ON after sending 1:

A picture containing text, wall, indoor Description automatically generated

LED turns OFF after sending 0:

A picture containing text, wall, indoor, electronics Description automatically generated

Note: We can also configure buttons for specific instructions like shown in image below. To do this click the buttons and set the value you want. Here we have set two buttons one for HIGH and other one for LOW state. You can also configure these shortcuts in Hexadecimal values.

Graphical user interface Description automatically generated

2: ESP32 Bluetooth Low Energy (BLE) with Arduino IDE

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.

BLE Server and Client

Bluetooth Low Energy supports the device in two different ways due to which 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 together 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.

Diagram Description automatically generated

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 has more than one 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 given to each 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.

Text Description automatically generated with medium confidence

To see how to install an ESP32 board 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:

Text Description automatically generated

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();  // this still is working for backward compatibility
  BLEAdvertising *pAdvertising = BLEDevice::getAdvertising();
  pAdvertising->addServiceUUID(SERVICE_UUID);
  pAdvertising->setScanResponse(true);
  pAdvertising->setMinPreferred(0x06);  // functions that help with iPhone connections issue
  pAdvertising->setMinPreferred(0x12);
  BLEDevice::startAdvertising();
  Serial.println("Characteristic defined! BLE Server Ready");
}
void loop() {
  // put your main code here, to run repeatedly:
  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 and 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.

Text Description automatically generated

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:

Text Description automatically generated

The code below will be open in Arduino IDE editor.

Scanner Code

The code given will be used in the Scanner ESP32 board. Open IDE and upload the code, remember to disconnect other boards before uploading the 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); //active scan uses more power, but get results faster
  pBLEScan->setInterval(100);
  pBLEScan->setWindow(99);  // less or equal setInterval value
}
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 fromBLEScan buffer to release 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<std::string, BLEAdvertisedDevice*>(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 ESP32 is an access point for devices. 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 as mentioned in image below:

Graphical user interface, text, application, email Description automatically generated

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

Graphical user interface, application Description automatically generated

Step 7: A new pop-up will appear here where we can write any Characteristic value and click Ok:

Step 8: New value which is written will appear as shown in image:

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 which are Bluetooth Classic and Bluetooth Low Energy. Here in this article, we discussed both Bluetooth classic and BLE and its various applications and working. Bluetooth Classic is used for high data transfer while BLE (Bluetooth Low Energy) is used for short distances with less power requirements. This article gives an ultimate guide to ESP32 board Bluetooth working and how to configure them.

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.