BLE onConnect callback working just once after pairing

jay_ar
Posts: 3
Joined: Fri Nov 08, 2019 2:31 am

BLE onConnect callback working just once after pairing

Postby jay_ar » Fri Nov 08, 2019 3:02 am

Hello all,

Sorry if this is a stupid question, but I honestly don't know where to start looking for the root of my problem or for a solution :/

I'm trying to create a little device for my son. The idea is to send an SMS when a Bluetooth device (his cellphone) is in range, without needing any software running on his phone. I'm not dealing with sending the SMS yet, but I'm having problems just firing an event when a device comes *back* in range.

After reviewing several of the examples included on the Arduino IDE esp32 add-on, there's at least one ("SampleServer", by Evandro Copercini and chegewara) that seems to do just that: when a device connects, it sends via println() a confirmation to the PC. I modified the code just slightly to turn on a LED when "connecting" and off when "disconnecting", but the code - even including the original one, works only once (when I create a new connection between cellphone and ESP32):

* With the ESP32 board is running, I go to the BT setting on my phone and connect to the ESP32 --> LED goes on
* I then turn off BT on my phone --> LED goes off
* If at this point I turn BT on again, the LED doesn't turn on again
* the only way to trigger the whole thing again is by removing, and then adding again, the pairing from my phone.

So... it looks like this means the onConnect is more of a "onPair". Is this interpretation correct, or should the onConnect work whenever the two devices are connected? Is there a different event triggered when the two devices star/stop being able to see each other?

I'm using a cheap, Amazon-bought ESP32 board with Arduino ide 1.8.10, and I'm testing using an Android-based phone.

Thanks!

Code: Select all

/*
    Based on Neil Kolban example for IDF: https://github.com/nkolban/esp32-snippets/blob/master/cpp_utils/tests/BLE%20Tests/SampleServer.cpp
    Ported to Arduino ESP32 by Evandro Copercini
    updates by chegewara
*/

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

// See the following for generating UUIDs:
// https://www.uuidgenerator.net/

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

BLEServer* pServer = NULL;
BLECharacteristic* pCharacteristic = NULL;
uint32_t value = 0;

bool deviceConnected = false;
bool oldDeviceConnected = false;
const int LED_BUILTIN = 2;

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

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


void setup() {
  Serial.begin(115200);
  Serial.println("Starting BLE work!");

  // setup pin 5 as a digital output pin
  pinMode (LED_BUILTIN, OUTPUT);

  BLEDevice::init("Long name works now");
  /*BLEServer * */ pServer = BLEDevice::createServer();
  pServer->setCallbacks(new MyServerCallbacks());
  
  BLEService *pService = pServer->createService(SERVICE_UUID);
  /*BLECharacteristic * */ pCharacteristic = pService->createCharacteristic(
                                         CHARACTERISTIC_UUID,
                                         BLECharacteristic::PROPERTY_READ |
                                         BLECharacteristic::PROPERTY_WRITE
                                       );

  pCharacteristic->setValue("Hello World says Neil");
  pService->start();
  // BLEAdvertising *pAdvertising = pServer->getAdvertising();  // this still is working for backward compatibility
  BLEAdvertising *pAdvertising = BLEDevice::getAdvertising();
  pAdvertising->addServiceUUID(SERVICE_UUID);
  pAdvertising->setScanResponse(true);
  pAdvertising->setMinPreferred(0x06);  // functions that help with iPhone connections issue
  pAdvertising->setMinPreferred(0x12);
  BLEDevice::startAdvertising();
  Serial.println("Characteristic defined! Now you can read it in your phone!");
}

void loop() {
    // notify changed value
    if (deviceConnected) {
        pCharacteristic->setValue((uint8_t*)&value, 4);
        pCharacteristic->notify();
        value++;
        delay(10); // bluetooth stack will go into congestion, if too many packets are sent, in 6 hours test i was able to go as low as 3ms
    }
    // disconnecting
    if (!deviceConnected && oldDeviceConnected) {
        delay(500); // give the bluetooth stack the chance to get things ready
        pServer->startAdvertising(); // restart advertising
        Serial.println("start advertising");
        oldDeviceConnected = deviceConnected;
        digitalWrite (LED_BUILTIN, LOW);  // turn off the LED
    }
    // connecting
    if (deviceConnected && !oldDeviceConnected) {
        // do stuff here on connecting
        oldDeviceConnected = deviceConnected;
        digitalWrite (LED_BUILTIN, HIGH);  // turn on the LED
    }
}

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

Re: BLE onConnect callback working just once after pairing

Postby chegewara » Fri Nov 08, 2019 8:46 pm

onConnect callback is fired only one time when connection is established. So, when you disconnect and connect again onConnect will be fired again.

I dont think you will be able to achieve your goal this way, but i hope you can do it.

jay_ar
Posts: 3
Joined: Fri Nov 08, 2019 2:31 am

Re: BLE onConnect callback working just once after pairing

Postby jay_ar » Sat Nov 09, 2019 3:05 am

chegewara wrote:
Fri Nov 08, 2019 8:46 pm
onConnect callback is fired only one time when connection is established. So, when you disconnect and connect again onConnect will be fired again.

I dont think you will be able to achieve your goal this way, but i hope you can do it.
Hello Chegewara.

I'm sorry I'm not familiar with the terminology used for BLE. Does "connect" in your 1st sentence means "going to the BT screen on the phone and selecting the device" (what I called "pairing"), or "getting in range at any point after adding it on the BT screen"?

From what I have seen you are right... this may be hard to pull off :/

Thank you for taking the time to answer :)

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

Re: BLE onConnect callback working just once after pairing

Postby chegewara » Tue Nov 12, 2019 7:40 am

It's similar to wifi, you can find many APs and see their SSID, but you are not connected as long as you not decide to connect.
You may have auto connection enabled, but this is handled by some system app.

With ble you have to write own app, or cheat a bit. Android can re-connect already known/paired (not paired like you said) devices like HID for example (keyboard). You can cheat android if you tell him with advertising your device is hid.

jay_ar
Posts: 3
Joined: Fri Nov 08, 2019 2:31 am

Re: BLE onConnect callback working just once after pairing

Postby jay_ar » Wed Nov 13, 2019 2:19 am

Aha! Interesting :)
For the time being I just hardcoded a known MAC address (from an iTag) into the ESP32 scan example, and I got to trigger a simple function when the tag is nearby. If my son decides he wants something more complex I'll try to fool the phone into providing some kind of reply to an action initiated by the ESP32. We'll see.

Thanks!

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

Re: BLE onConnect callback working just once after pairing

Postby chegewara » Thu Nov 14, 2019 12:17 pm

With iTag is different situation. You can scan for iTag and dont need to connect it, when you discover that iTag you can check RSSI and more or less count or assume how far it is. Assuming that BLE can be discovered in range up to 100 m without obstacles, you may build simple device that will inform you when kid is back home even without making calculations how far he is.

Who is online

Users browsing this forum: No registered users and 15 guests