├── keywords.txt ├── .gitignore ├── library.properties ├── examples ├── BLESerialGraph │ └── BLESerialGraph.ino ├── BLESerialInput │ └── BLESerialInput.ino └── BLESerialSimple │ └── BLESerialSimple.ino ├── src ├── BLESerial.h └── BLESerial.cpp └── readme.MD /keywords.txt: -------------------------------------------------------------------------------- 1 | BLESerial KEYWORD1 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .pio 2 | .pioenvs 3 | .piolibdeps 4 | .vscode/.browse.c_cpp.db* 5 | .vscode/c_cpp_properties.json 6 | .vscode/launch.json 7 | -------------------------------------------------------------------------------- /library.properties: -------------------------------------------------------------------------------- 1 | name=BLESerial 2 | version=0.1.0 3 | author=Ian Archbell of oddWires 4 | maintainer= 5 | sentence=This library makes it simple to send and received data that would normally go to or be sent by the serial monitor. 6 | paragraph=It is based on the BLE implementation originally created by Neil Kolban and included in the Espressif esp32 distribution. 7 | category=Communication 8 | url=https://github.com/iot-bus/BLESerial 9 | architectures=esp32 10 | includes=BLESerial.h -------------------------------------------------------------------------------- /examples/BLESerialGraph/BLESerialGraph.ino: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | BLESerial was written by Ian Archbell of oddWires. It is based on the BLE implementation 4 | originally created by Neil Kolban and included in the Espressif esp32 distribution. 5 | This library makes it simple to send and received data that would normally go to or be sent by 6 | the serial monitor. The interface is very similar so most usage is identical. 7 | 8 | To use: 9 | 10 | 1. Create an instance of BLESerial 11 | 2. Make sure you call begin() 12 | 13 | In this example we use BLESerial to use in a similair way as the "graph" example in the IDE. 14 | You could use this P5 sketch to plot the data from the Arduino (if using chrome) 15 | https://editor.p5js.org/lemio/sketches/qKGGxBG4C 16 | Or use the Adafruit "Bluefruit Connect" App. 17 | 18 | */ 19 | 20 | #include "BLESerial.h" 21 | BLESerial bleSerial; 22 | 23 | void setup() { 24 | Serial.begin(115200); 25 | bleSerial.begin("BLE-UART"); 26 | } 27 | 28 | void loop() { 29 | //If we're connected 30 | if (bleSerial.connected()){ 31 | //Send the analog value 32 | bleSerial.println(analogRead(A0)); 33 | Serial.println(analogRead(A0)); 34 | //Wait for 0.1 second 35 | delay(100); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /examples/BLESerialInput/BLESerialInput.ino: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | BLESerial was written by Ian Archbell of oddWires. It is based on the BLE implementation 4 | originally created by Neil Kolban and included in the Espressif esp32 distribution. 5 | This library makes it simple to send and received data that would normally go to or be sent by 6 | the serial monitor. The interface is very similar so most usage is identical. 7 | 8 | To use: 9 | 10 | 1. Create an instance of BLESerial 11 | 2. Make sure you call begin() 12 | 13 | In this example we don't redefine bleSerial as Serial as we want to use both the bluetooth serial and the regular serial monitor. 14 | 15 | There is a connected() method that enables you to find out whether a bluetooth central manager is connected. 16 | 17 | You will need an Ios or Android app on your phone that will connect to the Nordic BLE Serial UART service 18 | and use its associated characteristics. 19 | 20 | We suggest using basic-chat which is a Bluetooth Low Energy App for iOS using Swift originally written by Adafruit. 21 | This fork is updated for Swift 4 and to easily interface with BLESerial library for esp32 on github at: 22 | https://github.com/iot-bus/basic-chat 23 | 24 | */ 25 | 26 | #include "BLESerial.h" 27 | #include 28 | 29 | BLESerial bleSerial; 30 | 31 | #define LEDPin 5 32 | 33 | void setup() { 34 | Serial.begin(115200); 35 | bleSerial.begin("IoT-Bus Bluetooth Serial"); 36 | pinMode(LEDPin, OUTPUT); 37 | digitalWrite(LEDPin, LOW); 38 | } 39 | 40 | void loop() { 41 | if (bleSerial.connected()){ 42 | digitalWrite(LEDPin, LOW); 43 | // Read input 44 | if(bleSerial.available()) 45 | { 46 | Serial.println("*********"); 47 | while(bleSerial.available()) 48 | { 49 | Serial.write(bleSerial.read()); 50 | } 51 | Serial.println("*********"); 52 | } 53 | } 54 | else{ 55 | digitalWrite(LEDPin, HIGH); 56 | } 57 | } 58 | 59 | -------------------------------------------------------------------------------- /src/BLESerial.h: -------------------------------------------------------------------------------- 1 | // Copyright 2019 Ian Archbell / oddWires 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #ifndef _BLE_SERIAL_H_ 16 | #define _BLE_SERIAL_H_ 17 | 18 | #include "Arduino.h" 19 | #include "Stream.h" 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | #define SERVICE_UUID "6E400001-B5A3-F393-E0A9-E50E24DCCA9E" // UART service UUID 26 | #define CHARACTERISTIC_UUID_RX "6E400002-B5A3-F393-E0A9-E50E24DCCA9E" 27 | #define CHARACTERISTIC_UUID_TX "6E400003-B5A3-F393-E0A9-E50E24DCCA9E" 28 | 29 | class BLESerial: public Stream 30 | { 31 | public: 32 | 33 | BLESerial(void); 34 | ~BLESerial(void); 35 | 36 | bool begin(char* localName="IoT-Bus UART Service"); 37 | int available(void); 38 | int peek(void); 39 | bool connected(void); 40 | int read(void); 41 | size_t write(uint8_t c); 42 | size_t write(const uint8_t *buffer, size_t size); 43 | void flush(); 44 | void end(void); 45 | 46 | private: 47 | String local_name; 48 | BLEServer *pServer = NULL; 49 | BLEService *pService; 50 | BLECharacteristic * pTxCharacteristic; 51 | bool deviceConnected = false; 52 | uint8_t txValue = 0; 53 | 54 | std::string receiveBuffer; 55 | 56 | friend class BLESerialServerCallbacks; 57 | friend class BLESerialCharacteristicCallbacks; 58 | 59 | }; 60 | 61 | #endif 62 | -------------------------------------------------------------------------------- /examples/BLESerialSimple/BLESerialSimple.ino: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | BLESerial was written by Ian Archbell of oddWires. It is based on the BLE implementation 4 | originally created by Neil Kolban and included in the Espressif esp32 distribution. 5 | This library makes it simple to send and received data that would normally go to or be sent by 6 | the serial monitor. The interface is very similar so most usage is identical. 7 | 8 | To use: 9 | 10 | 1. Create an instance of BLESerial 11 | 2. Define it as Serial (not necessary as you can use it directly as your named instance 12 | but makes it easy to add to existing programs) 13 | 3. Make sure you call begin() 14 | 15 | There is a connected() method that enables you to find out whether a bluetooth central manager is connected. 16 | 17 | You will need an Ios or Android app on your phone that will connect to the Nordic BLE Serial UART service 18 | and use its associated characteristics. 19 | 20 | We suggest using basic-chat which is a Bluetooth Low Energy App for iOS using Swift originally written by Adafruit. 21 | This fork is updated for Swift 4 and to easily interface with BLESerial library for esp32 on github at: 22 | https://github.com/iot-bus/basic-chat 23 | 24 | */ 25 | 26 | #include "BLESerial.h" 27 | #include 28 | 29 | BLESerial bleSerial; 30 | 31 | char message[] = "A message"; 32 | 33 | #define Serial bleSerial 34 | 35 | #define LEDPin 5 36 | 37 | void setup() { 38 | Serial.begin("IoT-Bus Bluetooth Serial"); 39 | pinMode(LEDPin, OUTPUT); 40 | digitalWrite(LEDPin, LOW); 41 | } 42 | 43 | void loop() { 44 | if (Serial.connected()){ 45 | 46 | digitalWrite(LEDPin, HIGH); 47 | // some output 48 | Serial.println("Output being sent to Bluetooth"); 49 | Serial.println("Starting"); 50 | 51 | for(int i=0; i "Include Library" -> "Add .ZIP Library..." and select the file you just downloaded. 14 | - Select an ESP32 board in "Tools" -> "Board" 15 | - You can now go to "File" -> "Examples" -> "BLESerial" and select any of the examples to get started. 16 | 17 | ## Example 18 | 19 | ``` C++ 20 | #include "BLESerial.h" 21 | BLESerial bleSerial; 22 | 23 | void setup() { 24 | Serial.begin(115200); 25 | bleSerial.begin("BLE-UART"); 26 | } 27 | 28 | void loop() { 29 | //If we're connected 30 | if (bleSerial.connected()){ 31 | //Send the analog value through BLE/Serial 32 | bleSerial.println(analogRead(A0)); 33 | //Send the analog value through USB/Serial 34 | Serial.println(analogRead(A0)); 35 | //Wait for 0.1 second 36 | delay(100); 37 | } 38 | } 39 | ``` 40 | 41 | In this example we don't redefine bleSerial as Serial as we want to use both the bluetooth serial and the regular serial monitor. 42 | 43 | There is a connected() method that enables you to find out whether a bluetooth central manager is connected. 44 | 45 | You will need an Ios or Android app on your phone that will connect to the Nordic BLE Serial UART service 46 | and use its associated characteristics. 47 | 48 | To interact with this the ESP32 there are several options: 49 | 50 | 1. Adafruit ["Bluefruit le Connect" App](https://learn.adafruit.com/bluefruit-le-connect), this lets you plot the values, see the messages, send messages and more... 51 | 2. If you want to create your own application useing P5 you can use [p5.ble.js](https://github.com/ITPNYU/p5.ble.js/tree/master/examples/BluefruitLE), we made [an example for plotting the values](https://editor.p5js.org/lemio/sketches/qKGGxBG4C). 52 | 3. Basic-chat which is a Bluetooth Low Energy App for iOS using Swift originally written by Adafruit. 53 | This fork is updated for Swift 4 and to easily interface with BLESerial library for esp32 on github at: 54 | https://github.com/iot-bus/basic-chat 55 | 56 | ## Credits 57 | 58 | BLESerial was written by Ian Archbell of oddWires. It is based on the BLE implementation 59 | originally created by Neil Kolban and included in the Espressif esp32 distribution. -------------------------------------------------------------------------------- /src/BLESerial.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2019 Ian Archbell / oddWires 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "BLESerial.h" 16 | 17 | class BLESerialServerCallbacks: public BLEServerCallbacks { 18 | friend class BLESerial; 19 | BLESerial* bleSerial; 20 | 21 | void onConnect(BLEServer* pServer) { 22 | // do anything needed on connection 23 | delay(1000); // wait for connection to complete or messages can be lost 24 | }; 25 | 26 | void onDisconnect(BLEServer* pServer) { 27 | pServer->startAdvertising(); // restart advertising 28 | Serial.println("Started advertising"); 29 | } 30 | }; 31 | 32 | class BLESerialCharacteristicCallbacks: public BLECharacteristicCallbacks { 33 | friend class BLESerial; 34 | BLESerial* bleSerial; 35 | 36 | void onWrite(BLECharacteristic *pCharacteristic) { 37 | 38 | bleSerial->receiveBuffer = bleSerial->receiveBuffer + pCharacteristic->getValue(); 39 | } 40 | 41 | }; 42 | 43 | // Constructor 44 | 45 | BLESerial::BLESerial() 46 | { 47 | // create instance 48 | receiveBuffer = ""; 49 | } 50 | 51 | // Destructor 52 | 53 | BLESerial::~BLESerial(void) 54 | { 55 | // clean up 56 | } 57 | 58 | // Begin bluetooth serial 59 | 60 | bool BLESerial::begin(char* localName) 61 | { 62 | // Create the BLE Device 63 | BLEDevice::init(localName); 64 | 65 | // Create the BLE Server 66 | pServer = BLEDevice::createServer(); 67 | if (pServer == nullptr) 68 | return false; 69 | 70 | BLESerialServerCallbacks* bleSerialServerCallbacks = new BLESerialServerCallbacks(); 71 | bleSerialServerCallbacks->bleSerial = this; 72 | pServer->setCallbacks(bleSerialServerCallbacks); 73 | 74 | // Create the BLE Service 75 | pService = pServer->createService(SERVICE_UUID); 76 | if (pService == nullptr) 77 | return false; 78 | 79 | // Create a BLE Characteristic 80 | pTxCharacteristic = pService->createCharacteristic( 81 | CHARACTERISTIC_UUID_TX, 82 | BLECharacteristic::PROPERTY_NOTIFY 83 | ); 84 | if (pTxCharacteristic == nullptr) 85 | return false; 86 | pTxCharacteristic->addDescriptor(new BLE2902()); 87 | 88 | BLECharacteristic * pRxCharacteristic = pService->createCharacteristic( 89 | CHARACTERISTIC_UUID_RX, 90 | BLECharacteristic::PROPERTY_WRITE 91 | ); 92 | if (pRxCharacteristic == nullptr) 93 | return false; 94 | 95 | BLESerialCharacteristicCallbacks* bleSerialCharacteristicCallbacks = new BLESerialCharacteristicCallbacks(); 96 | bleSerialCharacteristicCallbacks->bleSerial = this; 97 | pRxCharacteristic->setCallbacks(bleSerialCharacteristicCallbacks); 98 | 99 | // Start the service 100 | pService->start(); 101 | Serial.println("starting service"); 102 | 103 | // Start advertising 104 | pServer->getAdvertising()->addServiceUUID(pService->getUUID()); 105 | pServer->getAdvertising()->start(); 106 | Serial.println("Waiting a client connection to notify..."); 107 | return true; 108 | } 109 | 110 | int BLESerial::available(void) 111 | { 112 | // reply with data available 113 | return receiveBuffer.length(); 114 | } 115 | 116 | int BLESerial::peek(void) 117 | { 118 | // return first character available 119 | // but don't remove it from the buffer 120 | if ((receiveBuffer.length() > 0)){ 121 | uint8_t c = receiveBuffer[0]; 122 | return c; 123 | } 124 | else 125 | return -1; 126 | } 127 | 128 | bool BLESerial::connected(void) 129 | { 130 | // true if connected 131 | if (pServer->getConnectedCount() > 0) 132 | return true; 133 | else 134 | return false; 135 | } 136 | 137 | int BLESerial::read(void) 138 | { 139 | // read a character 140 | if ((receiveBuffer.length() > 0)){ 141 | uint8_t c = receiveBuffer[0]; 142 | receiveBuffer.erase(0,1); // remove it from the buffer 143 | return c; 144 | } 145 | else 146 | return -1; 147 | } 148 | 149 | size_t BLESerial::write(uint8_t c) 150 | { 151 | // write a character 152 | uint8_t _c = c; 153 | pTxCharacteristic->setValue(&_c, 1); 154 | pTxCharacteristic->notify(); 155 | delay(10); // bluetooth stack will go into congestion, if too many packets are sent 156 | return 1; 157 | } 158 | 159 | size_t BLESerial::write(const uint8_t *buffer, size_t size) 160 | { 161 | // write a buffer 162 | for(int i=0; i < size; i++){ 163 | write(buffer[i]); 164 | } 165 | return size; 166 | } 167 | 168 | void BLESerial::flush() 169 | { 170 | // remove buffered data 171 | receiveBuffer.clear(); 172 | } 173 | 174 | void BLESerial::end() 175 | { 176 | // close connection 177 | } 178 | 179 | --------------------------------------------------------------------------------