Hello,
I have been modifying the BLEClient example to get datas from an Arduino Nano 33 BLE Sense. To be clear:
- server = Arduino nano 33 BLE Sense
- client = Wio Terminal.
My code is working if the Serial Monitor of the Server is opend before the Client’s one. I think that I can change the scan duration if I modify the line pBLEScan->start(5, false); in the void setup. But what I would like to do is like a do while loop so that the scan is carried out until the server is detected. I guess I have to put the loop in the void setup but is there another function than the start that I could use? I have tried to put the loop in the class MyAdvertisedDeviceCallbacks, but it didn’t work (and it seems normal to me that it didn’t…)
Here is my Client code for the Wio Terminal :
/**
* A BLE client example that is rich in capabilities.
* There is a lot new capabilities implemented.
* author unknown
* updated by chegewara
*/
#include "rpcBLEDevice.h"
#include <BLEScan.h>
#include <BLEAdvertisedDevice.h>
// The remote service we wish to connect to.
//static BLEUUID serviceUUID(0xFEE0);
static BLEUUID serviceUUID(0x1101);
// The characteristic of the remote service we are interested in.
//static BLEUUID charUUID(0x2A2B);
static BLEUUID XcharUUID(0x2101);
static BLEUUID YcharUUID(0x2102);
static BLEUUID ZcharUUID(0x2103);
static BLEUUID TcharUUID(0x2104);
static BLEUUID McharUUID(0x2105);
static boolean doConnect = false;
static boolean connected = false;
static boolean doScan = false;
//static BLERemoteCharacteristic* pRemoteCharacteristic;
static BLERemoteCharacteristic* pTChar;
static BLERemoteCharacteristic* pXChar;
static BLERemoteCharacteristic* pYChar;
static BLERemoteCharacteristic* pZChar;
static BLERemoteCharacteristic* pMChar;
static BLEAdvertisedDevice* myDevice;
uint8_t bd_addr[6] = {0xD3, 0xE3, 0xAE, 0xC0, 0xB9, 0x38};
//uint8_t bd_addr[6] = {0x7d, 0x18, 0x1b, 0xf1, 0xf7, 0x2c}; // MAC address: 2c:f7:f1:1b:18:7d
BLEAddress BattServer(bd_addr);
static void temperatureNotifyCallback(
BLERemoteCharacteristic* pTChar,
uint8_t* pTData,
size_t length,
bool isNotify) {
Serial.print("Notify callback for temperature characteristic ");
Serial.print(pTChar->getUUID().toString().c_str());
Serial.print(" of data length ");
Serial.println(length);
Serial.print("data: ");
Serial.println(*(uint8_t *)pTData);
Serial.println(*pTData);
Serial.println(pTData[0]);
//Serial.println(pData);
}
static void accelerationModuleNotifyCallback(
BLERemoteCharacteristic* pMChar,
uint8_t* pMData,
size_t length,
bool isNotify) {
Serial.print("Notify callback for acceleration for module characteristic ");
Serial.print(pMChar->getUUID().toString().c_str());
Serial.print(" of data length ");
Serial.println(length);
Serial.print("data: ");
Serial.println(*(uint8_t *)pMData);
Serial.println(*pMData);
Serial.println(pMData[0]);
//Serial.println(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); // if you pass BLEAdvertisedDevice instead of address, it will be recognized type of peer device address (public or private)
Serial.println(" - Connected to server");
// Obtain a reference to the service we are after in the remote BLE server.
BLERemoteService* pRemoteService = pClient->getService(serviceUUID);
Serial.println(serviceUUID.toString().c_str());
if (pRemoteService == nullptr) {
Serial.print("Failed to find our service UUID: ");
Serial.println(serviceUUID.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.
//pRemoteCharacteristic = pRemoteService->getCharacteristic(charUUID);
pTChar = pRemoteService->getCharacteristic(TcharUUID);
pXChar = pRemoteService->getCharacteristic(XcharUUID);
pYChar = pRemoteService->getCharacteristic(YcharUUID);
pZChar = pRemoteService->getCharacteristic(ZcharUUID);
pMChar = pRemoteService->getCharacteristic(McharUUID);
if (pTChar == nullptr || pMChar == nullptr) {
Serial.print("Failed to find our characteristic UUID ");
// Serial.println(TcharUUID.toString().c_str());
// Serial.println(XcharUUID.toString().c_str());
// Serial.println(YcharUUID.toString().c_str());
// Serial.println(ZcharUUID.toString().c_str());
pClient->disconnect();
return false;
}
Serial.println(" - Found our characteristic");
// Read the temperature characteristic value
if(pTChar->canRead()) {
Serial.println(" - can read start");
std::string value = pTChar->readValue();
Serial.print("The characteristic value was: ");
Serial.println(value.c_str());
}
if(pTChar->canNotify())
pTChar->registerForNotify(temperatureNotifyCallback);
/*
// Read the X characteristic value
if(pXChar->canRead()) {
Serial.println(" - can read start");
std::string value = pXChar->readValue();
Serial.print("The characteristic value was: ");
Serial.println(value.c_str());
}
if(pXChar->canNotify())
pXChar->registerForNotify(notifyCallback);
// Read the Y characteristic value
if(pYChar->canRead()) {
Serial.println(" - can read start");
std::string value = pYChar->readValue();
Serial.print("The characteristic value was: ");
Serial.println(value.c_str());
}
if(pYChar->canNotify())
pYChar->registerForNotify(notifyCallback);
// Read the Z characteristic value
if(pZChar->canRead()) {
Serial.println(" - can read start");
std::string value = pZChar->readValue();
Serial.print("The characteristic value was: ");
Serial.println(value.c_str());
}
if(pZChar->canNotify())
pZChar->registerForNotify(notifyCallback);
*/
// Read the acceleration module characteristic value
if(pMChar->canRead()) {
Serial.println(" - can read start");
std::string value = pMChar->readValue();
Serial.print("The acceleration characteristic value was: ");
Serial.println(value.c_str());
}
if(pMChar->canNotify())
pMChar->registerForNotify(accelerationModuleNotifyCallback);
connected = true;
return true;
}
/**
* Scan for BLE servers and find the first one that advertises the service we are looking for.
* Also in BLEscan example but with a shorter onresult
*/
class MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks { // crée une classe MyAdvertisedDeviceCallbacks qui hérite de la classe BLEAdvertisedDeviceCallbacks
/**
* Called for each advertising BLE server.
*/
void onResult(BLEAdvertisedDevice advertisedDevice) {
Serial.print("BLE Advertised Device found: ");
Serial.println(advertisedDevice.toString().c_str());
// We have found a device, let us now see if it contains the service we are looking for.
//int memcmp ( const void * ptr1, const void * ptr2, size_t num );
//: Compares the first num bytes of the block of memory pointed by ptr1 to the first num bytes pointed by ptr2,
//returning zero if they all match or a value different from zero representing which is greater if they do not.
if (memcmp(advertisedDevice.getAddress().getNative(),BattServer.getNative(), 6) == 0) {
Serial.print("BATT Device found: ");
Serial.println(advertisedDevice.toString().c_str());
BLEDevice::getScan()->stop();
Serial.println("new BLEAdvertisedDevice");
myDevice = new BLEAdvertisedDevice(advertisedDevice);
Serial.println("new BLEAdvertisedDevice done");
doConnect = true;
doScan = true;
} // onResult
}
}; // MyAdvertisedDeviceCallbacks
void setup() {
Serial.begin(115200);
while(!Serial){};
delay(2000);
Serial.println("Starting Arduino BLE Client application...");
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(); // get scanner from our client device
pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks()); // behaviour of the scanner each time it find another bluetooth device
//setAdvertisedDeviceCallbacks, setInterval, setWindow, setActiveScan methods from the librairy BLEscan
pBLEScan->setInterval(1349); // period between 2 active scans
pBLEScan->setWindow(449); // active scan time range
pBLEScan->setActiveScan(true);//beginning of the scan
pBLEScan->start(5, false);
} // End of setup.
// 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) {//static boolean initialized as false
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;
}
Serial.println(".");
delay(1000);
} // End of loop
Here is the code on the Arudino Nano BLE 33 Sense (server):
/*
* Device: Arduino Nano 33 BLE Sense
* Peripheral
* The values of the integrated temperature sensor and
* accelerometer are sent using BLE.
*/
#include <ArduinoBLE.h>
#include <Arduino_LSM9DS1.h> //accelerometer sensor
#include <Arduino_HTS221.h> // temperature sensor
int const d_a=1; //number of decimal to keep for the accelerometer
int const d_t=0; //number of decimal to keep for the temperature
int const d_m=2*d_a; //number of decimal to keep for the temperature
//float values read by the sensor
float xSensor=0;
float ySensor=0;
float zSensor=0;
float mSensor=0;
float tSensor=37;
//integer variables to send via BLE
int xBLE=xSensor*pow(10,d_a);
int yBLE=ySensor*pow(10,d_a);
int zBLE=zSensor*pow(10,d_a);
int mBLE=mSensor*pow(10,d_m);
int tBLE=tSensor*pow(10,d_t);
//int t_i=t_f*100;
//int x_i=x_f*100;
//int y_i=y_f*100;
//int z_i=z_f*100;
BLEService SensorService("1101");
//BLEService SensorService("FEE0");
BLEUnsignedIntCharacteristic XChar("2101", BLERead | BLENotify);
BLEUnsignedIntCharacteristic YChar("2102", BLERead | BLENotify);
BLEUnsignedIntCharacteristic ZChar("2103", BLERead | BLENotify);
BLEUnsignedIntCharacteristic TChar("2104", BLERead | BLENotify);
BLEUnsignedIntCharacteristic MChar("2105", BLERead | BLENotify);
//BLEUnsignedIntCharacteristic TChar("2A2B", BLERead | BLENotify);
void setup() {
IMU.begin();
HTS.begin();
Serial.begin(9600);
while (!Serial);
// if (!HTS.begin()){
// Serial.println("Failed to start the HTS221 sensor.");
// while(1);
//
// if (!IMU.begin()) {
// Serial.println("Failed to start the LSM9DS sensor.");
// while (1);
pinMode(LED_BUILTIN, OUTPUT);
if (!BLE.begin()) {
Serial.println("BLE failed to Initiate");
delay(500);
while (1);
}
BLE.setLocalName("Arduino XYZT (peripheral)");
BLE.setAdvertisedService(SensorService);
SensorService.addCharacteristic(XChar);
SensorService.addCharacteristic(YChar);
SensorService.addCharacteristic(ZChar);
SensorService.addCharacteristic(MChar);
SensorService.addCharacteristic(TChar);
BLE.addService(SensorService);
XChar.writeValue(xBLE);
YChar.writeValue(yBLE);
ZChar.writeValue(zBLE);
MChar.writeValue(mBLE);
TChar.writeValue(tBLE);
BLE.advertise();
Serial.println("Arduino XYZT peripheral device is now active, waiting for connections...");
}
void loop() {
BLEDevice central = BLE.central();
if (central) {
Serial.print("Connected to central: ");
Serial.print("* Device MAC address: ");
Serial.println(central.address());
Serial.println(" ");
digitalWrite(LED_BUILTIN, HIGH);
while (central.connected()) {
//delay(200);
//read_sensor();
if (IMU.accelerationAvailable()) {
IMU.readAcceleration(xSensor, ySensor, zSensor);
}
mSensor=xSensor*xSensor+ySensor*ySensor+zSensor*zSensor;
tSensor=HTS.readTemperature();
Serial.print("xSensor ");
Serial.print(xSensor);
Serial.print(" - ySensor ");
Serial.print(ySensor);
Serial.print(" - zSensor ");
Serial.print(zSensor);
Serial.print(" - mSensor ");
Serial.print(mSensor);
Serial.print(" - tSensor ");
Serial.println(tSensor);
Serial.println("");
xBLE=xSensor*pow(10,d_a);
yBLE=ySensor*pow(10,d_a);
zBLE=zSensor*pow(10,d_a);
mBLE=zSensor*pow(10,d_m);
tBLE=tSensor*pow(10,d_t);
//int t_i=t_f*100;
//int x_i=x_f*100;
//int y_i=y_f*100;
//int z_i=z_f*100;
//writeCharacteristicValue (Tchar, Xchar, Ychar, Zchar);
Serial.print("xBLE ");
Serial.print(xBLE);
Serial.print(" - yBLE ");
Serial.print(yBLE);
Serial.print(" - zBLE ");
Serial.print(zBLE);
Serial.print(" - mBLE ");
Serial.print(mBLE);
Serial.print(" - tBLE ");
Serial.println(tBLE);
Serial.println("");
XChar.writeValue(xBLE);
YChar.writeValue(yBLE);
ZChar.writeValue(zBLE);
MChar.writeValue(mBLE);
TChar.writeValue(tBLE);
//Serial.println("At Main Function");
Serial.print("XChar ");
Serial.print(XChar.value());
Serial.print(" - YChar ");
Serial.print(YChar.value());
Serial.print(" - ZChar ");
Serial.print(ZChar);
Serial.print(" - MChar ");
Serial.print(MChar);
Serial.print(" - TChar ");
Serial.println(TChar.value());
Serial.println("");
Serial.println("");
//Serial.println("");
//Serial.println("");
delay(1000);
}
}
else {
delay(1000);
}
digitalWrite(LED_BUILTIN, LOW);
Serial.print("Disconnected from central: ");
Serial.println(central.address());
BLE.advertise();
}
//void read_sensor(){
//if (IMU.accelerationAvailable()) {
//IMU.readAcceleration(x_f, y_f, z_f);
//}
//t_f=HTS.readTemperature();
//
//Serial.print("x_f ");
//Serial.print(x_f);
//Serial.print(" - y_f ");
//Serial.print(y_f);
//Serial.print(" - z_f ");
//Serial.print(z_f);
//Serial.print(" - t_f ");
//Serial.println(t_f);
//Serial.println("");
////x_i=x_f*pow(10,d);
////y_i=y_f*pow(10,d);
////z_i=z_f*pow(10,d);
////t_i=t_f*pow(10,d);
//
//int t_i=t_f;
//int x_i=x_f;
//int y_i=y_f;
//int z_i=z_f;
//
//Serial.print("x_i ");
//Serial.print(x_i);
//Serial.print(" - y_i ");
//Serial.print(y_i);
//Serial.print(" - z_i ");
//Serial.print(z_i);
//Serial.print(" - t_i ");
//Serial.println(t_i);
//Serial.println("");
//}
I would be very grateful for any advise.
