-
Notifications
You must be signed in to change notification settings - Fork 508
Open
Labels
enhancementNew feature or requestNew feature or request
Description
The only LEPeripheral example in the library is marked as
// LE Peripheral Example - not working yet
Can you add a Nordic Uart example Peripheral example
Here is the corresponding ESP32 code
#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEServer.h>
#include <BLE2902.h>
// =========== pfodBLESerial definitions
const char* localName = "ESP32 BLE"; // <<<<<< change this string to customize the adverised name of your board
class pfodBLESerial : public Stream, public BLEServerCallbacks, public BLECharacteristicCallbacks {
public:
pfodBLESerial();
void begin();
void poll();
size_t write(uint8_t);
size_t write(const uint8_t*, size_t);
int read();
int available();
void flush();
int peek();
void close();
bool isConnected();
static void addReceiveBytes(const uint8_t* bytes, size_t len);
const static uint8_t pfodEOF[1];
const static char* pfodCloseConnection;
volatile static bool connected;
void onConnect(BLEServer* serverPtr);
void onDisconnect(BLEServer* serverPtr);
void onWrite(BLECharacteristic* pCharacteristic);
private:
static const int BLE_MAX_LENGTH = 20;
static const int BLE_RX_MAX_LENGTH = 256;
static volatile size_t rxHead;
static volatile size_t rxTail;
volatile static uint8_t rxBuffer[BLE_RX_MAX_LENGTH];
size_t txIdx;
uint8_t txBuffer[BLE_MAX_LENGTH];
};
volatile size_t pfodBLESerial::rxHead = 0;
volatile size_t pfodBLESerial::rxTail = 0;
volatile uint8_t pfodBLESerial::rxBuffer[BLE_RX_MAX_LENGTH];
const uint8_t pfodBLESerial::pfodEOF[1] = { (uint8_t)-1 };
volatile bool pfodBLESerial::connected = false;
#define SERVICE_UUID "6E400001-B5A3-F393-E0A9-E50E24DCCA9E" // UART service UUID
#define CHARACTERISTIC_UUID_RX "6E400002-B5A3-F393-E0A9-E50E24DCCA9E"
#define CHARACTERISTIC_UUID_TX "6E400003-B5A3-F393-E0A9-E50E24DCCA9E"
// NOTE: the reverse characteristics do no work
BLEServer* serverPtr = NULL;
BLECharacteristic* characteristicTXPtr;
// =========== end pfodBLESerial definitions
// create a parser to handle the pfod messages
pfodBLESerial bleSerial; // create a BLE serial connection
// the setup routine runs once on reset:
void setup() {
Serial.begin(115200);
Serial.println();
// Create the BLE Device
BLEDevice::init(localName);
// Create the BLE Server
serverPtr = BLEDevice::createServer();
serverPtr->setCallbacks(&bleSerial);
// Create the BLE Service
BLEService* servicePtr = serverPtr->createService(SERVICE_UUID);
// Create a BLE Characteristic
characteristicTXPtr = servicePtr->createCharacteristic(CHARACTERISTIC_UUID_TX, BLECharacteristic::PROPERTY_NOTIFY);
characteristicTXPtr->addDescriptor(new BLE2902());
BLECharacteristic* characteristicRXPtr = servicePtr->createCharacteristic(CHARACTERISTIC_UUID_RX, BLECharacteristic::PROPERTY_WRITE);
characteristicRXPtr->setCallbacks(&bleSerial);
serverPtr->getAdvertising()->addServiceUUID(BLEUUID(SERVICE_UUID));
// Start the service
servicePtr->start();
// Start advertising
serverPtr->getAdvertising()->start();
Serial.println("BLE Server and Advertising started");
bleSerial.begin();
}
void loop() {
while (bleSerial.available()) {
Serial.println((char)bleSerial.read());
}
while (Serial.available()) {
bleSerial.write(Serial.read());
}
// <<<<<<<<<<< Your other loop() code goes here
}
// ========== pfodBLESerial methods
pfodBLESerial::pfodBLESerial() {}
bool pfodBLESerial::isConnected() {
return (connected);
}
void pfodBLESerial::begin() {}
void pfodBLESerial::close() {}
void pfodBLESerial::poll() {}
size_t pfodBLESerial::write(const uint8_t* bytes, size_t len) {
for (size_t i = 0; i < len; i++) { write(bytes[i]); }
return len; // just assume it is all written
}
size_t pfodBLESerial::write(uint8_t b) {
if (!isConnected()) { return 1; }
txBuffer[txIdx++] = b;
if ((txIdx == sizeof(txBuffer)) || (b == ((uint8_t)'\n')) || (b == ((uint8_t)'}'))) {
flush(); // send this buffer if full or end of msg or rawdata newline
}
return 1;
}
int pfodBLESerial::read() {
if (rxTail == rxHead) { return -1; }
// note increment rxHead befor writing
// so need to increment rxTail befor reading
rxTail = (rxTail + 1) % sizeof(rxBuffer);
uint8_t b = rxBuffer[rxTail];
return b;
}
// called as part of parser.parse() so will poll() each loop()
int pfodBLESerial::available() {
flush(); // send any pending data now. This happens at the top of each loop()
int rtn = ((rxHead + sizeof(rxBuffer)) - rxTail) % sizeof(rxBuffer);
return rtn;
}
void pfodBLESerial::flush() {
if (txIdx == 0) { return; }
characteristicTXPtr->setValue((uint8_t*)txBuffer, txIdx);
txIdx = 0;
characteristicTXPtr->notify();
}
int pfodBLESerial::peek() {
if (rxTail == rxHead) { return -1; }
size_t nextIdx = (rxTail + 1) % sizeof(rxBuffer);
uint8_t byte = rxBuffer[nextIdx];
return byte;
}
void pfodBLESerial::addReceiveBytes(const uint8_t* bytes, size_t len) {
// note increment rxHead befor writing
// so need to increment rxTail befor reading
for (size_t i = 0; i < len; i++) {
rxHead = (rxHead + 1) % sizeof(rxBuffer);
Serial.print((char)bytes[i]);
rxBuffer[rxHead] = bytes[i];
}
}
//=========== ESP32 BLE callback methods
void pfodBLESerial::onConnect(BLEServer* serverPtr) {
Serial.println("Connect");
connected = true;
}
void pfodBLESerial::onDisconnect(BLEServer* serverPtr) {
Serial.println("Disconnect");
connected = false;
Serial.println("Start Advert");
serverPtr->getAdvertising()->start();
}
void pfodBLESerial::onWrite(BLECharacteristic* pCharacteristic) {
String rxValue = pCharacteristic->getValue();
uint8_t* data = (uint8_t*)rxValue.c_str();
size_t len = rxValue.length();
addReceiveBytes((const uint8_t*)data, len);
}
//======================= end pfodBLESerial methods
Metadata
Metadata
Assignees
Labels
enhancementNew feature or requestNew feature or request