Skip to content

Commit df4a852

Browse files
committed
Towards finalized first release in Arduino Libraries
1 parent 7f0105d commit df4a852

12 files changed

Lines changed: 1990 additions & 2680 deletions

File tree

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,2 @@
11
# Changelog
2-
All notable changes to this project will be documented in this file.
3-
4-
5-
## [Unreleased]
2+
- November 2025 First release
Lines changed: 88 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,98 @@
11
# BLE Serial Library
22

3-
# Installation
3+
## Introduction
44

5-
# Dependencies
5+
BLESerial is a library that allows serial communication over a BLE connection. It implements the Nordic UART Service (NUS).
66

7-
# Quick Start
7+
You will need a program like SerialUI (https://github.com/uutzinger/SerialUI) to communicate with your micro controller as Arduino IDE Monitor does not yet have NUS support.
88

9-
# Conditioning
9+
Functions:
10+
- begin(mode, deviceName, secure);
11+
- end();
12+
- available();
13+
- read(); / read(*dst,n);
14+
- peek(); / peek(*dst, n);
15+
- write(b) / write(*b, n) override;
16+
- writeTimeout(t*p, n, timeoutMs);
17+
- writeReady()
18+
- writeAvailable(n)
19+
- flush()
20+
- update()
21+
22+
Setters:
23+
- setLogLevel(level);
24+
- requestMTU(mtu);
25+
26+
Status:
27+
- connected();
28+
- mtu();
29+
- mode();
30+
- bytesRx();
31+
- bytesTx();
32+
- rxDrops();
33+
- txDrops();
34+
- interval();
35+
- rssi()
36+
- mac();
37+
- txBuffered();
38+
- rxBuffered();
39+
40+
41+
## Installation
42+
43+
Installation occurs through the Arduino library manager.
44+
45+
Requires a terminal application on a client computer that supports NUS.
46+
47+
## Dependencies
48+
49+
- NimBLE (https://github.com/h2zero/NimBLE-Arduino)
50+
- RingBuffer (provided)
51+
52+
## Quick Start
53+
54+
```
55+
#import BLESerial
56+
#import LineReader
57+
58+
BLESerial ble;
59+
LineReader<128> lr;
60+
61+
void setup() {
62+
ble.begin(BLESerial::Mode::Fast, "BLESerialDevice", false)
63+
ble.setPumpMode(BLESerial::PumpMode::Polling);
64+
}
65+
66+
void loop(){
67+
68+
ble.update();
69+
70+
// read command
71+
if (lr.poll(ble, line, sizeof(line))) {
72+
auto reply = [&](const char* msg){
73+
Serial.println(msg);
74+
ble.write(reinterpret_cast<const uint8_t*>(msg), strlen(msg));
75+
ble.write(reinterpret_cast<const uint8_t*>("\r\n"), 2);
76+
};
77+
78+
if (strcasecmp(line, "?") == 0) {
79+
reply(helpmsg);
80+
} else if (...) {
81+
...
82+
}
83+
}
84+
85+
... generate data
86+
87+
ble.write(reinterpret_cast<const uint8_t*>(data), (size_t)dataLen);
88+
}
89+
90+
```
1091

1192
# Contributing
1293

94+
Urs Utzinger 2025
95+
1396
# License
1497

15-
See [LICENSE](LICENSE).
98+
See [LICENSE](License.txt).
Lines changed: 112 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,132 @@
1-
// ===== SERIAL ======
2-
inline constexpr unsigned long BAUDRATE = 2'000'000UL;
1+
# include <Arduino.h>
2+
#include <BLESerial.h>
3+
#include <Linereader.h>
34

4-
void setup() {
5+
constexpr unsigned long BAUDRATE = 2'000'000UL;
6+
constexpr uint8_t LED_PIN = LED_BUILTIN;
7+
constexpr bool useTaskPump = true; // set to 'false' to use polling mode
8+
9+
BLESerial ble;
10+
LineReader<128> lr;
511

6-
pinMode(ledPin, OUTPUT);
12+
char line[128]; // command line buffer
13+
char data[256]; // data output buffer
14+
bool paused = false; // do not generated data
15+
unsigned long lastBlinkUs = 0; // last LED blink time (microseconds)
16+
unsigned long blinkIntervalUs = 800'000; // LED blink interval (microseconds)
17+
bool ledState = LOW; // current LED state
18+
unsigned long lastDataUs = 0; // last data rate calc time (microseconds)
19+
unsigned long dataCount = 0;
20+
unsigned long dataCountPrev = 0;
21+
unsigned long currentTime;
22+
unsigned long rate = 0;
23+
24+
void setup() {
25+
// Initialize LED
26+
pinMode(LED_PIN, OUTPUT);
27+
digitalWrite(LED_PIN, LOW);
728

829
Serial.begin(BAUDRATE);
30+
while (!Serial && millis() < 5000) { delay(10); }
931

10-
currentTime = millis();
11-
while (!Serial && ( (millis() - currentTime) < 10000 )) { delay(5); }
12-
Serial.println("==================================================================");
13-
Serial.println("BLE Serial Test Program");
14-
Serial.println("==================================================================");
32+
Serial.println(F("=================================================================="));
33+
Serial.println(F("BLE Serial Test Program"));
34+
Serial.println(F("=================================================================="));
1535

1636
// Initialize PSRAM (optional check)
17-
if (psramInit()) {
18-
Serial.println("PSRAM initialized successfully.");
19-
Serial.printf("Total PSRAM: %d bytes\r\n", ESP.getPsramSize());
20-
Serial.printf("Free PSRAM: %d bytes\r\n", ESP.getFreePsram());
21-
} else {
22-
Serial.println("No PSRAM available.");
23-
}
37+
#ifdef ARDUINO_ARCH_ESP32
38+
if (psramInit()) {
39+
Serial.printf("PSRAM: total=%d free=%d\r\n", ESP.getPsramSize(), ESP.getFreePsram());
40+
} else {
41+
Serial.println("No PSRAM available.");
42+
}
43+
#endif
2444

45+
#ifdef ARDUINO_ARCH_ESP32
46+
ble.setPumpMode(useTaskPump ? BLESerial::PumpMode::Task : BLESerial::PumpMode::Polling);
47+
#endif
2548

26-
// Initialize BLESerial driver
27-
driver.begin("BLESerialDevice"); // device name
49+
if (!ble.begin(
50+
BLESerial::Mode::Fast,
51+
"BLESerialDevice",
52+
false
53+
)
54+
) {
55+
Serial.println(F("BLESerial begin() failed"));
56+
while (true) delay(1000);
57+
}
2858

2959
// Optionally configure parameters before calling begin()
30-
// driver.setTxPower(ESP_PWR_LVL_P9); // set transmit power
31-
// driver.setMTU(517); // set desired MTU
32-
// driver.setConnectionInterval(24, 40); // set min/max connection interval (in units of 1.25ms)
33-
34-
LineReader lr(driver);
60+
// ble.setTxPower(BLE_TX_DBP9); // set transmit power
61+
// ble.setMTU(517); // set desired MTU
3562

3663
}
3764

65+
3866
void loop() {
39-
char line[128];
40-
if (lr.poll(line, sizeof(line))) {
41-
// parse command
67+
currentTime = micros();
68+
69+
// BLE Serial Update
70+
// =======================================================
71+
if (!useTaskPump) {
72+
ble.update(); // polling pump
73+
}
74+
75+
// Command Receiver
76+
// =======================================================
77+
if (lr.poll(ble, line, sizeof(line)))
78+
{
79+
auto reply = [&](const char* msg){
80+
Serial.println(msg);
81+
ble.write(reinterpret_cast<const uint8_t*>(msg), strlen(msg));
82+
ble.write(reinterpret_cast<const uint8_t*>("\r\n"), 2);
83+
};
84+
85+
if (strcasecmp(line, "pause") == 0) {
86+
paused = true;
87+
reply("TX paused");
88+
} else if (strcasecmp(line, "resume") == 0) {
89+
paused = false;
90+
reply("TX resumed");
91+
} else if (strcasecmp(line, "status") == 0) {
92+
const char* modeStr = "Balanced";
93+
switch (ble.modeValue()) {
94+
case BLESerial::Mode::Fast: modeStr = "Fast"; break;
95+
case BLESerial::Mode::LowPower: modeStr = "LowPower"; break;
96+
case BLESerial::Mode::LongRange: modeStr = "LongRange"; break;
97+
default: break;
98+
}
99+
snprintf(data, sizeof(data),
100+
"Status: connected=%d txBuffered=%u mode=%s rssi=%d",
101+
ble.connected(), (unsigned)ble.txBuffered(), modeStr, ble.rssi());
102+
reply(data);
103+
}
104+
105+
106+
// Data Generator
107+
// =======================================================
108+
if (!paused && ble.connected() && ble.writeReady()) {
109+
if (currentTime - lastDataUs >= 1'000'000UL) {
110+
rate = dataCount - dataCountPrev;
111+
lastDataUs = currentTime;
112+
dataCountPrev = dataCount;
42113
}
43114

44-
driver.update(); // pumps TX and handles time-based backoff
45-
// rest of app
115+
int dataLen = snprintf(data, sizeof(data),
116+
"count=%lu rate=%lu/s\r\n", dataCount++, rate);
117+
118+
ble.write(reinterpret_cast<const uint8_t*>(data), (size_t)dataLen);
119+
}
120+
121+
// Blink LED
122+
// =======================================================
123+
if ((currentTime - lastBlinkUs) >= blinkIntervalUs) {
124+
lastBlinkUs = currentTime;
125+
ledState = !ledState;
126+
digitalWrite(LED_PIN, ledState);
127+
blinkIntervalUs = ledState ? 200'000 : 800'000;
128+
}
129+
46130
}
47131

48132

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
name=BLESerial
22
version=1.0.0
33
author=Urs Utzinger
4-
maintainer=Urs Utinger
4+
maintainer=Urs Utzinger
55
sentence=Library for Nordic UART Service
66
paragraph=Provides Serial over BLE
7-
url=https://github.com/uutzinger/BLESerial
7+
url=https://github.com/uutzinger/Arduino_BLESerial
88
category=Serial
99
includes=BLESerial.h

0 commit comments

Comments
 (0)