Home / Tutorials / ESP32 Tutorial / Using BLE with ESP32 on the Arduino
pcbway
ESP32 NodeMCU-32S

Using BLE with ESP32 on the Arduino

The ESP32 microcontroller is a powerful and versatile platform, widely used in IoT applications due to its built-in Wi-Fi and Bluetooth capabilities. One of its standout features is support for Bluetooth Low Energy (BLE), which is an energy-efficient version of Bluetooth designed for IoT devices, wearable tech, smart home gadgets, and more. In this post, I will show how to use BLE with ESP32 in Arduino, which provides an easy and user-friendly environment for programming and prototyping.

ESP32 NodeMCU-32S

Why BLE?

Bluetooth Low Energy (BLE) is ideal for projects that require wireless communication with minimal power consumption. Some benefits of BLE over traditional Bluetooth include:

  • Low Power Consumption: BLE is designed to run for extended periods on battery power, making it perfect for sensor-based applications.
  • Range: BLE typically offers a range of up to 50 meters indoors and can go beyond 100 meters outdoors.
  • Interoperability: BLE works with most modern smartphones, tablets, and computers, making it easy to communicate with a wide variety of devices.

Getting Started with BLE on ESP32

Setting Up the Arduino IDE for ESP32

Before we start coding, you’ll need to set up the Arduino IDE to support the ESP32 platform. If you haven’t already done this, follow these steps:

Install the ESP32 Board Package:

    • Open Arduino IDE and go to File > Preferences.

In the Additional Board Manager URLs field, add the following link:

https://dl.espressif.com/dl/package_esp32_index.json
    • Go to Tools > Board > Boards Manager and search for “ESP32” to install the board package.

Select the ESP32 Board:

    • Under Tools > Board, select your specific ESP32 board (e.g., “ESP32 Dev Module”).

    Including the BLE Library

    The ESP32 Arduino framework comes with built-in BLE support via the ESP32 BLE Arduino library. You can include this in your sketches by importing the library.

    #include <BLEDevice.h>
    #include <BLEUtils.h>
    #include <BLEServer.h>

    Setting Up a BLE Server

    In a typical BLE setup, the ESP32 acts as a server that advertises its presence and offers services that a client (e.g., a smartphone) can connect to. Here’s a simple sketch to turn the ESP32 into a BLE server.

    #include <BLEDevice.h>
    #include <BLEServer.h>
    #include <BLEUtils.h>
    #include <BLE2902.h>
    
    
    BLEServer* pServer = NULL;
    BLECharacteristic* pCharacteristic = NULL;
    
    
    bool deviceConnected = false;
    const int ledPin = 2;
    
    #define SERVICE_UUID        "91bad492-b950-4226-aa2b-4ede9fa42f59"  // Custom service UUID
    #define CHARACTERISTIC_UUID "cba1d466-344c-4be3-ab3f-189f80dd7518"  // Custom characteristic UUID
    
    class MyServerCallbacks: public BLEServerCallbacks {
        void onConnect(BLEServer* pServer) {
          deviceConnected = true;
        };
    
        void onDisconnect(BLEServer* pServer) {
          deviceConnected = false;
        }
    };
    
    
    void setup() {
      Serial.begin(115200);
    
      // Initialize the LED pin
      pinMode(ledPin, OUTPUT);
      digitalWrite(ledPin, LOW);
    
      // Create the BLE Device
      BLEDevice::init("ESP32_BLE");
    
      // Create the BLE Server
      pServer = BLEDevice::createServer();
      pServer->setCallbacks(new MyServerCallbacks());
    
      // Create the BLE Service
      BLEService *pService = pServer->createService(SERVICE_UUID);
    
      // Create a BLE Characteristic
      pCharacteristic = pService->createCharacteristic(
                          CHARACTERISTIC_UUID,
                          BLECharacteristic::PROPERTY_READ |
                          BLECharacteristic::PROPERTY_WRITE
                        );
    
    
      // Start the service
      pService->start();
    
      // Start advertising
      pServer->getAdvertising()->start();
      Serial.println("Waiting for a client to connect...");
    }
    
    
    void loop() {
      if (deviceConnected) {
        digitalWrite(ledPin, HIGH);  // Turn on LED when connected
      } else {
        digitalWrite(ledPin, LOW);   // Turn off LED when disconnected
      }
    }

    Code Breakdown:

    • BLEDevice::init(): Initializes the BLE stack with the device name, which will be visible when scanning from a client.
    • BLEServerCallbacks: Handles connection and disconnection events.
    • BLEService and BLECharacteristic: Define a custom BLE service and characteristic, which are key components in BLE communication.
    • getAdvertising(): Starts the advertising process, which broadcasts the availability of the BLE server.

    Testing the BLE Server

    To test the BLE server, you’ll need a BLE-enabled device, such as a smartphone, and a BLE scanning app like nRF Connect (available on Android and iOS).

    1. Open the BLE scanning app and scan for available devices.
    2. You should see your ESP32_BLE device.
    3. Connect to it and explore the services and characteristics.

    You can interact with the characteristic by writing and reading values from it. The ESP32 will recognize the connection, and the onboard LED will turn on when connected and turn off when disconnected.

    Adding Data to the Characteristic

    To make the BLE device more functional, you can add data transmission capabilities to your characteristic. Here’s how to modify the sketch to send data (e.g., sensor readings) to the client:

    int sensorValue = 0;
    
    
    void loop() {
      if (deviceConnected) {
        sensorValue = analogRead(34);  // Read from a sensor (e.g., potentiometer)
        pCharacteristic->setValue(sensorValue);
        pCharacteristic->notify();     // Notify the client
        delay(1000);                   // Send updates every second
      }
    }

    Here, we read from a sensor (connected to pin 34) and send the value to the client using notify(). The client will receive updates every second.

    BLE Client

    If you want the ESP32 to act as a BLE client, scanning for and connecting to another BLE server (such as a heart rate monitor or temperature sensor), you would use the BLEClient class in place of BLEServer. While this is less common for ESP32, it’s useful in scenarios where the ESP32 needs to gather data from other BLE peripherals.

    Conclusion

    Using BLE with the ESP32 on the Arduino framework opens up endless possibilities for wireless communication in IoT projects. Whether you’re building smart home devices, wearable tech, or sensor networks, BLE offers an energy-efficient and versatile way to connect your devices. With the simple yet powerful Arduino environment, you can quickly get started with BLE, creating both server and client applications with minimal effort.

    By expanding the basic example, you can integrate additional sensors, send complex data structures, and handle multiple simultaneous connections, making ESP32 one of the most powerful microcontrollers for Bluetooth-enabled IoT projects.

     

    Check Also

    ESP32 NodeMCU-32S

    ESP32 SPIFFS Tutorial: Storing Files and Building a Web Server

    The ESP32 is a powerful microcontroller with built-in Wi-Fi and Bluetooth capabilities, making it a …

    Index