|
1 | | -# BLE Serial Library |
| 1 | +# Graphical User Interface for Serial Communication |
2 | 2 |
|
3 | | -## Introduction |
| 3 | + **SerialUI** provides a graphical interface to send and receive text and data from the serial port or BLE connection (Nordic UART Service). |
4 | 4 |
|
5 | | -BLESerial is a library that allows serial communication over a BLE connection. It implements the Nordic UART Service (NUS). |
| 5 | +It includes a serial plotter for displaying numerical data. |
6 | 6 |
|
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. |
| 7 | +It offers features beyond other serial terminals. For example, in addition to features found on Arduino IDE Monitor or Plotter it offers: |
| 8 | +- Serial over BLE (NUS) |
| 9 | +- Recording of received data |
| 10 | +- Extended charting of the data |
| 11 | + |
| 12 | +Throughput is similar to other serial terminal programs. |
8 | 13 |
|
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() |
| 14 | +This program is written in python using PyQt <img src="docs/pyqt.png" height="30"/> and Bleak <img src="docs/bleak.png" height="30"/> as well as PyQtGraph <img src="docs/pyqtgraph.png" height="30"/> or fastplotlib <img src="docs/fastplotlib.png" height="30"/>. |
21 | 15 |
|
22 | | -Setters: |
23 | | -- setLogLevel(level); |
24 | | -- requestMTU(mtu); |
| 16 | +Under development are binary data transmission and indicating data with display elements other than a chart. |
25 | 17 |
|
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(); |
| 18 | +The main program is `SerialUI.py`. It uses files in the `assets`, `docs` and `helper` folders. |
39 | 19 |
|
| 20 | +## Video |
40 | 21 |
|
41 | | -## Installation |
| 22 | +Video using ESP32 with testBLESerial program. Data is transmitted using BLE Serial and maximum transfer test shows > 100 kByte/s. Device is initally connected to application with serial USB and then with serial BLE. |
42 | 23 |
|
43 | | -Installation occurs through the Arduino library manager. |
| 24 | +<a href="https://youtu.be/O6hl1_sOgLs"> |
| 25 | + <img src="https://img.youtube.com/vi/O6hl1_sOgLs/maxresdefault.jpg" alt="Video" width="600"> |
| 26 | +</a> |
44 | 27 |
|
45 | | -Requires a terminal application on a client computer that supports NUS. |
| 28 | +## Description |
| 29 | +The serial monitor interface |
46 | 30 |
|
47 | | -## Dependencies |
| 31 | +<img src="docs/SerialMonitor.png" alt="Serial Monitor" width="600"/> |
48 | 32 |
|
49 | | -- NimBLE (https://github.com/h2zero/NimBLE-Arduino) |
50 | | -- RingBuffer (provided) |
| 33 | +The serial charting interface |
51 | 34 |
|
52 | | -## Quick Start |
| 35 | +<img src="docs/SerialPlotter.png" alt="Serial Plotter" width="600"/> |
53 | 36 |
|
54 | | -``` |
55 | | -#import BLESerial |
56 | | -#import LineReader |
| 37 | +Serial BLE extension |
57 | 38 |
|
58 | | -BLESerial ble; |
59 | | -LineReader<128> lr; |
| 39 | +<img src="docs/SerialBLE.png" alt="Serial BLE" width="600"/> |
60 | 40 |
|
61 | | -void setup() { |
62 | | - ble.begin(BLESerial::Mode::Fast, "BLESerialDevice", false) |
63 | | - ble.setPumpMode(BLESerial::PumpMode::Polling); |
64 | | -} |
| 41 | +## How to Use This Program |
65 | 42 |
|
66 | | -void loop(){ |
| 43 | +- [Usage instructions](docs/Instructions.md). |
| 44 | +- [Supplemental instructions](docs/Supplementalinstructions.md). |
| 45 | +- [Helpful readings to learn about QT and qtgraph](docs/Helpful_readings.md). |
67 | 46 |
|
68 | | - ble.update(); |
| 47 | +## Installation Requirements |
69 | 48 |
|
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 | | - }; |
| 49 | +*One liner Windows:* |
| 50 | + - `pip3 install pyqt6 pyqtgraph markdown wmi bleak` |
77 | 51 |
|
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 | | -} |
| 52 | +*One liner Linux:* |
| 53 | + - `pip3 install pyqt6 pyqtgraph markdown pyudev bleak` |
| 54 | + |
| 55 | +The following python modules are needed: |
| 56 | + |
| 57 | +- `pyqt5` or `pyqt6` user interface |
| 58 | +- `pyqtgraph` plotting |
| 59 | +- `fastplotlib` for high throughput plotting |
| 60 | +- `numpy` data gathering and manipulation |
| 61 | +- `markdown` help file |
| 62 | +- `wmi` on Windows for USB device notifications |
| 63 | +- `pyudev` on Linux for USB device notifications |
| 64 | +- `bleak` for bluetooth communication |
| 65 | +- `numba` acceleration of numpy code |
| 66 | + |
| 67 | +To install the optional accelerated text parser you need to navigate in your shell to the `helper` folder and then execute: |
| 68 | +- `python3 setup.py build_ext --inplace -v` |
| 69 | +- `pip install -e .` |
| 70 | +If you are using virtual env for python don't forget to activate it. |
| 71 | + |
| 72 | +If you rebuild, clean the previous build with: |
| 73 | +- `python3 setup.py clean --all || true` |
| 74 | +- `rm -rf build *.egg-info .eggs` |
| 75 | + |
| 76 | + |
| 77 | +This requires a c11 compiler and the python packages `pybind11` and `setuptools` to be available. |
| 78 | + |
| 79 | +A future version will also need: |
| 80 | +- `scipy` image decompression (FFT) |
| 81 | +- `cobs` serial data encoding (byte stuffing) |
| 82 | +- `tamp` for compression (lightweight for microcontrollers) |
| 83 | + |
| 84 | +## Enabling / Disabling Features |
| 85 | + |
| 86 | +The programs configuration is stored in `config.py` (main folder). Here you can enable/disable features such as: |
| 87 | +- USE_FASTPLOTLIB: Plotting with fastplotlib instead of pyqtgraph |
| 88 | +- USE_BLE: enable serial communication over BLE |
| 89 | +- USE_BLUETOOTHCTL: enable pairing and trusting of BLE devices (available on Unix like systems) |
| 90 | + |
| 91 | +## Modules |
| 92 | + |
| 93 | +The program is organized into these [modules](docs/Module_Organization.md). |
| 94 | + |
| 95 | +## Nordic UART Service - BLE |
| 96 | + |
| 97 | +The NUS provides a serial interface similar to regular USB interface for microcontrollers. |
| 98 | +The implementation on a microcontroller requires more programming effort than a simple `Serial.print` especially if secure connections and automatic reconnection is considered. BLE connections can be optimized for low power, extended distance or high throughput. |
| 99 | + |
| 100 | +A detailed example is the [BLE test program](./Arduino_programs/testBLESerial/testBLESerial.ino) which was used to test SerialUI. |
| 101 | + |
| 102 | +With ESP32-S3 a transfer rate of more than 100kByte/s can be expected when BLE connection is optimized for high throughput. |
| 103 | + |
| 104 | +## Data Parsing |
| 105 | + |
| 106 | +The data parser extract values and variable names from lines of text. Besides a python version, there is a C accelerated version available. For supported data formats see: [Data Parsing Approach](docs/Dataparsing.md) |
| 107 | + |
| 108 | +## Indicating Data |
| 109 | + |
| 110 | +Indicating data is not implemented yet: [Feature not implemented yet](docs/Indicating.md). |
| 111 | + |
| 112 | +## fastplotlib |
| 113 | + |
| 114 | +Fastplotlib itself is under development. There is a cusom legend.py in python libraries folder that is needed when you enable fastplotlib in the config file. The file replaces the legends.py of the creators. It needs more work. |
| 115 | + |
| 116 | +During program startup the library and the chart widget are initialized. This requires building the pipeline for the GPU which takes 5-10 seconds. During that time the program might be sluggish. |
| 117 | + |
| 118 | +## Arduino Test Programs |
| 119 | + |
| 120 | +In the `Arduino_programs` folder are example programs that simulate data for serial UART and BLE connection. |
| 121 | + |
| 122 | +## Efficiency |
| 123 | + |
| 124 | +A detailed [comparison of SerialUI with other serial IO programs](docs/Efficiency.md) was conducted. |
| 125 | + |
| 126 | +The SerialUI is as performant as other good terminal programs. The maximum text transfer of an ESP32-S3 over USB is about 800k bytes/s and 100k bytes/s over BLE. With a Cortex-M7 (Teensy) we reached about 7M bytes/s over USB. |
| 127 | + |
| 128 | +With both fastplotlib and pyqtgraph we can plot two channels with at least 200k samples per second at 10Hz plotting refresh rate. When large display history is needed fastplotlib with a dedicated GPU is better suited as plotting engine. |
| 129 | + |
| 130 | +## Packages utilized in this Project |
89 | 131 |
|
90 | | -``` |
| 132 | +The following libraries are used: |
91 | 133 |
|
92 | | -# Contributing |
| 134 | +- [asyncio for bleak](https://docs.python.org/3/library/asyncio.html)`**` |
| 135 | +- [bleak - BLE](https://github.com/hbldh/bleak)`**` |
| 136 | +- [cobs - serial binary](https://github.com/cmcqueen/cobs-python)`****` |
| 137 | +- [fastplotlib - GPU based charting](https://fastplotlib.org/)`***` beta |
| 138 | +- [datetime](https://docs.python.org/3/library/datetime.html) |
| 139 | +- [difflib - device ID comparison](https://docs.python.org/3/library/difflib.html) |
| 140 | +- [html - html display](https://docs.python.org/3/library/html.parser.html) |
| 141 | +- [logging](https://docs.python.org/3/library/logging.html) |
| 142 | +- [markdown - markdown display](https://python-markdown.github.io/) |
| 143 | +- [math](https://docs.python.org/3/library/math.html) |
| 144 | +- [numpy - data buffer and display](https://numpy.org/) |
| 145 | +- [numba - accelerator](https://numba.pydata.org/)`*` |
| 146 | +- [os](https://docs.python.org/3/library/os.html) |
| 147 | +- [pathlib](https://docs.python.org/3/library/pathlib.html) |
| 148 | +- [platform](https://docs.python.org/3/library/platform.html) |
| 149 | +- [pybind11 - text parsing acceleration](https://github.com/pybind/pybind11)`*` |
| 150 | +- [PyQt5 or 6 - UI](https://www.riverbankcomputing.com/software/pyqt/) |
| 151 | +- [pyqtgraph - charting](https://www.pyqtgraph.org/) |
| 152 | +- [re - regular expression filter](https://docs.python.org/3/library/re.html) |
| 153 | +- [scipy - fft](https://scipy.org/) `***` |
| 154 | +- [setuptools](https://github.com/pypa/setuptools)`*` |
| 155 | +- [tamp - compressor](https://github.com/BrianPugh/tamp) `***` |
| 156 | +- [textwrap - logging](https://docs.python.org/3/library/textwrap.html) |
| 157 | +- [time](https://docs.python.org/3/library/time.html) |
| 158 | +- [typing](https://docs.python.org/3/library/typing.html) |
| 159 | +- [wmi - USB events](https://timgolden.me.uk/python/wmi/index.html) or [pyudev - USB events](https://pyudev.readthedocs.io/en/latest/) |
| 160 | +- [zlib - compressor](https://docs.python.org/3/library/zlib.html) `***` |
93 | 161 |
|
94 | | -Urs Utzinger 2025 |
| 162 | +[`*`] not required but will accelerate the program, |
| 163 | +[`**`] needed if BLE is enabled, |
| 164 | +[`***`] needed if fastplotlib is enabled |
| 165 | +[`***`] future version |
95 | 166 |
|
96 | | -# License |
| 167 | +## Contributors |
97 | 168 |
|
98 | | -See [LICENSE](License.txt). |
| 169 | +Urs Utzinger, 2022-2025 (University of Arizona), |
| 170 | +Cameron K Brooks, 2024 (Western University), |
| 171 | +ChatGPT (OpenAI) |
0 commit comments