Skip to content

How to Pair ESP32 with BLE

DodaTech Updated 2026-06-24 3 min read

In this tutorial, you'll learn about How to Pair ESP32 with BLE. We cover key concepts, practical examples, and best practices.

The Problem

Your ESP32 BLE (Bluetooth Low Energy) server is not visible to your phone, the app cannot discover services, or the connection drops within seconds. BLE pairing fails with timeout errors or GATT ERROR. Without reliable BLE, your IoT project cannot communicate with mobile devices.

Quick Fix

Fix 1: BLE Server Not Advertising

WRONG — starting advertising without setting up the server properly:

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

void setup() {
    Serial.begin(115200);
    BLEDevice::init("ESP32-BLE");
    // (advertising never starts — missing BLEServer and advertising setup)
}

RIGHT — complete BLE server setup:

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

BLECharacteristic* pCharacteristic;
bool deviceConnected = false;

class MyServerCallbacks: public BLEServerCallbacks {
    void onConnect(BLEServer* pServer) {
        deviceConnected = true;
        Serial.println("Connected");
    }
    void onDisconnect(BLEServer* pServer) {
        deviceConnected = false;
        Serial.println("Disconnected");
    }
};

void setup() {
    Serial.begin(115200);
    BLEDevice::init("ESP32-BLE");

    BLEServer* pServer = BLEDevice::createServer();
    pServer->setCallbacks(new MyServerCallbacks());

    BLEService* pService = pServer->createService("4fafc201-1fb5-459e-8fcc-c5c9c331914b");
    pCharacteristic = pService->createCharacteristic(
        "beb5483e-36e1-4688-b7f5-ea07361b26a8",
        BLECharacteristic::PROPERTY_READ | BLECharacteristic::PROPERTY_NOTIFY
    );
    pCharacteristic->setValue("Hello BLE");

    pService->start();
    BLEAdvertising* pAdvertising = BLEDevice::getAdvertising();
    pAdvertising->start();
    Serial.println("BLE server ready");
}
// Output:
// BLE server ready
// (ESP32 is now discoverable as "ESP32-BLE")

Fix 2: Device Not Discoverable on Phone

WRONG — advertising stops after a few seconds:

BLEDevice::getAdvertising()->start();
// (advertising stops after 30 seconds by default)

RIGHT — set advertising to continue indefinitely:

BLEAdvertising* pAdvertising = BLEDevice::getAdvertising();
pAdvertising->setScanResponse(true);
pAdvertising->setMinPreferred(0x06);
pAdvertising->setMaxPreferred(0x12);
pAdvertising->start();  // continues until a device connects

Fix 3: GATT Error 133 (Connection Failure)

# GATT ERROR 133: Peer device is out of range or Bluetooth is off

RIGHT — check physical proximity and phone Bluetooth status:

# 1. Ensure the phone is within 10 meters of the ESP32
# 2. Toggle phone Bluetooth off and on
# 3. Clear Bluetooth cache on the phone
# 4. Remove the ESP32 from paired devices and re-scan

Fix 4: Service UUID Not Found

WRONG — using custom UUIDs without verifying they match:

// ESP32 uses: "4fafc201-1fb5-459e-8fcc-c5c9c331914b"
// Phone app looks for: "0000180d-0000-1000-8000-00805f9b34fb"
// (no match — service not found)

RIGHT — print the advertised UUID on the ESP32 and compare:

Serial.println(pService->getUUID().toString().c_str());
// Should match what the phone app expects

Fix 5: Connection Drops After a Few Seconds

WRONG — not maintaining connection with notifications:

// (ESP32 disconnects because it is not sending any data)

RIGHT — send periodic notifications to keep the connection alive:

void loop() {
    if (deviceConnected) {
        char value[10];
        sprintf(value, "%d", analogRead(34));
        pCharacteristic->setValue(value);
        pCharacteristic->notify();
        delay(1000);
    }
}

Fix 6: BLE Stack Initialization Failed

# E (154) BT: esp_bt_controller_mem_release: not enough memory

RIGHT — allocate sufficient memory:

// Increase BLE memory allocation
esp_bt_controller_mem_release(ESP_BT_MODE_CLASSIC_BT);
// (releases Classic BT memory for BLE use)

Use DodaTech's BLE Explorer to scan, connect, and inspect ESP32 BLE services and characteristics during development and debugging.

Prevention

  • Always set setScanResponse(true) for discoverability.
  • Use standard UUIDs (16-bit) when possible for better compatibility.
  • Keep the ESP32 close to the phone during pairing.
  • Send periodic notifications to maintain the connection.
  • Handle disconnection gracefully with auto-reconnect.

Common Mistakes with ble pair

  1. Non-exhaustive pattern matches that compile with warnings then crash at runtime
  2. Misunderstanding that String is [Char] with poor performance for large text operations
  3. Using foldl instead of foldl' causing stack overflow on large lists

These mistakes appear frequently in real-world ESP32 code. DodaTech's contributors have identified these patterns through analysis of open-source projects and production systems.

Practice Exercise

Write a pure function that safely divides two integers using Maybe, then test it with edge cases like division by zero and negative numbers.

This exercise reinforces the concepts covered in this guide. Try implementing it before checking online solutions.

FAQ

### Why does my phone see the ESP32 but cannot connect?

The ESP32 may be in advertising mode without a proper GATT server. Ensure you create a BLE service with at least one characteristic before starting advertising. Check that the phone app expects the correct service UUID.

What is the difference between BLE and Classic Bluetooth on ESP32?

BLE (Bluetooth Low Energy) is for low-power periodic data transfer. Classic Bluetooth is for high-bandwidth streaming (audio). ESP32 supports both but cannot run them simultaneously without memory configuration. BLE is preferred for IoT sensors.

Can multiple phones connect to one ESP32 BLE server?

By default, the ESP32 BLE server accepts only one connection. To support multiple clients, enable bonding and use the BLE2902 descriptor with notifications. Consider using ESP32 as a peripheral with connection whitelist for multi-client support.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro