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.