Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 25 additions & 12 deletions examples/NimBLE_Stream_Client/NimBLE_Stream_Client.ino
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
* This allows you to use familiar methods like print(), println(),
* read(), and available() over BLE, similar to how you would use Serial.
*
* This example connects to the NimBLE_Stream_Server example.
* This example connects to the NimBLE_Stream_Server example using the Nordic UART
* Service (NUS) with separate TX and RX characteristics.
*
* Created: November 2025
* Author: NimBLE-Arduino Contributors
Expand All @@ -16,9 +17,10 @@
#include <Arduino.h>
#include <NimBLEDevice.h>

// Service and Characteristic UUIDs (must match the server)
#define SERVICE_UUID "6E400001-B5A3-F393-E0A9-E50E24DCCA9E"
#define CHARACTERISTIC_UUID "6E400002-B5A3-F393-E0A9-E50E24DCCA9E"
// Nordic UART Service (NUS) UUIDs (must match the server)
#define SERVICE_UUID "6E400001-B5A3-F393-E0A9-E50E24DCCA9E"
#define TX_CHAR_UUID "6E400003-B5A3-F393-E0A9-E50E24DCCA9E" // Server TX: client subscribes here
#define RX_CHAR_UUID "6E400002-B5A3-F393-E0A9-E50E24DCCA9E" // Server RX: client writes here

// Create the stream client instance
NimBLEStreamClient bleStream;
Expand Down Expand Up @@ -116,7 +118,7 @@ bool connectToServer() {

Serial.println("Connected! Discovering services...");

// Get the service and characteristic
// Get the service
NimBLERemoteService* pRemoteService = pClient->getService(SERVICE_UUID);
if (!pRemoteService) {
Serial.println("Failed to find our service UUID");
Expand All @@ -125,19 +127,30 @@ bool connectToServer() {
}
Serial.println("Found the stream service");

NimBLERemoteCharacteristic* pRemoteCharacteristic = pRemoteService->getCharacteristic(CHARACTERISTIC_UUID);
if (!pRemoteCharacteristic) {
Serial.println("Failed to find our characteristic UUID");
// Get the TX characteristic (server sends notifications here; client subscribes for RX)
NimBLERemoteCharacteristic* pTxChar = pRemoteService->getCharacteristic(TX_CHAR_UUID);
if (!pTxChar) {
Serial.println("Failed to find TX characteristic");
pClient->disconnect();
return false;
}
Serial.println("Found the stream characteristic");
Serial.println("Found the TX characteristic");

// Get the RX characteristic (server receives writes here; client writes for TX)
NimBLERemoteCharacteristic* pRxChar = pRemoteService->getCharacteristic(RX_CHAR_UUID);
if (!pRxChar) {
Serial.println("Failed to find RX characteristic");
pClient->disconnect();
return false;
}
Serial.println("Found the RX characteristic");

/**
* Initialize the stream client with the remote characteristic
* subscribeNotify=true means we'll receive notifications in the RX buffer
* Initialize the stream client with separate TX and RX characteristics:
* - pRxChar: the characteristic we write to (our TX = server's RX, UUID 6E400002)
* - pTxChar: the characteristic we subscribe to (our RX = server's TX, UUID 6E400003)
*/
if (!bleStream.begin(pRemoteCharacteristic, true)) {
if (!bleStream.begin(pRxChar, pTxChar)) {
Serial.println("Failed to initialize BLE stream!");
pClient->disconnect();
return false;
Expand Down
16 changes: 9 additions & 7 deletions examples/NimBLE_Stream_Client/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,18 @@ This example demonstrates how to use the `NimBLEStreamClient` class to connect t

- Uses Arduino Stream interface (print, println, read, available, etc.)
- Automatic server discovery and connection
- Bidirectional communication
- Bidirectional communication using the Nordic UART Service (NUS)
- Buffered TX/RX using ring buffers
- Automatic reconnection on disconnect
- Compatible with NUS terminal apps and the NimBLE_Stream_Server example
- Similar usage to Serial communication

## How it Works

1. Scans for BLE devices advertising the target service UUID
2. Connects to the server and discovers the stream characteristic
3. Initializes `NimBLEStreamClient` with the remote characteristic
4. Subscribes to notifications to receive data in the RX buffer
1. Scans for BLE devices advertising the NUS service UUID
2. Connects to the server and discovers the TX and RX characteristics
3. Initializes `NimBLEStreamClient` with separate TX (write) and RX (subscribe) characteristics
4. Subscribes to the TX characteristic to receive data in the RX buffer
5. Uses familiar Stream methods like `print()`, `println()`, `read()`, and `available()`

## Usage
Expand All @@ -30,11 +31,12 @@ This example demonstrates how to use the `NimBLEStreamClient` class to connect t
- Begin bidirectional communication
4. You can also type in the Serial monitor to send data to the server

## Service UUIDs
## Service UUIDs (Nordic UART Service)

Must match the server:
- Service: `6E400001-B5A3-F393-E0A9-E50E24DCCA9E`
- Characteristic: `6E400002-B5A3-F393-E0A9-E50E24DCCA9E`
- TX Characteristic (server → client, client subscribes): `6E400003-B5A3-F393-E0A9-E50E24DCCA9E`
- RX Characteristic (client → server, client writes): `6E400002-B5A3-F393-E0A9-E50E24DCCA9E`

## Serial Monitor Output

Expand Down
22 changes: 14 additions & 8 deletions examples/NimBLE_Stream_Server/NimBLE_Stream_Server.ino
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
* This allows you to use familiar methods like print(), println(),
* read(), and available() over BLE, similar to how you would use Serial.
*
* Uses the Nordic UART Service (NUS) UUIDs with separate TX and RX characteristics
* for compatibility with NUS terminal apps (e.g. nRF UART, Serial Bluetooth Terminal).
*
* Created: November 2025
* Author: NimBLE-Arduino Contributors
*/
Expand Down Expand Up @@ -36,10 +39,11 @@ NimBLEStream::RxOverflowAction onRxOverflow(const uint8_t* data, size_t len, voi
return NimBLEStream::DROP_OLDER_DATA;
}

// Service and Characteristic UUIDs for the stream
// Using custom UUIDs - you can change these as needed
#define SERVICE_UUID "6E400001-B5A3-F393-E0A9-E50E24DCCA9E"
#define CHARACTERISTIC_UUID "6E400002-B5A3-F393-E0A9-E50E24DCCA9E"
// Nordic UART Service (NUS) UUIDs
// Using separate TX and RX characteristics for compatibility with NUS terminal apps.
#define SERVICE_UUID "6E400001-B5A3-F393-E0A9-E50E24DCCA9E"
#define TX_CHAR_UUID "6E400003-B5A3-F393-E0A9-E50E24DCCA9E" // Server TX: notify (server → client)
#define RX_CHAR_UUID "6E400002-B5A3-F393-E0A9-E50E24DCCA9E" // Server RX: write (client → server)

/** Server callbacks to handle connection/disconnection events */
class ServerCallbacks : public NimBLEServerCallbacks {
Expand Down Expand Up @@ -68,21 +72,23 @@ void setup() {

/**
* Create the BLE server and set callbacks
* Note: The stream will create its own service and characteristic
* Note: The stream will create its own service and characteristics
*/
NimBLEServer* pServer = NimBLEDevice::createServer();
pServer->setCallbacks(&serverCallbacks);

/**
* Initialize the stream server with:
* Initialize the stream server with NUS UUIDs using separate TX and RX characteristics:
* - Service UUID
* - Characteristic UUID
* - TX Characteristic UUID: server sends notifications here (client subscribes)
* - RX Characteristic UUID: client writes here (server receives)
* - txBufSize: 1024 bytes for outgoing data (notifications)
* - rxBufSize: 1024 bytes for incoming data (writes)
* - secure: false (no encryption required - set to true for secure connections)
*/
if (!bleStream.begin(NimBLEUUID(SERVICE_UUID),
NimBLEUUID(CHARACTERISTIC_UUID),
NimBLEUUID(TX_CHAR_UUID),
NimBLEUUID(RX_CHAR_UUID),
1024, // txBufSize
1024, // rxBufSize
false)) // secure
Expand Down
21 changes: 11 additions & 10 deletions examples/NimBLE_Stream_Server/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,37 +6,38 @@ This example demonstrates how to use the `NimBLEStreamServer` class to create a

- Uses Arduino Stream interface (print, println, read, available, etc.)
- Automatic connection management
- Bidirectional communication
- Bidirectional communication using the Nordic UART Service (NUS)
- Buffered TX/RX using ring buffers
- Compatible with NUS terminal apps (nRF UART, Serial Bluetooth Terminal, etc.)
- Similar usage to Serial communication

## How it Works

1. Creates a BLE GATT server with a custom service and characteristic
2. Initializes `NimBLEStreamServer` with the characteristic configured for notifications and writes
1. Creates a BLE GATT server with the NUS service and two separate characteristics (TX and RX)
2. Initializes `NimBLEStreamServer` with separate TX (notify) and RX (write) characteristics
3. Uses familiar Stream methods like `print()`, `println()`, `read()`, and `available()`
4. Automatically handles connection state and MTU negotiation

## Usage

1. Upload this sketch to your ESP32
2. The device will advertise as "NimBLE-Stream"
3. Connect with a BLE client (such as the NimBLE_Stream_Client example or a mobile app)
3. Connect with a BLE client (such as the NimBLE_Stream_Client example or a NUS terminal app)
4. Once connected, the server will:
- Send periodic messages to the client
- Echo back any data received from the client
- Display all communication on the Serial monitor

## Service UUIDs
## Service UUIDs (Nordic UART Service)

- Service: `6E400001-B5A3-F393-E0A9-E50E24DCCA9E`
- Characteristic: `6E400002-B5A3-F393-E0A9-E50E24DCCA9E`

These are based on the Nordic UART Service (NUS) UUIDs for compatibility with many BLE terminal apps.
- TX Characteristic (server → client, notify): `6E400003-B5A3-F393-E0A9-E50E24DCCA9E`
- RX Characteristic (client → server, write): `6E400002-B5A3-F393-E0A9-E50E24DCCA9E`

## Compatible With

- NimBLE_Stream_Client example
- nRF Connect mobile app
- Serial Bluetooth Terminal apps
- Any BLE client that supports characteristic notifications and writes
- nRF UART app
- Serial Bluetooth Terminal app
- Any BLE client that supports the Nordic UART Service (NUS)
Loading