ESP32 Bluetooth LE (BLE) reconnect client when server appears

lykkedk
Posts: 3
Joined: Tue Dec 29, 2020 10:55 am

ESP32 Bluetooth LE (BLE) reconnect client when server appears

Postby lykkedk » Tue Dec 29, 2020 11:23 am

Hi here...

This is my first post on this board, so i'am a newbee :)

Story ::
I have created an ESP32 remote-controller which used to send BLE data to an RaspberryPi with enabled BLE. -Working okay within 1-2 meters range.

The Remote-controller is the server part in the chain.
Problem 1. ::
The RaspberryPi sits in my main stereo inside a chassis (picture shows my testrig, not my main stereo) and it keep's loosing connection when remote goes + 1-2meters away or so.
Solution for problem 1. ::
I have another ESP32 connected to my RaspberryPi. With this setup it's working much better and the range is around 10 meters now.
This ESP32 is a Client in my setup.

Problem is NOW ::
When Serverpart (remote-controller) is loosing connection or awakes after sleeping, the Client cannot connect before it's reset or rebooted or like.
I'am sure that it should be possible for the client to autoreconnect when loosing connection, but i can't figure out howto do that.
The server is working as expected and no reboot/reset is neccesary here.

Server (remote-controller) code ::

Code: Select all

// 
// SuperPlayer Bluetooth (BLE) Controller 
// Build from different sources (www)
// Jesper Lykke [User :: Lykkedk @ diyaudio.com]
//
// Lib's needed :: (Installed from Arduino IDE)
//
// https://github.com/mickey9801/ButtonFever
// https://github.com/madhephaestus/ESP32Encoder/
//

// - Sleep stuff -

unsigned long startMillis;
unsigned long currentMillis;

// period ::
//1 Hour  3,600,000 ms
//2 Hours 7,200,000 ms
//3 Hours 10,800,000 ms
//4 Hours 14,400,000 ms
const unsigned long period = 3600000;  //the value is a number of milliseconds
//const unsigned long period = 20000;  //the value is a number of milliseconds

unsigned long BLE_startMillis;
unsigned long BLE_currentMillis;
const unsigned long BLE_period = 3000;  //Adjust a bit to fit the wakeup/vs. when first BLE send is fired

// - Encoder stuff -
#include <ESP32Encoder.h>
#include <BfButton.h>

// - BLE stuff -

#include <BLEDevice.h>
#include <BLEServer.h>
#include <BLEUtils.h>
#include <BLE2902.h>

// - Battery level -

//#define VBATPIN A13
#define VBATPIN 35
float SaveBle = 0;

// - Sleep stuff -

#define BUTTON_PIN_BITMASK 0x200000000 // 2^33 in hex
RTC_DATA_ATTR int bootCount = 0;

// - Encoder -

const unsigned int btnPin = 25;
BfButton btn(BfButton::STANDALONE_DIGITAL, btnPin, false, HIGH); // I added a pull-down myself
ESP32Encoder encoder;

// Encoder values for Volume control
int32_t Volume = 0;
int32_t OLD_Volume = 0;
uint32_t BLE_encoder = 0;
uint32_t OLD_BLE_encoder = 0;

// - BLE stuff -

BLEServer* pServer = NULL;
BLECharacteristic* pCharacteristic = NULL;
bool deviceConnected = false;
bool oldDeviceConnected = false;

#define SERVICE_UUID        "4fafc201-1fb5-459e-8fcc-c5c9c331914b"
#define CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a8"

class MyServerCallbacks: public BLEServerCallbacks {
    void onConnect(BLEServer* pServer) {
      deviceConnected = true;
    };

    void onDisconnect(BLEServer* pServer) {
      deviceConnected = false;
    }
};

// - Handle Sleep -

void print_wakeup_reason(){
  esp_sleep_wakeup_cause_t wakeup_reason;

  wakeup_reason = esp_sleep_get_wakeup_cause();

  switch(wakeup_reason)
  {
    case ESP_SLEEP_WAKEUP_EXT0 : Serial.println("Wakeup caused by external signal using RTC_IO"); break;
    case ESP_SLEEP_WAKEUP_EXT1 : Serial.println("Wakeup caused by external signal using RTC_CNTL"); break;
    case ESP_SLEEP_WAKEUP_TIMER : Serial.println("Wakeup caused by timer"); break;
    case ESP_SLEEP_WAKEUP_TOUCHPAD : Serial.println("Wakeup caused by touchpad"); break;
    case ESP_SLEEP_WAKEUP_ULP : Serial.println("Wakeup caused by ULP program"); break;
    default : Serial.printf("Wakeup was not caused by deep sleep: %d\n",wakeup_reason); break;
  }
}

// - Handle BLE -

void Ble() { // Start void BLE

    // Only fire BLE stuff, after a short time when awake from deep sleep
    // BLE_period is that time configured first in this code 
    BLE_currentMillis = millis();
    if (BLE_currentMillis - BLE_startMillis >= BLE_period) { // Start BLE first fire 
           
    if (BLE_encoder!=OLD_BLE_encoder) {

    Serial.print("BLE_encoder value : ");
    Serial.println(BLE_encoder);

    startMillis = millis(); // Reset initial gotosleep start time
        
    if (deviceConnected) {     
    pCharacteristic->setValue(BLE_encoder);
            
    pCharacteristic->notify();
    delay(500); // Critical time... to short will send to many packet's, too long will make it seem slow
    }

    OLD_BLE_encoder = BLE_encoder;
    }
    
    // disconnecting
    if (!deviceConnected && oldDeviceConnected) {
        delay(500); // give the bluetooth stack the chance to get things ready
        pServer->startAdvertising(); // restart advertising
        Serial.println("start advertising");
        Serial.println("DisConnecting");
        oldDeviceConnected = deviceConnected;
     }
    // connecting
    if (deviceConnected && !oldDeviceConnected) {
        Serial.println("Connecting");
        // do stuff here on connecting
        oldDeviceConnected = deviceConnected;
    }
    } // End BLE first fire
} // End void BLE

// - Handle Encoder Button -

void pressHandler (BfButton *btn, BfButton::press_pattern_t pattern) {
  Serial.print(btn->getID());
  switch (pattern) {
    case BfButton::SINGLE_PRESS:           // Does not work very well!
      Serial.println(" pressed.");
      BLE_encoder = 75000;                 // Not used
      break;
    case BfButton::DOUBLE_PRESS:           // Works fine
      Serial.println(" double pressed.");  // Mute/unmute
      BLE_encoder = 50000;
      break;
    case BfButton::LONG_PRESS:             // Works fine
      Serial.println(" long pressed.");
      BLE_encoder = 25000;                 // Play/pause/battery level
      delay(50);
      ReadPower();                         // Read battery voltage & save the volume value
      Ble();                               // Send the value
      delay(50);
      LoadBle();                           // Restore volume value
      break;
  }
}

// - Handle Encoder data -

void ReadEncoder () {
  // Loop and read the count
  Volume = encoder.getCount();
  if (Volume!=OLD_Volume) {
    OLD_Volume = Volume;   
  }
  BLE_encoder = Volume;
  }

void ReadPower () { 
  float measuredvbat = analogRead(VBATPIN);

  measuredvbat = measuredvbat/4095;
  measuredvbat = measuredvbat*2*3.3*1.1;
  measuredvbat = measuredvbat*1000;
  
  Serial.print("DC Voltage :: "); Serial.println(measuredvbat);
  SaveBle = BLE_encoder;
  BLE_encoder = measuredvbat;
  }

void LoadBle () {
  BLE_encoder = SaveBle;
  }

// - SETUP -

void setup(){
	
	Serial.begin(115200);

  startMillis = millis();       // Initial gotosleep start time
  BLE_startMillis = millis();   // First BLE fire start counter
  
  //Increment boot number and print it every reboot - Sleep
  ++bootCount;
  Serial.println("Boot number: " + String(bootCount));

  esp_sleep_enable_ext0_wakeup(GPIO_NUM_25,0); // 1 = High, 0 = Low - Wakeup when encoder is clicked (Long pressed)

// - BLE stuff -

    // Create the BLE Device
    BLEDevice::init("SPR");    // SuperPlayer Remote (Server part of chain)

// - TX Power -
    esp_ble_tx_power_set(ESP_BLE_PWR_TYPE_ADV, ESP_PWR_LVL_P9);  // ESP_PWR_LVL_N12       = 0 Corresponding to -12dbm 
                                                                 // ESP_PWR_LVL_N9        = 1 Corresponding to -9dbm
                                                                 // ESP_PWR_LVL_N6        = 2 Corresponding to -6dbm 
                                                                 // ESP_PWR_LVL_N3        = 3 Corresponding to -3dbm 
                                                                 // ESP_PWR_LVL_N0        = 4 Corresponding to 0dbm
                                                                 // ESP_PWR_LVL_P3        = 5 Corresponding to +3dbm <--- Default
                                                                 // ESP_PWR_LVL_P6        = 6 Corresponding to +6dbm 
                                                                 // ESP_PWR_LVL_P9        = 7 Corresponding to +9dbm 

    // Create the BLE Server
    pServer = BLEDevice::createServer();
    pServer->setCallbacks(new MyServerCallbacks());

    // Create the BLE Service
    BLEService *pService = pServer->createService(SERVICE_UUID);

    // Create a BLE Characteristic
    pCharacteristic = pService->createCharacteristic(
                      CHARACTERISTIC_UUID,
                      BLECharacteristic::PROPERTY_READ   |
                      BLECharacteristic::PROPERTY_WRITE  |
                      BLECharacteristic::PROPERTY_NOTIFY |
                      BLECharacteristic::PROPERTY_INDICATE
                    );

    // https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.descriptor.gatt.client_characteristic_configuration.xml
    // Create a BLE Descriptor
    pCharacteristic->addDescriptor(new BLE2902());

    // Start the service
    pService->start();

    // Start advertising
    BLEAdvertising *pAdvertising = BLEDevice::getAdvertising();
    pAdvertising->addServiceUUID(SERVICE_UUID);
    pAdvertising->setScanResponse(false);
    //pAdvertising->setScanResponse(true);
    pAdvertising->setMinPreferred(0x0);  // set value to 0x00 to not advertise this parameter
    BLEDevice::startAdvertising();
    Serial.println("Waiting a client connection to notify...");

// - Button stuff -
	
	btn.onPress(pressHandler)
     .onDoublePress(pressHandler)      // default timeout
     .onPressFor(pressHandler, 1000);  // custom timeout for 1 second

// - Encoder stuff -
  
	// Enable the weak pull down resistors
	//ESP32Encoder::useInternalWeakPullResistors=DOWN;
	// Enable the weak pull up resistors
	ESP32Encoder::useInternalWeakPullResistors=UP;
  //CLK (A pin) - to any microcontroler intput pin with interrupt -> in this example pin 32
  //DT (B pin) - to any microcontroler intput pin with interrupt -> in this example pin 21
  //SW (button pin) - to any microcontroler intput pin -> in this example pin 25
  //VCC - to microcontroler VCC (then set ROTARY_ENCODER_VCC_PIN -1) or in this example pin 25
  //GND - to microcontroler GND
	encoder.attachHalfQuad(32, 21);		
	// set starting count value after attaching
	encoder.setCount(100000);
  //encoder.setCount(250);
}

// - Loop section -

void loop(){

  ReadEncoder();
  btn.read();
  Ble();

  currentMillis = millis();                      // Grab the current time
  if (currentMillis - startMillis >= period) {   // Check if period before gotosleep is gone (period = time before we gotosleep)
  Serial.println("Going to sleep now ZZzzz...");
  esp_deep_sleep_start();
  
  }
  
}
Client code :: (The one which cannot reconnect to the server by itself)

Code: Select all

#include <cstdlib>
#include <string>
#include "BLEDevice.h"

int32_t Volume = 100000;                                            // Variable to store Volume from SuperPlayer Remote 
                                                                    // (100000 = Where encoder on SuperPlayer Remote starts)
int32_t OLD_Volume = 100010;                                        // Variable to store Volume value to compare

static BLEUUID serviceUUID("4fafc201-1fb5-459e-8fcc-c5c9c331914b"); // The remote service of SuperPlayer Remote [Server part]
static BLEUUID    charUUID("beb5483e-36e1-4688-b7f5-ea07361b26a8"); // The characteristic of SuperPlayer Remote [Server part]

static BLEAddress *pServerAddress;
static boolean doConnect = false;
static boolean connected = false;

static BLERemoteCharacteristic* pRemoteCharacteristic;

// this gets called when we receive a message
// Note that the server has to call notify to trigger this
// This function just prints the received message
static void notifyCallback(
  BLERemoteCharacteristic* pBLERemoteCharacteristic,
  uint8_t* pData,
  size_t length,
  bool isNotify)
{
  
  Volume = (*(uint32_t *)pData);                                     // BLE Volume read from SuperPlayer_Remote via Bluetooth LE (BLE)
  
}

bool connectToServer(BLEAddress pAddress)
{
  Serial.print("Creating connection to ");
  Serial.println(pAddress.toString().c_str());

  BLEClient*  pClient = BLEDevice::createClient();
  Serial.println(" - Created client");

  // Connect to the remove BLE Server.
  pClient->connect(pAddress);
  Serial.println(" - Connected to server");

  // Obtain a reference to the service we are after in the remote BLE server.
  BLERemoteService* pRemoteService = pClient->getService(serviceUUID);
  if (pRemoteService == nullptr) {
    Serial.print("Failed to find our service UUID: ");
    Serial.println(serviceUUID.toString().c_str());
    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);
  if (pRemoteCharacteristic == nullptr) {
    Serial.print("Failed to find our characteristic UUID: ");
    Serial.println(charUUID.toString().c_str());
    return false;
  }
  Serial.println(" - Found our characteristic");

  // Bind the notifyCallback method to the characteristic
  pRemoteCharacteristic->registerForNotify(notifyCallback);
}

/**
 * Scan for BLE servers and find the first one that advertises the service we are looking for.
 */
class MyAdvertisedDeviceCallbacks : public BLEAdvertisedDeviceCallbacks {
  /**
    * Called for each advertising BLE server.
    */
  void onResult(BLEAdvertisedDevice advertisedDevice) {
    
    // We have found a device, let us now see if it contains the service we are looking for.
    if (advertisedDevice.haveServiceUUID() && advertisedDevice.getServiceUUID().equals(serviceUUID)) {

      Serial.println(advertisedDevice.toString().c_str());
      Serial.print("Found our device! :: ");
      advertisedDevice.getScan()->stop();

      pServerAddress = new BLEAddress(advertisedDevice.getAddress());
      doConnect = true;

    } // Found our server
  } // onResult
}; // MyAdvertisedDeviceCallbacks

void send_volume() {
  if (Volume!=OLD_Volume) {
    //Serial.print("Sending volume on serial ---> ");
    Serial.println(Volume);
    }
  OLD_Volume = Volume;
}

void setup() {
  Serial.begin(115200);
  Serial.println("SETUP init ...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 30 seconds.
  BLEScan* pBLEScan = BLEDevice::getScan();
  pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());
  pBLEScan->setActiveScan(true);
  pBLEScan->start(5);

} // 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) {
    Serial.println("DEBUG 1");
    if (connectToServer(*pServerAddress)) {
      Serial.println("We are now connected to SuperPlayer Remote...");
      connected = true;
      }
    else {
      Serial.println("We have failed to connect to the server; there is nothing more we will do.");
    }
    doConnect = false;
  }

  send_volume();
  delay(250);

}
Really hope someone can help me further from here...
Rgds; Jesper.
Attachments
IMG_7775.jpg
IMG_7775.jpg (945.71 KiB) Viewed 8918 times
IMG_7744.jpg
IMG_7744.jpg (534.73 KiB) Viewed 8918 times
IMG_7742.jpg
IMG_7742.jpg (730.86 KiB) Viewed 8918 times

chegewara
Posts: 2364
Joined: Wed Jun 14, 2017 9:00 pm

Re: ESP32 Bluetooth LE (BLE) reconnect client when server appears

Postby chegewara » Tue Dec 29, 2020 11:46 am

Your client app is performing scan for only 5 sec, then it never try to scan again. You can use pBLEScan->start(0) (forever), and add BLEClentCallbacks and with the same line (pBLEScan->start(0)) in onDisconnect().

lykkedk
Posts: 3
Joined: Tue Dec 29, 2020 10:55 am

Re: ESP32 Bluetooth LE (BLE) reconnect client when server appears

Postby lykkedk » Tue Dec 29, 2020 12:33 pm

Hey hey hey :D

Very good, thing is working now...
I will get back and paste the final code, when i have it cleaned up some.

Thanks man!


Showing the Client reconnecting after Server rebooted or lost connection ::

Code: Select all

99991
99990
99983
99980
99973
99974
onDisconnect
BLE Advertised Device found: Name: SPR, Address: fc:f5:c4:06:bb:c6, serviceUUID: 4fafc201-1fb5-459e-8fcc-c5c9c331914b, txPower: 9
Forming a connection to fc:f5:c4:06:bb:c6
 - Created client
 - Connected to server
 - Found our service
 - Found our characteristic
The characteristic value was: 
We are now connected to the BLE Server.
99999
99998

lykkedk
Posts: 3
Joined: Tue Dec 29, 2020 10:55 am

Re: ESP32 Bluetooth LE (BLE) reconnect client when server appears

Postby lykkedk » Wed Dec 30, 2020 9:08 am

chegewara wrote:
Tue Dec 29, 2020 11:46 am
Your client app is performing scan for only 5 sec, then it never try to scan again. You can use pBLEScan->start(0) (forever), and add BLEClentCallbacks and with the same line (pBLEScan->start(0)) in onDisconnect().
Hi again...

I thought that i did solve the problems, everything is working, except when i go away with the remote and it looses connection.
Then the code stops where i marked it (!GETS STUCK HERE!) near the end of the code (Client code pasted here)
I don't know why the Client don't reconnect here? - If i reset or unplug the battery on the remote, Client reconnect fine, only case is when it looses connection when remote comes +10 meters away or so?

I'am stuck here i guess :)

[Codebox]//
// SuperPlayer Bluetooth (BLE) Controller
// Build from different sources (www)
// Jesper Lykke [User :: Lykkedk @ diyaudio.com]
//
// Lib's needed :: (Installed from Arduino IDE)
//
// https://github.com/mickey9801/ButtonFever
// https://github.com/madhephaestus/ESP32Encoder/
//

#include <cstdlib>
#include <string>
#include "BLEDevice.h"
//#include "BLEScan.h"

int32_t Volume = 100000; // Variable to store Volume from SuperPlayer Remote
// (100000 = Where encoder on SuperPlayer Remote starts)
int32_t OLD_Volume = 100000; // Variable to store Volume value to compare

static BLEUUID serviceUUID("4fafc201-1fb5-459e-8fcc-c5c9c331914b"); // The remote service of SuperPlayer Remote [Server part]
static BLEUUID charUUID("beb5483e-36e1-4688-b7f5-ea07361b26a8"); // The characteristic of SuperPlayer Remote [Server part]

static boolean doConnect = false;
static boolean connected = false;
static boolean doScan = false;
static BLERemoteCharacteristic* pRemoteCharacteristic;
static BLEAdvertisedDevice* myDevice;

static void notifyCallback(
BLERemoteCharacteristic* pBLERemoteCharacteristic,
uint8_t* pData,
size_t length,
bool isNotify) {
//Serial.print("Notify callback for characteristic ");
//Serial.print(pBLERemoteCharacteristic->getUUID().toString().c_str());
//Serial.print(" of data length ");
//Serial.println(length);
//Serial.print("data: ");
//Serial.println((char*)pData);
Volume = (*(int32_t *)pData); // BLE Volume read from SuperPlayer_Remote via Bluetooth LE (BLE)
}

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);
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);
if (pRemoteCharacteristic == nullptr) {
//Serial.print("Failed to find our characteristic UUID: ");
//Serial.println(charUUID.toString().c_str());
pClient->disconnect();
return false;
}
//Serial.println(" - Found our characteristic");

// Read the value of the characteristic.
if(pRemoteCharacteristic->canRead()) {
std::string value = pRemoteCharacteristic->readValue();
//Serial.print("The characteristic value was: ");
//Serial.println(value.c_str());
}

if(pRemoteCharacteristic->canNotify())
pRemoteCharacteristic->registerForNotify(notifyCallback);

connected = true;
return true;
Serial.println("230000");
}
/**
* Scan for BLE servers and find the first one that advertises the service we are looking for.
*/
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());

// We have found a device, let us now see if it contains the service we are looking for.
if (advertisedDevice.haveServiceUUID() && advertisedDevice.isAdvertisingService(serviceUUID)) {

BLEDevice::getScan()->stop();
myDevice = new BLEAdvertisedDevice(advertisedDevice);
doConnect = true;
doScan = true;

} // Found our server
} // onResult
}; // MyAdvertisedDeviceCallbacks

void send_volume() {
if (Volume!=OLD_Volume) {
//Serial.print("Sending volume on serial ---> ");
Serial.println(Volume); // Sending volume on serial ---> To Raspberry Pi SuperPlayer
}
OLD_Volume = Volume;
}

void setup() {
Serial.begin(115200);
//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();
pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());
pBLEScan->setInterval(1349);
pBLEScan->setWindow(449);
pBLEScan->setActiveScan(true);
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) {
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) {
send_volume();
delay(50);
//String newValue = "Time since boot: " + String(millis()/1000);
//Serial.println("Setting new characteristic value to \"" + newValue + "\"");
//Serial.println("Connected ---> Do nothing");
// Set the characteristic's value to be the array of bytes that is actually a string.
//pRemoteCharacteristic->writeValue(newValue.c_str(), newValue.length());
}else if(doScan){
BLEDevice::getScan()->start(0); // this is just example to start scan after disconnect, most likely there is better way to do it in arduino
!GETS STUCK HERE!
}

delay(50); // Delay between loops.

} // End of loop[/Codebox]

Who is online

Users browsing this forum: Baidu [Spider] and 75 guests