ArduinoDumbDisplay v0.9.9-r34
DumbDisplay Arduino Library -- https://github.com/trevorwslee/Arduino-DumbDisplay
 
Loading...
Searching...
No Matches
esp32bledumbdisplay.h
1//************************************************//
2//*** must define DD_4_ESP32 before includeing ***/
3//************************************************//
4
5#ifndef esp32bledumbdisplay_h
6#define esp32bledumbdisplay_h
7
8// after inclusion, can check DD_USING_WIFI to be sure WIFI is used
9#define DD_USING_LE
10
11// #ifndef DD_4_ESP32
12// #error DD_4_ESP32 need be defined in order to use DumbDisplay for ESP32 BLE
13// #else
14
15
16#ifndef ESP32
17 #error DDBLESerialIO is for ESP32
18#endif
19
20// #ifndef ESP32
21// #error DDBLESerialIO is for ESP32
22// #else
23
24#include <BLEDevice.h>
25#include <BLEServer.h>
26#include <BLEUtils.h>
27#include <BLE2902.h>
28#include "dumbdisplay.h"
29
30#define DD_SERVICE_UUID "6E400001-B5A3-F393-E0A9-E50E24DCCA9E" // UART service UUID
31#define DD_CHARACTERISTIC_UUID_RX "6E400002-B5A3-F393-E0A9-E50E24DCCA9E"
32#define DD_CHARACTERISTIC_UUID_TX "6E400003-B5A3-F393-E0A9-E50E24DCCA9E"
33
34#define DD_RECEIVE_BUFFER_SIZE 256
35#define DD_SEND_BUFFER_SIZE 20
36
37// using DD_BLE_NOTIFY is faster, but not as reliable
38// #define DD_BLE_NOTIFY
39
40//#define DD_DEBUG_BLE
41//#define DD_DEBUG_BLE_SEND
42//#define DD_DEBUG_BLE_RECEIVE
43
44
45
48 public:
49 /* ESP32 BLE IO mechanism */
50 /* - deviceName -- BLE device name */
51 /* - enableSerial: enable Serial as well or not (if enabled, connecting via USB will also work) */
52 /* - serialBaud: Serial baud rate (if enableSerial) */
53 DDBLESerialIO(const String& deviceName, bool enableSerial = false,
54 unsigned long serialBaud = DD_SERIAL_BAUD):
55 DDInputOutput(serialBaud, enableSerial, enableSerial) {
56 this->deviceName = deviceName;
57 this->initialized = false;
58 // if (!enableSerial) {
59 // Serial.begin(serialBaud);
60 // }
61 }
62 const char* getWhat() {
63 return "ESP32BLE";
64 }
65 bool available() {
66 return pCallbacks->available();
67 }
68 char read() {
69 return pCallbacks->read();
70 }
71 void print(const String &s) {
72 pCallbacks->print(s.c_str());
73 }
74 void print(const char *p) {
75 pCallbacks->print(p);
76 }
77 void write(uint8_t b) {
78 pCallbacks->write(b);
79 }
80 bool preConnect(bool firstCall) {
81#ifdef DD_DEBUG_BLE
82 if (!setupForSerial) {
83 Serial.begin(115200);
84 }
85#endif
86 DDInputOutput::preConnect(firstCall);
87 if (!initialized) {
88 initBLE();
89 } else {
90 if (!willUseSerial()) { // since 2024-08-13
91 if (firstCall) {
92 if (!Serial) Serial.begin(DD_SERIAL_BAUD);
93 }
94 Serial.println("ble address: " + address);
95 }
96// #ifdef DD_DEBUG_BLE
97// if (firstCall) {
98// Serial.println("FIRST preConnect() called, but already initialized");
99// } else {
100// Serial.println("preConnect() called, but already initialized");
101// }
102// #endif
103 if (pServerCallbacks->isDisconnected()) {
104 pServerCallbacks->restartAdvertising();
105 }
106 }
107 return true;
108 }
109 void flush() {
110 }
111 void validConnection() {
112 if (pServerCallbacks->isDisconnected()) {
113 delay(500); // give the bluetooth stack the chance to get things ready
114 pServerCallbacks->restartAdvertising();
115#ifdef DD_DEBUG_BLE
116 Serial.println("... connection lost ... waiting for re-connection ...");
117#endif
118 }
119 }
120 bool canConnectPassive() {
121 return true;
122 }
123 bool canUseBuffer() {
124 return false;
125 }
126 private:
127 class ServerCallbacks: public BLEServerCallbacks {
128 public:
129 ServerCallbacks(BLEServer* pServer) {
130 this->pServer = pServer;
131 this->connectionState = 0; // assume connecting
132 }
133 public:
134 void restartAdvertising() {
135 pServer->startAdvertising();
136 connectionState = 0;
137#ifdef DD_DEBUG_BLE
138 Serial.println("restarted advertising");
139#endif
140 }
141 bool isDisconnected() { return connectionState == -1; }
142 bool isConnected() { return connectionState == 1; }
143 bool isConnecting() { return connectionState == 0; }
144 public:
145 void onConnect(BLEServer* pServer) {
146 connectionState = 1;
147#ifdef DD_DEBUG_BLE
148 Serial.println("BLE connected");
149#endif
150 };
151 void onDisconnect(BLEServer* pServer) {
152 connectionState = -1;
153#ifdef DD_DEBUG_BLE
154 Serial.println("BLE disconnected");
155#endif
156 }
157 private:
158 BLEServer* pServer;
159 int connectionState;
160 };
161 class Callbacks: public BLECharacteristicCallbacks {
162 public:
163 Callbacks(BLECharacteristic *pTx, ServerCallbacks* pServerCallbacks) {
164 this->pTx = pTx;
165 this->pServerCallbacks = pServerCallbacks;
166 this->buffering = false;
167 this->bufferStart = 0;
168 this->bufferEnd = 0;
169#ifdef DD_SEND_BUFFER_SIZE
170 this->sendBufferSize = 0;
171#endif
172 }
173 public:
174 void print(std::string s) {
175#ifdef DD_SEND_BUFFER_SIZE
176 int len = s.length();
177 if ((len + sendBufferSize) > DD_SEND_BUFFER_SIZE) {
178 _flushSendBuffer();
179 if (len > DD_SEND_BUFFER_SIZE) {
180 _print(s.c_str());
181 return;
182 }
183 }
184 for (int i = 0; i < len; i++) {
185 sendBuffer[sendBufferSize++] = s[i];
186 }
187 if (sendBufferSize > 0 && sendBuffer[sendBufferSize - 1] == '\n') {
188 _flushSendBuffer();
189 }
190#else
191 _print(s.c_str());
192#endif
193 }
194 void write(uint8_t b) {
195 int s = b;
196 pTx->setValue(s);
197#ifdef DD_BLE_NOTIFY
198 pTx->notify();
199#else
200 pTx->indicate();
201#endif
202 }
203 bool available() {
204 while (true) {
205 if (!buffering) {
206 return bufferStart != bufferEnd;
207 }
208 yield();
209 }
210 }
211 char read() {
212 while (true) {
213 if (!buffering) {
214 char c = buffer[bufferStart];
215 if (++bufferStart >= DD_RECEIVE_BUFFER_SIZE) {
216 bufferStart = 0;
217 }
218 return c;
219 }
220 yield();
221 }
222 }
223 private:
224#ifdef DD_SEND_BUFFER_SIZE
225 void _flushSendBuffer() {
226 if (sendBufferSize > 0) {
227 sendBuffer[sendBufferSize] = 0;
228 _print(sendBuffer);
229 sendBufferSize = 0;
230 }
231 }
232#endif
233 void _print(std::string s) {
234#if defined(DD_DEBUG_BLE_SEND)
235 if (pServerCallbacks->isConnected()) {
236 } else if (pServerCallbacks->isConnecting()) {
237 Serial.print("[connecting] ");
238 } else {
239 Serial.print("[not connected] ");
240 }
241 Serial.print("BLE sent ... [");
242 Serial.print(s.c_str());
243 Serial.println("]");
244#endif
245 int len = s.length();
246 while (len > 0) {
247 if (len <= 20) { // 20 is the BLE limit
248 pTx->setValue(s);
249#ifdef DD_BLE_NOTIFY
250 pTx->notify();
251#else
252 pTx->indicate();
253#endif
254 break;
255 } else {
256 pTx->setValue(s.substr(0, 20));
257#ifdef DD_BLE_NOTIFY
258 pTx->notify();
259#else
260 pTx->indicate();
261#endif
262 s = s.substr(20);
263 len -= 20;
264 }
265 }
266 }
267 public:
268 void onWrite(BLECharacteristic *pCharacteristic) {
269 buffering = true;
270 std::string rxValue = pCharacteristic->getValue();
271 int count = rxValue.size();
272 for (int i = 0; i < count; i++) {
273 int nextBufferEnd = bufferEnd + 1;
274 if (nextBufferEnd >= DD_RECEIVE_BUFFER_SIZE) {
275 nextBufferEnd = 0;
276 }
277 if (nextBufferEnd == bufferStart) {
278 break;
279 }
280 buffer[bufferEnd] = rxValue[i];
281 bufferEnd = nextBufferEnd;
282 }
283#ifdef DD_DEBUG_BLE_RECEIVE
284 Serial.print("BLE received ... ");
285 Serial.print(count);
286 Serial.print(" ... [");
287 Serial.print(rxValue.c_str());
288 Serial.print("] ==> ");
289 Serial.print(bufferStart);
290 Serial.print('-');
291 Serial.print(bufferEnd);
292 Serial.print('/');
293 Serial.print(DD_RECEIVE_BUFFER_SIZE);
294 Serial.println();
295#endif
296 buffering = false;
297 }
298 private:
299 BLECharacteristic *pTx;
300 ServerCallbacks* pServerCallbacks;
301 volatile bool buffering;
302 uint8_t bufferStart;
303 uint8_t bufferEnd;
304 char buffer[DD_RECEIVE_BUFFER_SIZE];
305#ifdef DD_SEND_BUFFER_SIZE
306 uint8_t sendBufferSize;
307 char sendBuffer[DD_SEND_BUFFER_SIZE + 1];
308#endif
309 };
310 private:
311 void initBLE() {
312#ifdef DD_DEBUG_BLE
313 Serial.println("initialized BLE ...");
314#endif
315 BLEDevice::init(deviceName.c_str());
316 BLEServer *pServer = BLEDevice::createServer();
317 pServerCallbacks = new ServerCallbacks(pServer);
318 pServer->setCallbacks(pServerCallbacks);
319 BLEService *pService = pServer->createService(DD_SERVICE_UUID);
320 BLECharacteristic *pTx = pService->createCharacteristic(
321 DD_CHARACTERISTIC_UUID_TX,
322#ifdef DD_BLE_NOTIFY
323 BLECharacteristic::PROPERTY_NOTIFY
324#else
325 BLECharacteristic::PROPERTY_INDICATE
326#endif
327 );
328 pTx->addDescriptor(new BLE2902());
329 BLECharacteristic *pRx = pService->createCharacteristic(
330 DD_CHARACTERISTIC_UUID_RX,
331 BLECharacteristic::PROPERTY_WRITE
332 );
333 pCallbacks = new Callbacks(pTx, pServerCallbacks);
334 pRx->setCallbacks(pCallbacks);
335 pService->start();
336 pServer->getAdvertising()->start();
337 initialized = true;
338 address = BLEDevice::getAddress().toString().c_str();
339 address.toUpperCase();
340 //serviceUUID = pService->getUUID().toString().c_str();
341#ifdef DD_DEBUG_BLE
342 Serial.println("... done initialized BLE ... waiting for connection ...");
343#endif
344 }
345 private:
346 String deviceName;
347 String address;
348 bool initialized;
349 ServerCallbacks* pServerCallbacks;
350 Callbacks* pCallbacks;
351};
352
353
354//#endif
355#endif
Subclass of DDInputOutput.
Definition: esp32bledumbdisplay.h:47
Class for DD input/output; you explicitly constructed it, pass in when instantiate DumbDisplay,...
Definition: _dd_io.h:9