Exercise of BLE Communication between Nano RP2040 Connect (Peripheral) and ESP32 (Central), in Arduino framework.
nanoRP2040_BLE_Peripheral_20210623a.ino run on Arduino Nano RP2040 Connect, act as BLE Peripheral (server), wait to be connected.
/*
* Arduino nano RP2040 Connect exercise:
* as BLE Peripheral
*
* reference:
* ArduinoBLE library-
* https://www.arduino.cc/en/Reference/ArduinoBLE
*
* In my implementation:
* BLEByteCharacteristic written event checked by polling.
* BLEStringCharacteristic/BLEIntCharacteristic using event haandler.
*
*/
#include <ArduinoBLE.h>
/* Visit Online GUID / UUID Generator
* (https://www.guidgenerator.com/)
* to generate your uuid
*/
const char* serviceUUID = "20a07a95-8c12-484c-94fa-b828c4465a3c";
const char* byteCharUUID = "d34dda3b-7b4a-4ce3-9666-a8338db4e604";
const char* stringCharUUID = "41281b9c-8dc4-4649-8cbe-c39fa01513e2";
const char* intCharUUID = "c7d27dc6-f4d8-4523-b060-3e2e4c187808";
const char* myLocalName = "MyBLE";
BLEService myBLEService(serviceUUID);
BLEByteCharacteristic myBLEByteCharacteristic(byteCharUUID,
BLERead|BLEWrite);
BLEStringCharacteristic myBLEStringCharacteristic(stringCharUUID,
BLERead|BLEWrite|BLENotify, 24); //max length = 10
BLEIntCharacteristic myBLEIntCharacteristic(intCharUUID,
BLERead|BLEWrite);
void setup() {
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, LOW);
Serial.begin(115200);
delay(100);
digitalWrite(LED_BUILTIN, HIGH);
//Started, connect Serial to begin
while(!Serial);
Serial.println("\n---Start ---");
digitalWrite(LED_BUILTIN, LOW);
Serial.println("Initialize BLE...");
if(!BLE.begin()){
Serial.println("Starting BLE failed!");
while(1);
}
Serial.println("BLE initialized.");
Serial.print("MAC: ");
Serial.println(BLE.address());
Serial.println("Service UUIID: \t\t\t" + String(serviceUUID));
Serial.println("Byte Characteristic UUIID: \t" + String(byteCharUUID));
Serial.println("String Characteristic UUIID: \t" + String(stringCharUUID));
Serial.println("Int Characteristic UUIID: \t" + String(intCharUUID));
Serial.println();
BLE.setLocalName(myLocalName);
BLE.setAdvertisedService(myBLEService);
myBLEService.addCharacteristic(myBLEByteCharacteristic);
myBLEService.addCharacteristic(myBLEStringCharacteristic);
myBLEService.addCharacteristic(myBLEIntCharacteristic);
BLE.addService(myBLEService);
myBLEStringCharacteristic.setEventHandler(BLEWritten, myBLEString_Written_Hndl);
myBLEIntCharacteristic.setEventHandler(BLEWritten, myBLEInt_Written_Hndl);
BLE.advertise();
}
void loop() {
BLEDevice central = BLE.central();
if(central){
digitalWrite(LED_BUILTIN, HIGH);
Serial.print("Connected: ");
Serial.println(central.address());
while(central.connected()){
if(myBLEByteCharacteristic.written()){
byte valByte = myBLEByteCharacteristic.value();
Serial.print("myBLEByteCharacteristic received: ");
Serial.println(valByte, HEX);
}
}
digitalWrite(LED_BUILTIN, LOW);
Serial.println("Disconnected.");
}
}
// Event Handler for myBLEStringCharacteristic Written
// Print received Sring, and write back in upper case.
void myBLEString_Written_Hndl(BLEDevice central, BLECharacteristic characteristic) {
Serial.print("BLEStringCharacteristic event, written: ");
Serial.println("myBLEStringCharacteristic received: len=" +
String(myBLEStringCharacteristic.valueLength()));
String valString = myBLEStringCharacteristic.value();
Serial.println(valString);
valString.toUpperCase();
Serial.println(valString);
myBLEStringCharacteristic.setValue(valString);
}
// Event Handler for myBLEIntCharacteristic Written
void myBLEInt_Written_Hndl(BLEDevice central, BLECharacteristic characteristic) {
Serial.print("BLEIntCharacteristic event, written: ");
int valInt = myBLEIntCharacteristic.value();
Serial.println(valInt);
}
ESP32_BLE_Central_20210623a.ino run on ESP32 Dev. Board, act as Central (client), scan and connect to Peripheral, and send something.
/*
* ESP32 BLE exercise, as Central (Client)
* connect to nanoRP2040 BLE Peripheral
*
*/
#include "BLEDevice.h"
const String targetName = "MyBLE";
// The remote service/characteristic we wish to connect to.
// UUID(s) have to match with Peripheral side.
const char* serviceUUID = "20a07a95-8c12-484c-94fa-b828c4465a3c";
const char* byteCharUUID = "d34dda3b-7b4a-4ce3-9666-a8338db4e604";
const char* stringCharUUID = "41281b9c-8dc4-4649-8cbe-c39fa01513e2";
const char* intCharUUID = "c7d27dc6-f4d8-4523-b060-3e2e4c187808";
static BLEUUID BLEUUID_service(serviceUUID);
static BLEUUID BLEUUID_byteChar(byteCharUUID);
static BLEUUID BLEUUID_stringChar(stringCharUUID);
static BLEUUID BLEUUID_intChar(intCharUUID);
static BLERemoteCharacteristic* pRemoteChar_byte;
static BLERemoteCharacteristic* pRemoteChar_string;
static BLERemoteCharacteristic* pRemoteChar_int;
static boolean doConnect = false;
static boolean connected = false;
static boolean doScan = false;
static BLEAdvertisedDevice* myDevice;
int notifyDur;
static void notifyCallback(
BLERemoteCharacteristic* pBLERemoteCharacteristic,
uint8_t* pData,
size_t length,
bool isNotify) {
Serial.println("pRemoteChar_string notify callback -");
Serial.println(pBLERemoteCharacteristic->getUUID().toString().c_str());
Serial.print(" of data length ");
Serial.println(length);
Serial.print("data: ");
Serial.println((char*)pData);
}
class MyClientCallback : public BLEClientCallbacks {
void onConnect(BLEClient* pclient) {
}
void onDisconnect(BLEClient* pclient) {
connected = false;
Serial.println("onDisconnect");
}
};
bool connectToServer() {
Serial.print("Forming a connection to ");
Serial.println(myDevice->getAddress().toString().c_str());
BLEClient* pClient = BLEDevice::createClient();
Serial.println(" - Created client");
pClient->setClientCallbacks(new MyClientCallback());
// Connect to the remove BLE Server.
pClient->connect(myDevice);
Serial.println(" - Connected to server");
// Obtain a reference to the service we are after in the remote BLE server.
BLERemoteService* pRemoteService = pClient->getService(BLEUUID_service);
if (pRemoteService == nullptr) {
Serial.print("Failed to find our service UUID: ");
Serial.println(BLEUUID_service.toString().c_str());
pClient->disconnect();
return false;
}
Serial.println(" - Found our service");
// Obtain a reference to the characteristic in the service of the remote BLE server.
pRemoteChar_byte = pRemoteService->getCharacteristic(BLEUUID_byteChar);
pRemoteChar_string = pRemoteService->getCharacteristic(BLEUUID_stringChar);
pRemoteChar_int = pRemoteService->getCharacteristic(BLEUUID_intChar);
//assume all characteristics found, skip checking
/*
if (pRemoteChar_string == nullptr) {
Serial.print("Failed to find our characteristic UUID: ");
Serial.println(BLEUUID_stringChar.toString().c_str());
pClient->disconnect();
return false;
}
*/
Serial.println(" - Found our characteristic");
// Read the value of the characteristic.
if(pRemoteChar_string->canRead()) {
std::string value = pRemoteChar_string->readValue();
Serial.print("The characteristic value was: ");
Serial.println(value.c_str());
}
if(pRemoteChar_string->canNotify()){
Serial.println("pRemoteChar_string CAN Notify");
pRemoteChar_string->registerForNotify(notifyCallback);
}else{
Serial.println("pRemoteChar_string CANNOT Notify");
}
connected = true;
return true;
}
/**
* Scan for BLE servers and find the first one matched advertises service
*/
class MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks {
/**
* Called for each advertising BLE server.
*/
void onResult(BLEAdvertisedDevice advertisedDevice) {
//Serial.print("BLE Advertised Device found: ");
//Serial.println(advertisedDevice.toString().c_str());
String devName = advertisedDevice.getName().c_str();
//Serial.println(devName);
if(devName == targetName){
Serial.println("Target found-");
// We have found a device,
// let us now see if it contains the service we are looking for.
Serial.println(advertisedDevice.getServiceUUID().toString().c_str());
if (advertisedDevice.haveServiceUUID() &&
advertisedDevice.isAdvertisingService(BLEUUID_service)) {
Serial.println("BLEUUID_service match -");
BLEDevice::getScan()->stop();
myDevice = new BLEAdvertisedDevice(advertisedDevice);
doConnect = true;
doScan = true;
} // Found our server
}
} // onResult
}; // MyAdvertisedDeviceCallbacks
void setup() {
Serial.begin(115200);
delay(1000);
Serial.println("\n--- ESP32 Start ---");
BLEDevice::init("");
// Retrieve a Scanner and set the callback we want to use to be informed when we
// have detected a new device. Specify that we want active scanning and start the
// scan to run for 5 seconds.
BLEScan* pBLEScan = BLEDevice::getScan();
pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());
pBLEScan->setInterval(1349);
pBLEScan->setWindow(449);
pBLEScan->setActiveScan(true);
pBLEScan->start(5, false);
}
// This is the Arduino main loop function.
void loop() {
// If the flag "doConnect" is true then we have scanned for and found the desired
// BLE Server with which we wish to connect. Now we connect to it. Once we are
// connected we set the connected flag to be true.
if (doConnect == true) {
if (connectToServer()) {
Serial.println("We are now connected to the BLE Server.");
} else {
Serial.println("We have failed to connect to the server; there is nothin more we will do.");
}
doConnect = false;
}
// If we are connected to a peer BLE Server, update the characteristic each time we are reached
// with the current time since boot.
if (connected) {
notifyDur = millis();
String newValue = "time since boot: " + String(notifyDur/1000);
// Set the characteristic's value to be the array of bytes that is actually a string.
pRemoteChar_string->writeValue(newValue.c_str(), newValue.length());
pRemoteChar_int->writeValue(notifyDur, true);
}else if(doScan){
BLEDevice::getScan()->start(0);
}
delay(1000); // Delay a second between loops.
} // End of loop
~ More exercise of Arduino Nano RP2040 Connect.
No comments:
Post a Comment