Tag: ESP32 BLE Gateway

  • ESP32 BLE Notifications: Master Complete Beginner Friendly Guide

    Build an ESP32 BLE server easily with this beginner-friendly guide. Learn setup, examples, troubleshooting, and pro tips to create fast, stable BLE communication.

    When you first start with Bluetooth Low Energy on the ESP32, one feature immediately stands out: BLE notifications. They’re fast, lightweight, don’t need constant polling, and make your ESP32 react in real time whether you’re sending sensor data to a smartphone or receiving commands from a BLE device.

    But here’s the tricky part: BLE can feel confusing when you’re just starting out. Terms like characteristic, client, server, notify, and callbacks can turn anyone’s head into spaghetti code.

    So grab a coffee.
    Let’s talk through ESP32 BLE Notifications like two smart friends figuring things out step by step.

    By the end, you’ll understand:

    • What BLE notifications actually are
    • How the ESP32 sends and receives them
    • How notifications work on Android, iOS, Arduino, and client-server setups
    • How to use all the common BLE examples (server, client, callback, OTA, etc.)
    • Real code you can copy-paste and run

    Let’s jump in.

    What Are ESP32 BLE Notifications (And Why They Matter)?

    Imagine you’re waiting for a text message.
    Your phone doesn’t keep checking the server every second (that would kill your battery).
    Instead, the server pushes a notification only when something new comes in.

    That’s exactly what esp32 ble notifications do.

    Without notifications:
    The client keeps polling the server: “Do you have new data?”
    This wastes power and time.

    With notifications:
    The server automatically sends data whenever it changes.
    Fast. Simple. Efficient.

    This is why notifications are the backbone of:

    • BLE sensors
    • Fitness trackers
    • Smart locks
    • IoT BLE gateways
    • ESP32 BLE presence detection
    • ESP32 BLE keyboard inputs
    • OTA BLE updates
    • And simple BLE Arduino projects

    Notifications make communication feel instant—even though everything runs over BLE.

    ESP32 BLE Server and Client

    To understand esp32 ble notification, you need to know two roles:

    ESP32 BLE Server

    • Creates a service
    • Registers characteristics
    • Sends notifications

    ESP32 BLE Client

    • Connects to a server
    • Enables notify
    • Receives real-time data

    Many tutorials confuse these, so here’s a simple rule:
    The device that sends notifications is always the server.
    The device that receives notifications is the client.

    So if you see:

    • “esp32 ble client notify”
    • “esp32 ble notify callback”
    • “esp32 ble client example”

    It’s always referring to the receiving side.

    ESP32 BLE Arduino Example

    Let’s Write the Simplest Possible BLE Server That Sends Notifications

    This is the classic esp32 ble example to get started.

    ESP32 BLE Notify Example (Server Code)

    #include <BLEDevice.h>
    #include <BLEServer.h>
    #include <BLEUtils.h>
    #include <BLE2902.h>
    
    BLECharacteristic *pCharacteristic;
    bool deviceConnected = false;
    
    class ServerCallbacks : public BLEServerCallbacks {
      void onConnect(BLEServer *pServer) {
        deviceConnected = true;
      }
      void onDisconnect(BLEServer *pServer) {
        deviceConnected = false;
        pServer->startAdvertising();   // important for reconnection
      }
    };
    
    void setup() {
      BLEDevice::init("ESP32-Notify");
      BLEServer *pServer = BLEDevice::createServer();
      pServer->setCallbacks(new ServerCallbacks());
    
      BLEService *pService = pServer->createService("1234");
    
      pCharacteristic = pService->createCharacteristic(
        "ABCD",
        BLECharacteristic::PROPERTY_NOTIFY
      );
    
      pCharacteristic->addDescriptor(new BLE2902());
      pService->start();
    
      BLEAdvertising *pAdvertising = BLEDevice::getAdvertising();
      pAdvertising->start();
    }
    
    void loop() {
      if (deviceConnected) {
        int value = random(0, 100);
        pCharacteristic->setValue(value);
        pCharacteristic->notify();
        delay(500);
      }
    }
    

    This simple sketch demonstrates:

    • esp32 ble advertising example
    • esp32 ble notify example
    • esp32 ble notify callback
    • esp32 ble arduino example
    • Automatic advertising restart when the client disconnects

    Exactly how BLE devices behave in real products.

    ESP32 BLE Client Notify Example (How to Receive Notifications)

    Now that your server can notify, let’s write the esp32 ble client example that receives them.

    ESP32 as BLE Client Receiving Notifications

    #include <BLEDevice.h>
    
    static BLEUUID serviceUUID("1234");
    static BLEUUID charUUID("ABCD");
    
    class MyClientCallback : public BLERemoteCharacteristicCallbacks {
      void onNotify(
        BLERemoteCharacteristic* pBLERemoteCharacteristic,
        uint8_t* pData, size_t length, bool isNotify) {
    
        Serial.print("Received: ");
        for (int i = 0; i < length; i++) {
          Serial.print(pData[i]);
        }
        Serial.println();
      }
    };
    
    void setup() {
      Serial.begin(115200);
      BLEDevice::init("");
    
      BLEScan *scan = BLEDevice::getScan();
      BLEScanResults results = scan->start(5);
    
      for (int i = 0; i < results.getCount(); i++) {
        BLEAdvertisedDevice device = results.getDevice(i);
    
        if (device.haveServiceUUID() && device.isAdvertisingService(serviceUUID)) {
          BLEClient *client = BLEDevice::createClient();
          client->connect(&device);
    
          BLERemoteService* remoteService =
            client->getService(serviceUUID);
    
          BLERemoteCharacteristic* remoteChar =
            remoteService->getCharacteristic(charUUID);
    
          remoteChar->registerForNotify(new MyClientCallback());
        }
      }
    }
    
    void loop() {}
    

    This covers:

    • esp32 ble notify callback
    • esp32 ble client notify
    • esp32 ble callbacks
    • esp32 bluetooth example

    So you now have a working end-to-end notification system.

    ESP32 BLE Notifications With Android (Mobile App Example)

    If your user is on Android, BLE is easy to test.

    Use any app like:

    • nRF Connect
    • LightBlue
    • BLE Scanner

    What you can do:

    Scan for “ESP32-Notify”
    Connect
    Enable notification on the characteristic
    Watch live data come in

    This naturally uses and demonstrates:

    • esp32 ble android app example
    • esp32 ble receive data
    • esp32 bluetooth notification

    Once you enable notifications, the ESP32 sends data instantly without you touching anything.

    ESP32 BLE Notifications on iOS (ANCS & Regular BLE)

    iPhones work slightly differently, but they’re still easy.

    You can use:

    • LightBlue (iOS version)
    • nRF Connect
    • Custom Swift app

    If you’re looking at iOS-specific notification features, you might come across:

    • esp32 ble ios
    • esp32 ble ancs notifications

    ANCS = Apple Notification Center Service.
    It lets you forward real iPhone notifications (calls, SMS, app alerts) to the ESP32.

    Yes, your ESP32 can literally detect when you receive a WhatsApp message.

    ESP32 BLE Presence Detection (Cool Use Case)

    BLE notifications also help create presence detection systems.

    How?

    Your ESP32 scans nearby BLE MACs and checks whether known devices are present.

    This method is widely used in:

    • Smart homes
    • Security systems
    • Energy-saving automation

    This naturally uses:

    • esp32 ble presence detection
    • esp32 ble gateway

    Your ESP32 becomes a tiny BLE gateway that senses activity around it.

    ESP32 BLE Keyboard + Notifications

    Another cool trick:
    You can make your ESP32 act like a BLE keyboard and still send notifications.

    Useful for:

    • Home automation
    • Game controllers
    • Input devices

    This uses:

    You can send keystrokes and BLE data at the same time.

    ESP32 OTA BLE (Firmware Update Over BLE)

    BLE notifications are also part of BLE OTA protocols.

    The ESP32 can receive firmware chunks over BLE using:

    • write
    • notify
    • indicate

    This includes:

    • esp32 ota ble
    • esp32 push notification

    This includes powerful features like ESP32 OTA over BLE and ESP32 push notification support.

    If you want a complete beginner-friendly walkthrough, you can follow this practical guide on the ESP32 BLE Server
    Imagine updating thousands of devices wirelessly without ever touching a single one.

    ESP32 BLE Advertising Example (How Advertising Works)

    Before a device connects, it sees the advertising packet.

    A simple ESP32 BLE advertising example:

    BLEAdvertising *adv = BLEDevice::getAdvertising();
    adv->setScanResponse(true);
    adv->start();
    

    This helps with:

    • esp32 ble advertising example
    • esp32 ble examples

    You can modify advertising data to show battery status, device role, or quick info.

    ESP32 BLE Notify Callback Explained Simply

    A notify callback is a function that runs whenever new data arrives.

    Client-side callback helps you react instantly:

    • Blink LED
    • Update display
    • Log data
    • Trigger command

    This is used in:

    • esp32 ble notify callback
    • arduino ble notify example
    • esp32 arduino ble notification

    Callbacks make everything real-time.

    ESP32 BLE Receive Data (Client Side)

    When receiving data:

    • ESP32 is the client
    • Phone or another ESP32 acts as server
    • Notifications arrive as raw bytes

    Use them to read:

    • Temperature
    • Heart rate
    • Buttons
    • Sensor streams

    This naturally covers:

    • esp32 ble receive data
    • esp32 bluetooth example

    Receiving data is just as important as sending it.

    ESP32 BLE Gateway Use Case

    A BLE Gateway basically:

    • Scans BLE devices
    • Reads their notifications
    • Sends data to a server via Wi-Fi or MQTT

    This uses:

    • esp32 ble gateway

    A great use case if you’re building an IoT hub or smart home hub.

    12 Most Common Problems With ESP32 BLE Notifications (And Fixes)

    Problem 1: Notifications Not Working

    Enable notify:

    pCharacteristic->addDescriptor(new BLE2902());
    

    Problem 2: Client Disconnects Automatically

    Restart advertising in callback:

    pServer->startAdvertising();
    

    Problem 3: Data Comes in Broken

    Use a buffer instead of single bytes.

    Problem 4: Android Not Receiving Data

    Make sure scan permissions are granted.

    Problem 5: iPhone Not Connecting

    Use 128-bit UUIDs.

    Problem 6: Slow Notifications

    Decrease delay or increase MTU:

    pServer->getPeerMTU(connId);
    

    Problem 7: ESP32 Resets on Heavy Data

    Enable BLE Arduino NimBLE library for lower memory usage.

    Final Thoughts ESP32 BLE Notifications Are Simple Once You “Get It”

    If you’ve made it this far, you now understand:

    • How esp32 ble notifications work
    • How to create a server that sends them
    • How to build an ESP32 BLE client that receives them
    • How to test with Android and iOS
    • How callbacks, advertising, and BLE examples tie together
    • How to use advanced cases like OTA BLE, BLE keyboards, BLE gateway, presence detection

    BLE isn’t magic.
    It’s just event-based communication.

    FAQ : ESP32 BLE Notifications

    This FAQ section covers the most common questions about ESP32 BLE notifications, including examples, callbacks, Android/iOS behavior, advertising, gateways, presence detection, and advanced use cases.

    1. What exactly are ESP32 BLE notifications?

    ESP32 BLE notifications are automatic real-time data updates sent from a BLE server to a BLE client without the client needing to poll. This makes communication faster and more battery-efficient. You can use notifications for sensor data, ESP32 BLE gateway systems, presence detection, keyboard inputs, and more.

    2. How do ESP32 BLE notifications differ from indications?

    Notifications are one-way and do not require acknowledgment. Indications require the client to confirm receipt. For fast data like heart rate or sensor streams, notifications are better. For critical transfers (OTA BLE updates), indications may be safer.

    3. How do I enable notify on ESP32 BLE characteristics?

    You must add a BLE2902 descriptor and set the characteristic property to PROPERTY_NOTIFY. Without this, Android/iOS apps cannot enable notifications. This applies to all ESP32 BLE Arduino example projects.

    4. Why are my ESP32 BLE notifications not being received by Android?

    Most Android devices require the BLE2902 descriptor to be present. In addition, location permissions must be enabled for BLE scanning. Also ensure MTU is increased if sending large payloads.

    5. Why do notifications fail on iOS even though they work on Android?

    iOS has stricter BLE rules. You must use 128-bit UUIDs and include proper descriptors. For iPhone alert mirroring, you must implement the ANCS (Apple Notification Center Service), commonly used in esp32 ble ancs notifications.

    6. How can I test ESP32 BLE notifications on a smartphone?

    Use any BLE scanner app such as nRF Connect, LightBlue, or BLE Scanner. These apps let you scan for the ESP32 BLE advertising example, connect, enable notify, and monitor incoming data instantly.

    7. How do I receive notifications using an ESP32 BLE client?

    On the client side, register a callback using registerForNotify(). This triggers when a notification arrives. This pattern appears in most esp32 ble client example code.

    8. Why does my ESP32 stop sending notifications after the client disconnects?

    You must restart advertising inside onDisconnect(). Otherwise, the server waits forever and doesn’t allow reconnections. Example: pServer->startAdvertising();.

    9. Can ESP32 BLE send multiple notifications per second?

    Yes. You can send several notifications per second by optimizing the delay loop. Increasing MTU size improves throughput. For high-rate data (like audio streaming), BLE is limited but feasible for low-bitrate use cases.

    10. Will notifications drain the ESP32 battery fast?

    Notifications are lighter than polling, making them efficient for battery-powered applications. Adjusting advertising intervals and disabling scan responses in your ESP32 BLE advertising example helps conserve energy.

    11. Can I send data from my phone to ESP32 using notifications?

    No. Notifications only go from server → client. To send phone → ESP32, you must use writes or write-without-response. Many Arduino BLE notify examples combine writes and notifications for bidirectional messaging.

    12. How do ESP32 BLE notifications help with presence detection?

    Presence detection systems use BLE scans to identify nearby devices. Notifications help send detection events instantly to a central ESP32 BLE gateway or MQTT server. This is common in smart homes and automation setups.

    13. Can ESP32 BLE notifications be used with OTA updates?

    Yes. Some OTA BLE implementations use notifications to confirm transfer states or send progress feedback. This is useful when Wi-Fi isn’t available.

    14. Can I use ESP32 BLE notifications with ESP32 BLE keyboard projects?

    Yes. The ESP32 can act as a BLE keyboard and still expose a separate GATT service for notifications. This is common in custom HID devices like gamepads or macro pads.

    15. What is the maximum data size for one ESP32 BLE notification?

    The default BLE payload is 20 bytes. Increasing the MTU (e.g., to 185 bytes) allows larger packets. Large MTU is essential when streaming sensor data or sending structured JSON packets.

  • ESP32 BLE Server: Master Ultimate Complete Guide with 10 Expert Examples

    Learn ESP32 BLE Server step by step: send/receive data, handle multiple clients, and build powerful IoT projects with beginner-friendly examples.

    It all started one evening when I was tinkering with my ESP32 board in my tiny home workspace. I had a simple idea: what if my little ESP32 could talk to my phone without any wires? I didn’t want classic Bluetooth that streams music or Wi-Fi that drains the battery fast. I needed something lightweight, low-power, and fast. That’s when I stumbled upon BLE — Bluetooth Low Energy.

    I plugged in the ESP32, fired up the Arduino IDE, and started experimenting. Within a couple of hours, I had my ESP32 acting as a BLE server, sending real-time sensor data straight to my phone. And the best part? I could connect multiple phones at once, receive commands, and even make it act as a gateway for other BLE devices.

    By the end of that night, I realized this wasn’t just a fun experiment it was a whole world of possibilities. From smart home projects to IoT dashboards, the ESP32 BLE server became my go-to tool for wireless communication. And today, I’m going to walk you through everything you need to know to set up your own ESP32 BLE server, send and receive data, handle multiple clients, and even run client-server communication simultaneously all in a way that’s beginner-friendly and easy to follow.

    Introduction: Why Use an ESP32 BLE Server

    Imagine you’re building a smart gadget maybe a sensor hub, a remote control, or a fitness tracker and you want it to communicate with your phone or another device wirelessly. Bluetooth Low Energy (BLE) is perfect for that: low power, fast, and widely supported. On the ESP32 platform, you can easily make your board act as a BLE server, handling connections, sending data, receiving commands, and more.

    When I talk about an ESP32 BLE server, I literally mean the ESP32 acting as a Bluetooth server the “host” that exposes services and characteristics, listens for client connections, sends notifications, and more. This is different from a BLE client, which requests data, writes to characteristics, or reads them. But here’s the cool part: on the ESP32, you can run both server and client at the same time. More on that soon.

    In this article, we’ll walk through what BLE is, why ESP32 is great for BLE, how to build a BLE server on ESP32 (with Arduino code), how to handle multiple clients, how to send and receive data, and even how to set up a gateway. We’ll also look at real ESP32 BLE server example projects.

    What Is BLE (Bluetooth Low Energy)?

    Before we dive into ESP32, let’s clarify BLE. BLE is a wireless communication protocol designed for low power consumption. Unlike classic Bluetooth (used for audio), BLE is optimized for sending small packets of data infrequently perfect for sensors, beacons, and IoT devices.

    In BLE, the communication model revolves around GATT (Generic Attribute Profile). A GATT server exposes data via services and characteristics. A service is a collection of characteristics; a characteristic holds a piece of data and may support read, write, or notify operations.

    • Read – A client can read a characteristic value.
    • Write – A client can write a value to a characteristic.
    • Notify / Indicate – The server can push updates to clients when characteristic values change.

    That’s the basic architecture behind how your ESP32 BLE server will work.

    Why ESP32 for BLE?

    The ESP32 is a flexible, cost-effective microcontroller with built-in Wi-Fi and Bluetooth capabilities. For BLE, it’s especially powerful because:

    • It supports BLE GATT server and client roles.
    • It’s compatible with Arduino, making development very beginner‑friendly.
    • It has enough power and memory to handle multiple connections.
    • It’s inexpensive and widely available.

    Because of these strengths, the ESP32 is a go-to choice when building BLE projects like remote sensors, BLE gateways, or even custom BLE peripherals.

    Getting Started with an ESP32 BLE Server Example

    Let’s start with a simple ESP32 BLE server example. We’ll use the Arduino IDE (or PlatformIO) and write code to create a BLE server with one service, one characteristic, and let a phone connect to it, read data, and receive notifications.

    Here’s a step‑by‑step guide:

    1. Set up your Arduino IDE
      • Install the ESP32 board package via the Boards Manager.
      • Install the NimBLE-Arduino or ESP32 BLE Arduino library. I’ll use the ESP32 BLE Arduino library here for simplicity.
    2. Create the BLE server sketch
    #include <BLEDevice.h>
    #include <BLEUtils.h>
    #include <BLEServer.h>
    
    // Define your service and characteristic UUIDs
    #define SERVICE_UUID        "12345678-1234-1234-1234-1234567890ab"
    #define CHARACTERISTIC_UUID "abcd1234-5678-90ab-cdef-1234567890ab"
    
    BLEServer* pServer = nullptr;
    BLECharacteristic* pCharacteristic = nullptr;
    bool deviceConnected = false;
    
    // Server callback to handle client connection/disconnection
    class MyServerCallbacks : public BLEServerCallbacks {
        void onConnect(BLEServer* pServer) {
            deviceConnected = true;
        }
    
        void onDisconnect(BLEServer* pServer) {
            deviceConnected = false;
        }
    };
    
    void setup() {
        Serial.begin(115200);
    
        // Initialize BLE
        BLEDevice::init("ESP32_BLE_Server");
    
        // Create BLE Server
        pServer = BLEDevice::createServer();
        pServer->setCallbacks(new MyServerCallbacks());
    
        // Create BLE Service
        BLEService* pService = pServer->createService(SERVICE_UUID);
    
        // Create BLE Characteristic
        pCharacteristic = pService->createCharacteristic(
            CHARACTERISTIC_UUID,
            BLECharacteristic::PROPERTY_READ |
            BLECharacteristic::PROPERTY_WRITE |
            BLECharacteristic::PROPERTY_NOTIFY
        );
    
        // Set initial value for the characteristic
        pCharacteristic->setValue("Hello from ESP32!");
    
        // Start the service
        pService->start();
    
        // Start advertising
        BLEAdvertising* pAdvertising = BLEDevice::getAdvertising();
        pAdvertising->addServiceUUID(SERVICE_UUID);
        pAdvertising->start();
    
        Serial.println("Waiting for a client to connect...");
    }
    
    void loop() {
        if (deviceConnected) {
            static int counter = 0;
            String msg = "Count: " + String(counter++);
            pCharacteristic->setValue(msg.c_str());
            pCharacteristic->notify();
            Serial.println("Sent: " + msg);
            delay(1000);
        }
        delay(100);
    }
    

    In this example, the ESP32 sets up a BLE server, starts advertising, and once a client connects, it sends a notification every second updating a counter. This is a classic esp32 ble gatt server example.

    Understanding the Code: Read, Write, Notify

    • Read characteristic: Because we set BLECharacteristic::PROPERTY_READ, a connected client can read the characteristic’s current value (“Hello from ESP32!”), or updated values later. That covers the esp32 ble server read characteristic part.
    • Write characteristic: With PROPERTY_WRITE, clients can write data to the server. You can handle writes by implementing a onWrite callback and reading the data sent by the client. This is related to esp32 ble server receive data.
    • Notify: PROPERTY_NOTIFY lets the server push updates without the client polling. That covers esp32 ble server send data — the server sending notifications to the client.

    Running ESP32 BLE Server and Client at the Same Time

    One of the powerful features of ESP32 is that it can act as both BLE server and client simultaneously. This means your device can host services (server role) and connect to another BLE device (client role). This is your esp32 ble server and client same time scenario.

    Why is this useful? Imagine:

    • Your ESP32 acts as a gateway: It receives sensor data from another BLE sensor (as a client), then forwards that data to your phone (as a server).
    • It reads from one BLE peripheral and makes that data available for multiple client devices.

    Here’s a rough outline of how that works:

    1. Initialize BLE in both server and client roles.
    2. Set up your GATT server (services, characteristics).
    3. Start scanning for other BLE peripherals.
    4. When you find a peripheral that you’re interested in, connect to it as a BLE client.
    5. Read/write characteristics on that peripheral.
    6. Whenever you get updates from that peripheral, process them, then update your own GATT server’s characteristic so connected clients can see the data or be notified.

    It’s more advanced than just a simple server, but esp32 ble server and client in one device opens up powerful use cases.

    Handling Multiple Clients on an ESP32 BLE Server

    A really common question is: Can the ESP32 BLE server handle multiple clients? The answer is yes esp32 ble server multiple clients is supported, though with some caveats: performance and characteristics of BLE connection.

    Here’s what to keep in mind:

    1. Connection Limit: By default, the ESP32’s BLE stack supports a limited number of simultaneous connections. It depends on the library and configuration. With the ESP32 BLE Arduino or NimBLE, you can support at least a few clients.
    2. Resource Sharing: When multiple clients are connected, they’ll all read and possibly write to the same characteristic. If you use notify, each client will get notifications.
    3. State Management: In your server callback functions, you need to track client connections and disconnections carefully to avoid stale states.

    Here’s a sketch of how that might look:

    class MyServerCallbacks: public BLEServerCallbacks {
      void onConnect(BLEServer* pServer) {
        Serial.println("A client connected!");
        // You can examine the connection handle or track number of clients
      }
      void onDisconnect(BLEServer* pServer) {
        Serial.println("A client disconnected!");
      }
    };
    

    You may also keep a list of connection handles if you need per-client customization.

    Using multiple clients is especially useful in esp32 ble server gateway scenarios: your ESP32 could act as the hub for several phones or BLE devices, simultaneously sharing data.

    Writing and Receiving Data: How ESP32 BLE Server Receives Data

    Say you want to receive data from a BLE client — like a phone sending commands, or another device sending sensor readings. On the server side, you do this by enabling the write property for a characteristic and handling the write callback.

    Here’s an expanded example showing how to receive data from BLE clients:

    pCharacteristic = pService->createCharacteristic(
                       CHARACTERISTIC_UUID,
                       BLECharacteristic::PROPERTY_READ |
                       BLECharacteristic::PROPERTY_WRITE |
                       BLECharacteristic::PROPERTY_NOTIFY
                     );
    
    pCharacteristic->setCallbacks(new BLECharacteristicCallbacks() {
      void onWrite(BLECharacteristic* pChar) {
        std::string value = pChar->getValue();
        Serial.print("Received value: ");
        Serial.println(value.c_str());
        // process the received data
      }
    });
    

    In this way, the ESP32 BLE server can listen for writes, parse them, and react. That directly covers esp32 ble server receive data.

    Disconnecting Clients: ESP32 BLE Server Disconnect

    Another practical topic: sometimes clients will disconnect, or you might want to explicitly handle disconnections. In the server callbacks, you can detect when a client disconnects (as shown earlier). You can also stop advertising or reset the server.

    Example:

    void onDisconnect(BLEServer* pServer) {
      Serial.println("Client disconnected, restarting advertising...");
      pServer->getAdvertising()->start();
    }
    

    When the client disconnects, you can immediately start advertising again so new or returning clients can reconnect. This ensures your ESP32 BLE server handles disconnects gracefully.

    For practical projects and real-world examples, you can also explore ESP32 Blynk tutorials to integrate BLE communication with cloud-based dashboards.

    Sending Data from the Server: ESP32 BLE Server Send Data

    Sending data from the ESP32 to connected clients is one of the core actions of a BLE server. We achieve this with notify (or sometimes indicate).

    In the earlier example, I used:

    pCharacteristic->setValue(msg.c_str());
    pCharacteristic->notify();
    

    This sends a notification to all connected clients who have enabled notifications for that characteristic.

    If you want more control, you can:

    • Send only when there’s new data.
    • Use regular intervals (e.g., periodic sensor data).
    • Send different types of data (strings, binary, sensor readings).

    Because BLE has a limited MTU (maximum data size in a packet), you might split larger payloads into smaller chunks or increase the negotiated MTU. But for many applications — like ble serial esp32 small messages are just fine.

    Real‑World ESP32 BLE Server and Client Example

    To bring things together, here’s a more advanced ESP32 BLE server client example that demonstrates:

    • The ESP32 acting both as a server and a client.
    • Connecting to another BLE peripheral.
    • Exposing its own service to other clients.
    • Relaying data from the peripheral to its own clients.

    Flow:

    1. ESP32 starts as a BLE server (advertises its service).
    2. ESP32 also scans for another BLE device (as a client).
    3. On finding a target BLE peripheral, it connects and subscribes to its notifications.
    4. When the peripheral sends data, the ESP32 client receives it.
    5. The ESP32 server then forwards this data to its own connected clients via characteristic notifications.

    Pseudo‑code:

    void setup() {
      BLEDevice::init("ESP32_Gateway");
      // Setup server
      ...
      // Setup client
      BLEScan* pScan = BLEDevice::getScan();
      pScan->setAdvertisedDeviceCallbacks(...);
      pScan->start(scanTime, false);
    }
    
    void onPeripheralNotification(BLERemoteCharacteristic* pChar, uint8_t* data, size_t length, bool isNotify) {
      // Called when the remote BLE peripheral sends data.
      String incoming = "";
      for (int i = 0; i < length; i++) incoming += (char)data[i];
      Serial.println("Got from peripheral: " + incoming);
    
      // Forward to our clients
      myServerCharacteristic->setValue(incoming.c_str());
      myServerCharacteristic->notify();
    }
    

    This is a real esp32 ble client server communication pattern.

    Using Arduino: ESP32 Arduino BLE Server Example

    Many beginners prefer to work in Arduino IDE on ESP32. The earlier simple example already used Arduino, but let’s make it explicit as an esp32 arduino ble server example.

    Here are the key libraries and steps:

    1. Include the BLE library in Arduino: #include <BLEDevice.h> #include <BLEServer.h> #include <BLEUtils.h> #include <BLE2902.h> // For descriptor if you want notify
    2. Create the server, service, characteristic.
    3. Add a descriptor to the characteristic so that clients can enable notifications: pCharacteristic->addDescriptor(new BLE2902());
    4. Start advertising, monitor connections, and handle read/write.

    A more fully featured Arduino-style sketch:

    #include <BLEDevice.h>
    #include <BLEServer.h>
    #include <BLEUtils.h>
    #include <BLE2902.h>
    
    #define SERVICE_UUID        "12345678-1234-1234-1234-1234567890ab"
    #define CHARACTERISTIC_UUID "abcd1234-5678-90ab-cdef-1234567890ab"
    
    BLEServer* pServer = nullptr;
    BLECharacteristic* pCharacteristic = nullptr;
    bool deviceConnected = false;
    
    class ServerCallbacks: public BLEServerCallbacks {
      void onConnect(BLEServer* pServer) {
        deviceConnected = true;
      }
      void onDisconnect(BLEServer* pServer) {
        deviceConnected = false;
        pServer->getAdvertising()->start();
      }
    };
    
    class CharCallbacks: public BLECharacteristicCallbacks {
      void onWrite(BLECharacteristic* pChar) {
        std::string value = pChar->getValue();
        Serial.print("Client wrote: ");
        Serial.println(value.c_str());
      }
    };
    
    void setup() {
      Serial.begin(115200);
      BLEDevice::init("Arduino_ESP32_BLE");
    
      pServer = BLEDevice::createServer();
      pServer->setCallbacks(new ServerCallbacks());
    
      BLEService* pService = pServer->createService(SERVICE_UUID);
    
      pCharacteristic = pService->createCharacteristic(
                         CHARACTERISTIC_UUID,
                         BLECharacteristic::PROPERTY_READ |
                         BLECharacteristic::PROPERTY_WRITE |
                         BLECharacteristic::PROPERTY_NOTIFY
                       );
    
      pCharacteristic->setCallbacks(new CharCallbacks());
      pCharacteristic->addDescriptor(new BLE2902());
    
      pCharacteristic->setValue("Ready");
      pService->start();
      BLEAdvertising* pAdvertising = BLEDevice::getAdvertising();
      pAdvertising->addServiceUUID(SERVICE_UUID);
      pAdvertising->start();
      Serial.println("BLE server (Arduino) started, waiting for client...");
    }
    
    void loop() {
      if (deviceConnected) {
        static int number = 0;
        String msg = "Msg " + String(number++);
        pCharacteristic->setValue(msg.c_str());
        pCharacteristic->notify();
        Serial.println("Notified: " + msg);
        delay(2000);
      } else {
        delay(500);
      }
    }
    

    This properly shows esp32 arduino ble server example and esp32 ble example.

    BLE Client Side: ESP32 BLE Client Example

    To fully understand the system, it’s helpful to also know how the BLE client works. On a different ESP32 or on a phone, you might write a BLE client that connects to your server, reads the characteristic, writes data, or subscribes to notifications.

    Here’s a very basic esp32 ble client example using Arduino:

    #include <BLEDevice.h>
    #include <BLEUtils.h>
    #include <BLEScan.h>
    #include <BLEAdvertisedDevice.h>
    
    #define TARGET_SERVICE_UUID "12345678-1234-1234-1234-1234567890ab"
    #define TARGET_CHAR_UUID    "abcd1234-5678-90ab-cdef-1234567890ab"
    
    static boolean doConnect = false;
    static BLERemoteCharacteristic* pRemoteCharacteristic = nullptr;
    static BLEAdvertisedDevice* myDevice;
    
    class MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks {
      void onResult(BLEAdvertisedDevice advertisedDevice) {
        if (advertisedDevice.haveServiceUUID() && advertisedDevice.isAdvertisingService(BLEUUID(TARGET_SERVICE_UUID))) {
          Serial.println("Found our device!");
          BLEDevice::getScan()->stop();
          myDevice = new BLEAdvertisedDevice(advertisedDevice);
          doConnect = true;
        }
      }
    };
    
    void setup() {
      Serial.begin(115200);
      BLEDevice::init("");
      BLEScan* pBLEScan = BLEDevice::getScan();
      pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());
      pBLEScan->setActiveScan(true);
      pBLEScan->start(5);
    }
    
    void loop() {
      if (doConnect) {
        BLEClient* pClient = BLEDevice::createClient();
        pClient->connect(myDevice);
    
        BLERemoteService* pRemoteService = pClient->getService(TARGET_SERVICE_UUID);
        if (pRemoteService == nullptr) {
          Serial.println("Failed to find service.");
          pClient->disconnect();
          return;
        }
    
        pRemoteCharacteristic = pRemoteService->getCharacteristic(TARGET_CHAR_UUID);
        if (pRemoteCharacteristic == nullptr) {
          Serial.println("Failed to find characteristic.");
          pClient->disconnect();
          return;
        }
    
        // Read value
        std::string value = pRemoteCharacteristic->readValue();
        Serial.print("Characteristic value: ");
        Serial.println(value.c_str());
    
        // Subscribe to notifications
        if (pRemoteCharacteristic->canNotify()) {
          pRemoteCharacteristic->registerForNotify([](BLERemoteCharacteristic* pChar, uint8_t* data, size_t length, bool isNotify) {
            String str = "";
            for (size_t i = 0; i < length; i++) str += (char)data[i];
            Serial.print("Notification received: ");
            Serial.println(str);
          });
        }
    
        doConnect = false;
      }
      delay(1000);
    }
    

    This is a solid esp32 ble client example showing how to discover a server, connect, read, and listen for notifications.

    Gateway Use Case: ESP32 BLE Gateway

    One of the more advanced and useful patterns is to use the ESP32 as a BLE gateway that is, a device that sits between BLE peripherals and another system (like Wi-Fi or a cloud service).

    Here’s how this typically works:

    • The ESP32 acts as a BLE client and connects to a BLE sensor (another BLE device).
    • It receives data (through notifications).
    • The ESP32 also acts as a BLE server for other BLE clients (like phones or other ESP32s).
    • It republishes the sensor data via its own GATT characteristic, or forwards data via Wi-Fi to a server or cloud.

    This architecture esp32 ble gateway is very powerful in IoT because BLE sensors are often low power and local, but you want to expose their data to your phone or to a remote server.

    Advanced: Handling Multiple Clients, Data Flow, and Stability

    When you build a production‑quality ESP32 BLE server, especially one that handles multiple clients, receives data, and sends data, there are key practical challenges. Here are some tips, drawn from real-world experience:

    1. Manage Connection Handles
      Keep track of how many clients are connected, and possibly their connection handles if you want to send data to specific clients.
    2. Optimize Notification Frequency
      Rapid notifications can overload BLE or your microcontroller. Use a sensible interval, and only send when data changes.
    3. MTU and Payload Size
      The default BLE MTU is limited. If you need to send larger payloads, negotiate a higher MTU or break the payload into smaller packets.
    4. Disconnect Handling
      As discussed, always handle client disconnects. Restart advertising or clean up state to be ready for new clients. That covers esp32 ble server disconnect gracefully.
    5. Power Consumption
      BLE helps with low power, but if you’re sending very frequent notifications, power usage can go up. Use deep sleep on the ESP32 when possible and manage advertising/reporting intervals.
    6. Security
      BLE supports pairing, encryption, and bonding. If your use case involves sensitive data (control commands, personal data), you should enable pairing and encrypt communications.

    Using GitHub: ESP32 BLE Server GitHub Resources

    If you want to dive deeper or find ready-made projects, there are many examples on GitHub. You can search for terms like “esp32 ble server github” to explore repositories with well-documented BLE server code. These repos often have advanced examples such as:

    • BLE server + client gateway
    • Multiple service and characteristic definitions
    • Secure BLE with authentication, encryption
    • BLE serial over GATT for general-purpose data transfer (akin to ble serial esp32)

    Using these GitHub examples can save you a ton of time, and you can modify them to suit your own design.

    Use Case: BLE Serial on ESP32

    Sometimes what you really want is a serial-over-BLE bridge: send text or binary data back and forth as if over a UART, but wirelessly. This pattern is often called ble serial esp32.

    Here’s how you can do it:

    1. On the server (ESP32), expose a characteristic with write and notify properties.
    2. The client (a phone app or another ESP32) writes commands/data to that characteristic.
    3. The server notifies when there is data to send back (or when data from sensors arrives).
    4. On the server, handle writes, and parse the data just as if it came over serial – maybe forward it somewhere, or act on it.

    This BLE serial pattern is super useful for remote debugging, remote control, or even wireless configuration of devices.

    Putting It All Together: A Practical Project

    Let me walk you through a practical project an idea you could build with minimal parts:

    Project: BLE Environmental Monitor + Remote Dashboard

    • Hardware: ESP32 board + temperature/humidity sensor (say DHT22) + optionally a battery.
    • Goal: Read sensor data on the ESP32, expose it via a BLE server, and have a mobile app connect to read and get notifications. Also, ESP32 as a BLE client connects to a BLE light device to control light based on sensor data.

    Steps:

    1. Set up BLE server on the ESP32:
      • Create a service: “Environment Service”
      • Characteristic “Temperature”, “Humidity” readable and notifiable.
    2. Read sensor data periodically (e.g., every second).
      • When new values come in, call pTempCharacteristic->setValue() and notify(); same for humidity.
    3. Allow BLE clients (mobile app) to connect:
      • On connect, send the current values immediately.
      • Notify on changes.
    4. Set up BLE client functionality:
      • The same ESP32 also scans for a BLE peripheral light (or another ESP32).
      • On connecting, write a command to turn on/off the light based on temperature or humidity thresholds.
    5. Handle multiple clients:
      • Your phone and maybe another device (e.g., a tablet) can connect simultaneously to read environment data.
    6. Robustness:
      • When your mobile phone disconnects, restart advertising.
      • If the light device disconnects, reconnect periodically or attempt scanning again.

    This is a real case combining esp32 ble server, esp32 ble client, esp32 ble gateway, esp32 ble client write to server, and esp32 ble server multiple clients.

    Common Pitfalls and Debugging Tips

    Since you’re just getting started, here are some common mistakes and how to handle them:

    1. Forget to add BLE2902 descriptor
      • Without BLE2902, a client may not be able to enable notifications.
    2. Not starting advertising correctly
      • Ensure you call BLEAdvertising->start() after you set up services.
    3. Blocking loop
      • In loop(), avoid long blocking delays if you also need to handle BLE tasks. Use small delays or non-blocking code.
    4. Memory issues
      • BLE can use a chunk of memory on ESP32. If you add too many services or characteristics, or handle too many clients, you might hit memory limits.
    5. MTU too small
      • If you send large data, negotiate a larger MTU or break data into smaller pieces.
    6. Security not enabled
      • If you notice random disconnections, or if you need secure communication, turn on pairing/bonding.
    7. Unreliable notifications
      • If notifications don’t always arrive, make sure clients have properly enabled them, and check the connection quality.

    Why This Matters: Real‑World Impact

    Building an ESP32 BLE server isn’t just a fun electronics project it can have real-world impact:

    • Home automation: Use ESP32 as a BLE gateway in your smart home. It listens to sensors, forwards updates, and controls actuators.
    • Wearables: Build low-power wearable devices that report data to a phone without needing Wi-Fi.
    • Industrial IoT: Use ESP32 BLE in sensor networks where each device reports to a BLE hub.
    • Remote debugging: Use ble serial esp32 to get logs from your device without plugging it in.
    • Prototyping: Quickly prototype Bluetooth peripherals (like health trackers or remotes) without paying for expensive hardware.

    Summary: Key Takeaways

    • BLE basics: Use GATT, services, characteristics; properties include read, write, notify.
    • You can run esp32 ble server and client same time, enabling advanced topologies like gateways.
    • Multiple clients are possible ESP32 can handle more than one device connecting.
    • For receiving data, set up write-enabled characteristics and handle writes.
    • For sending data, use notify with updated characteristic values.
    • Handle disconnects cleanly by restarting advertising and cleaning up.
    • Use Arduino code for esp32 arduino ble server example, which is beginner-friendly.
    • You can also explore esp32 ble client example to interact with your server.
    • Build a BLE gateway, combining server and client roles.
    • Implement ble serial esp32 to transfer arbitrary data as if over serial.
    • For inspiration and more examples, check out esp32 ble server GitHub projects.

    Final Thoughts

    If you’re just starting out, building an ESP32 BLE server is a very achievable and rewarding project. You’ll learn how BLE works at a fundamental level, how to structure services and characteristics, and how to move data back and forth between devices. Once you’ve done the basics, you can level up: handle multiple clients, incorporate BLE client code on the same ESP32, or build a whole BLE gateway that bridges BLE sensors to your phone or a backend server.

    What’s powerful is that the ESP32 ecosystem (especially with Arduino) hides a lot of the complexity. You don’t need to be a Bluetooth expert to get a working BLE server up and running. The code example above is just a starting point you can expand it to support your own UUIDs, data formats, and logic.

    Frequently Asked Questions About ESP32 BLE Server

    1. What is an ESP32 BLE Server?

    An ESP32 BLE Server is a Bluetooth Low Energy device running on the ESP32 that can send and receive data from BLE clients like smartphones, tablets, or other BLE devices. It’s ideal for low-power IoT projects.

    2. How do I create an ESP32 BLE Server?

    You can create an ESP32 BLE Server using the Arduino IDE and the BLEDevice library. Define your service and characteristic UUIDs, initialize the BLE device, create the server, start a service, and begin advertising.

    3. Can an ESP32 act as both BLE server and client?

    Yes! The ESP32 can act as a BLE server and client at the same time. This allows it to communicate with multiple devices, send data as a server, and read or write data to other BLE servers as a client.

    4. How many clients can connect to an ESP32 BLE Server?

    The ESP32 BLE Server can handle multiple clients simultaneously, though practical limits depend on your code and memory. Typically, 3-4 clients can be connected reliably for small IoT applications.

    5. How do I send data from an ESP32 BLE Server?

    To send data, use the setValue() and notify() functions on your BLE characteristic. The server pushes the data to connected clients whenever you need, such as sending sensor readings.

    6. How can an ESP32 BLE Server receive data from clients?

    The server can receive data by enabling the write property on a characteristic. The client writes data to the characteristic, and the server can handle it using callbacks to read and process incoming data.

    7. What is the difference between ESP32 BLE Server and Client?

    The ESP32 BLE Server provides services and characteristics for clients to connect and interact with, while a BLE client connects to servers to read, write, or receive notifications. They complement each other for full communication.

    8. Can I use Arduino IDE for ESP32 BLE Server?

    Absolutely! Arduino IDE makes it easy to program ESP32 BLE Server and client examples. You just need to install the ESP32 board package and use libraries like BLEDevice.h to create your BLE server quickly.

    9. How do I read a characteristic from an ESP32 BLE Server?

    Clients can read a characteristic value from the ESP32 BLE Server using the read property. On the server side, the characteristic value is set with setValue(), and clients can request it anytime.

    10. How do I disconnect a client from ESP32 BLE Server?

    Clients can disconnect voluntarily, or the server can disconnect clients using the BLEServer callbacks. Handling disconnect events allows you to manage connections and restart advertising if needed.

    11. Are there ESP32 BLE Server examples available?

    Yes! There are plenty of ESP32 BLE server examples, including simple read/write examples, multiple clients, and full client-server communication demos. You can find them on GitHub or in the Arduino BLE library documentation.

    12. What is a BLE Gateway using ESP32?

    An ESP32 BLE Gateway collects data from multiple BLE devices and forwards it to Wi-Fi or other networks. It acts as a bridge between BLE devices and the internet, making it perfect for smart home or IoT applications.

    13. Can I use BLE Serial with ESP32?

    Yes! BLE Serial allows you to send and receive serial data over BLE using the ESP32. This is especially useful for wireless communication with sensors, displays, or other microcontrollers without physical connections.