BLESerial allows serial communication over a BLE connection .
It implements the Nordic UART Service (NUS) as a server on a micro controller, providing commands like:
BLESerial ble;
ble.println("Hello");
n=ble.available();
ble.read(buffer,n);
It attempts to adapt for maximum throughput, low power usage or long distance communication.
The library provides a server implementation as it is designed to work with programs such as:
There are similar implementations from other authors: senseshift (lightweight and customizable) and afpineda (feature-rich NUS protocols and commands).
This implementation is a managed high-throughput BLE serial transport with adaptive link behavior and explicit reliability/streaming modes.
A throughput of more than 100k bytes/s and a latency of 10..20 ms was achieved.
Installation occurs through the Arduino library manager.
BLESerial uses the shared UUtzinger_logger level but has a dedicated diagnostic
output that defaults to Serial. Configure it before begin() with
ble.setDiagnosticOutput(Serial1) or any application-provided Print, including
a flash-file adapter. The BLESerial object itself is rejected as a diagnostic
destination. Application LOG() / LOGln() calls continue to follow the global
logSetOutput() destination and may intentionally target BLE.
Minimal example demonstrating setup, polling versus task (ESP32) mode, command parsing, and date transmission and receiving:
#include <Arduino.h> #include "BLESerial.h" #include "Linereader.h" BLESerial ble; LineReader<128> lr; char line[128]; const char helpmsg[] = "Commands: ?=help, stats, echo <text>"; void setup() { Serial.begin(115200); while (!Serial) { /* wait for USB serial */ } // Optional: Serial is the default. Serial1 or any custom Print is accepted. ble.setDiagnosticOutput(Serial); // Security::None | JustWorks | PasskeyDisplay // Mode::Fast | LowPower | LongRange | Balanced ble.begin(BLESerial::Mode::Fast, "BLESerialDevice", BLESerial::Security::None); #ifdef ARDUINO_ARCH_ESP32 ble.setPumpMode(BLESerial::PumpMode::Task); // background TX pump #endif Serial.println("BLESerial demo started."); } void loop() { if (ble.getPumpMode() == BLESerial::PumpMode::Polling) { ble.update(); } // Parse incoming lines from BLE if (lr.poll(ble, line, sizeof(line))) { if (strcasecmp(line, "?") == 0) { ble.println(helpmsg); Serial.println(helpmsg); } else if (strcasecmp(line, "stats") == 0) { ble.printStats(); // shows on Serial port } else if (strncasecmp(line, "echo ", 5) == 0) { ble.println(line + 5); } else { ble.println("Unknown command. Type ? for help."); } } }
- BLESerial_minimal (simple echo program)
- BLESerial_demo (simple program listed above)
- BLESerial_comprehensive (generates data for performance measurements)
- BLESerial_text_stress (validates reliable large text output over USB and BLE;
the
selflogcommand exercises the dedicated diagnostic route)
Urs Utzinger 2025
ChatGPT (OpenAI)
See LICENSE.