Open luizahiginoss opened 6 years ago
@luizahiginoss https://github.com/nkolban/esp32-snippets/pull/541 should help. I made this mod and use it with PlatformIO / ESP32 quite successfully with multiple servers that have the same service and characteristic UUIDs.
I tried to use one ESP32 as the client and other 3 ESPs as servers. The client only connect with one server and receive the value from its characteristic. The other 2 continue to advertise, but their characteristics values are never showed and the connection never completed.
The client code I'm using is the one below
/**
* A BLE client example that is rich in capabilities.
*/
#include "BLEDevice.h"
//#include "BLEScan.h"
// The remote service we wish to connect to.
static BLEUUID serviceUUID("91bad492-b950-4226-aa2b-4ede9fa42f59");
// The characteristic of the remote service we are interested in.
static BLEUUID charUUID("0d563a58-196a-48ce-ace2-dfec78acc814");
static BLEAddress *pServerAddress;
static boolean doConnect = false;
static boolean connected = false;
static BLERemoteCharacteristic* pRemoteCharacteristic;
const uint8_t v[]={0x1,0x0};
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);
}
bool connectToServer(BLEAddress pAddress) {
Serial.print("Forming a 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");
// Read the value of the characteristic.
std::string value = pRemoteCharacteristic->readValue();
Serial.print("The characteristic value was: ");
Serial.println(value.c_str());
pRemoteCharacteristic->registerForNotify(notifyCallback);
pRemoteCharacteristic->getDescriptor(BLEUUID((uint16_t)0x2902))->writeValue((uint8_t*)v,2,true);
}
/**
* 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.getServiceUUID().equals(serviceUUID)) {
//
Serial.print("Found our device! address: ");
advertisedDevice.getScan()->stop();
pServerAddress = new BLEAddress(advertisedDevice.getAddress());
doConnect = true;
} // Found our server
} // onResult
}; // MyAdvertisedDeviceCallbacks
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 30 seconds.
BLEScan* pBLEScan = BLEDevice::getScan();
pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());
pBLEScan->setActiveScan(true);
pBLEScan->start(30);
} // 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(*pServerAddress)) {
Serial.println("We are now connected to the BLE Server.");
connected = true;
} 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) {
//String newValue = "Time since boot: " + String(millis()/1000);
//Serial.println("Setting new characteristic value to \"" + newValue + "\"");
std::string value = pRemoteCharacteristic->readValue();
Serial.print("The characteristic value was: ");
Serial.println(value.c_str());
//pRemoteCharacteristic->registerForNotify(notifyCallback);
// Set the characteristic's value to be the array of bytes that is actually a string.
//pRemoteCharacteristic->writeValue(newValue.c_str(), newValue.length());
}
delay(1000); // Delay a second between loops.
} // End of loop
And the Notify code I'm using is the one below
/*
Video: https://www.youtube.com/watch?v=oCMOYS71NIU
Based on Neil Kolban example for IDF: https://github.com/nkolban/esp32-snippets/blob/master/cpp_utils/tests/BLE%20Tests/SampleNotify.cpp
Ported to Arduino ESP32 by Evandro Copercini
Create a BLE server that, once we receive a connection, will send periodic notifications.
The service advertises itself as: 4fafc201-1fb5-459e-8fcc-c5c9c331914b
And has a characteristic of: beb5483e-36e1-4688-b7f5-ea07361b26a8
The design of creating the BLE server is:
1. Create a BLE Server
2. Create a BLE Service
3. Create a BLE Characteristic on the Service
4. Create a BLE Descriptor on the characteristic
5. Start the service.
6. Start advertising.
A connect hander associated with the server starts a background task that performs notification
every couple of seconds.
*/
#include <BLEDevice.h>
#include <BLEServer.h>
#include <BLEUtils.h>
#include <BLE2902.h>
BLEServer* pServer = NULL;
BLECharacteristic* pCharacteristic = NULL;
bool deviceConnected = false;
bool oldDeviceConnected = false;
uint8_t value = 0;
// See the following for generating UUIDs:
// https://www.uuidgenerator.net/
#define SERVICE_UUID "91bad492-b950-4226-aa2b-4ede9fa42f59"
#define CHARACTERISTIC_UUID "0d563a58-196a-48ce-ace2-dfec78acc814"
class MyServerCallbacks: public BLEServerCallbacks {
void onConnect(BLEServer* pServer) {
deviceConnected = true;
};
void onDisconnect(BLEServer* pServer) {
deviceConnected = false;
}
};
void setup() {
Serial.begin(115200);
// Create the BLE Device
BLEDevice::init("ESP30");
// 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();
BLEAdvertising *pAdvertising = pServer->getAdvertising();
pAdvertising->addServiceUUID(SERVICE_UUID); //<--- ADD THIS LINE
pAdvertising->start();
// Start advertising
pServer->getAdvertising()->start();
Serial.println("Waiting a client connection to notify...");
}
void loop() {
// notify changed value
if (deviceConnected) {
pCharacteristic->setValue("Hello world says Luli");
pCharacteristic->notify();
value++;
delay(20000); // bluetooth stack will go into congestion, if too many packets are sent
}
// 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;
}
// connecting
if (deviceConnected && !oldDeviceConnected) {
// do stuff here on connecting
oldDeviceConnected = deviceConnected;
}
}
It looks like the code above doesn't try connecting because doConnect
gets set to false
after the first connection. I can post an example of it connecting to multiple servers later today.
Ok! Ty
I was able to connect two devices (now using server code) making a few changes in the Client code. It works for at least 1 ou 2 minutes.
Forming a connection to 30:ae:a4:92:0b:be
- Created client
- Connected to server
- Found our service
- Found our characteristic
The characteristic value was: Hello World says Xastre
We are now connected to the BLE Server. 1
E (167657) BT: bta_gattc_conn_cback() - cif=3 connected=0 conn_id=3 reason=0x0016
E (167659) BT: bta_gattc_conn_cback() - cif=4 connected=0 conn_id=4 reason=0x0016
Forming a connection to 30:ae:a4:92:6b:72
- Created client
- Connected to server
- Found our service
- Found our characteristic
The characteristic value was: Hello World says Luli
We are now connected to the BLE Server 2.
E (171227) BT: bta_gattc_conn_cback() - cif=3 connected=0 conn_id=3 reason=0x0016
E (171230) BT: bta_gattc_conn_cback() - cif=4 connected=0 conn_id=4 reason=0x0016
Forming a connection to 30:ae:a4:92:0b:be
- Created client
- Connected to server
- Found our service
- Found our characteristic
The characteristic value was: Hello World says Xastre
We are now connected to the BLE Server. 1
E (174902) BT: bta_gattc_conn_cback() - cif=3 connected=0 conn_id=3 reason=0x0016
E (174905) BT: bta_gattc_conn_cback() - cif=4 connected=0 conn_id=4 reason=0x0016
--> So far, the messages are completely normal because I am using pClient->disconnect();, and then this happens
Forming a connection to 30:ae:a4:92:6b:72
- Created client
E (178064) BT: bta_gattc_conn_cback() - cif=3 connected=0 conn_id=3 reason=0x003e
E (178065) BT: p_conn is NULL in bta_gattc_conn_cback
E (178066) BT: bta_gattc_conn_cback() - cif=4 connected=0 conn_id=4 reason=0x003e
E (178073) BT: p_conn is NULL in bta_gattc_conn_cback
We are now connected to the BLE Server 2.
We are now connected to the BLE Server 2.
Forming a connection to 30:ae:a4:92:0b:be
- Created client
- Connected to server
- Found our service
- Found our characteristic
The characteristic value was: Hello World says Xastre
We are now connected to the BLE Server. 1
E (181757) BT: bta_gattc_conn_cback() - cif=3 connected=0 conn_id=3 reason=0x0016
E (181760) BT: bta_gattc_conn_cback() - cif=4 connected=0 conn_id=4 reason=0x0016
E (181767) BT: bta_gattc_conn_cback() - cif=5 connected=0 conn_id=5 reason=0x0016
Forming a connection to 30:ae:a4:92:6b:72
- Created client
E (184756) BT: application already registered.
E (184756) BT: Register with GATT stack failed.
E (184758) BT: application already registered.
E (184762) BT: Register with GATT stack failed.
E (184766) BT: bta_gattc_process_api_open Failed, unknown client_if: 0
After this, everything stops.
The code I'm using for client is in this txt file
Were you able to fix this problem?
No, I wasn't...
Can you please provide multiple servers connection example? I was able to connect to 2 servers and get the characteristics but somehow writeValue works only for the first server and hangs there.
@luizahiginoss @mangooose @Donderda @nsamala Ok, i have good news. I have working code for one esp32 client connecting to multiple peripherals. As for now works connecting, disconnecting and register for notifications with receiving notifications of course.
Only thing that does not work for me, but im pretty sure its because of my simplified main_app code, is write to remote characteristic. In theory it suppose to work too.
All i have to do now is to cleanup code and make some improvements, because i have to marge multiple clients with multiple servers.
@chegewara Great :D thanks a lot. Which ESP32 module are you using?
I am using devKitC and analog lamb esp32 wrover mini.
I would like to apology for mess in code, because i am working on many additions, changes and bugfixes now. This will be code for testing purposes only. I will create new branch for it and all issues or questions please post on my repository:
https://github.com/chegewara/esp32-snippets-enchancements-test/tree/multi_connect_test
Starting point to write own client and server are SampleServer and SampleClient from main subfolder (its just suggestion).
PS i am able to connect to 4 peripherals simultaneously and send independent write request to each of them, also receiving notifications. some crash occurs when 1 of 4 peripherals disconnects.
Added arduino compatibility, you just need to export library to arduino on your own. https://github.com/nkolban/esp32-snippets/blob/master/cpp_utils/ArduinoBLE.md#replacing-the-version-that-comes-with-arduino-esp32
PS there is arduino example in library too
Hi, i have to solve one or two issues and i can post nicely working version that can be used both ways (one server to multi client and one client to multi peripherals). Biggest issue now is how esp-idf stack works. When esp32 is running in central/master role (BLEClient) and there is few peripherals connected, when one peripheral got disconnected bt stack is disconnecting all peripheral devices. This and few more small issues drives me crazy, but i am working on it. If there is request to publish current version library to my repository just tell me.
@chegewara please publish it
@chegewara currently I use the latest code in master and i couldn't connect to multiple servers should i use this repo ?
Yes, but its not published yet. Give me few minutes.
I have nice rig setup now:
Now, esp32 client is performing infinite scanning for peripherals, when peripheral is found client is connecting to it and starts sending write message to remote characteristic on that peripheral. This is happening every 1000 ms with vTaskDelayUntil
. When peripheral receive write request then its sending echo with notification to every connected client device. As for now all works fine, from time to time i have central crash, but it seems to be esp-idf bt stack related.
With smartphone i can monitor peripherals.
So i can have one central esp32 connected to many peripherals that also can be connected to many centrals.
@mangooose Most API has not been changed, but in BLEScan is few changes. Those are not breaking older code changes but are useful during multi connecting.
@chegewara which repo should I use?
Implemented in latest version.
https://github.com/chegewara/esp32-snippets-enchancements-test/tree/multi_connect_test
@chegewara I can't acces the link, is it merged somewhere?
Its merged already in master.
"404 didnt find anyrhing here" . i cant open the link.
Its because repository is no longer public since code is merged here.
@chegeware I can’t access to the link And I need esp32 ble code to connect BLE server to 4 Clint have the same uuid
Its already in the latest master
Written with two thumbs on my mobile device...
Am 03.06.2019 um 00:55 schrieb helmym notifications@github.com:
@chegeware I can’t access to the link And I need esp32 ble code to connect BLE server to 4 Clint have the same uuid
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or mute the thread.
@chegewara Hello, I´m trying to connect one ESP32 as the client and other 6 ESPs as servers but i'm able to connect client to only one server. You said that you are able to connect multiple servers and its in the master but i'm not able to find it. Can you please help me where i can find it or is there any example? Thanks for response.
No, there is no example, at least i dont know any.
You have to remember that with arduino its limited to 3 simultaneous connection and with esp-idf you need to chanage setting with make menuconfig.
There is nothing special you have to do, just create BLEClient for every server you want to connect to.
@chegewara I tried to find your client code for multiple servers, but i couldn't. Can you show me the link?
This is very old code and its for sure not production ready, but it should works:
/**
* Create a sample BLE client that connects to a BLE server and then retrieves the current
* characteristic value. It will then periodically update the value of the characteristic on the
* remote server with the current time since boot.
*/
#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
#include <esp_log.h>
#include <string>
#include <sstream>
#include <sys/time.h>
#include "BLEDevice.h"
#include "FreeRTOS.h"
#include <nvs_flash.h>
#include "BLEAdvertisedDevice.h"
#include "BLEClient.h"
#include "BLEScan.h"
#include "BLEUtils.h"
#include "Task.h"
#include "sdkconfig.h"
#define TICKS_TO_DELAY 1000
BLEScan *pBLEScan;
static const char* LOG_TAG = "TEST";
// esp_ble_addr_type_t addressType;
TaskHandle_t handle;
TaskHandle_t xTaskGetHandle( const char *pcWriteBuffer );
static BLEUUID serviceUUID("4fafc201-1fb5-459e-8fcc-c5c9c331914b");
static BLEUUID charUUID1("beb5483e-36e1-4688-b7f5-ea07361b26a8");
static BLEUUID charUUID2("beb5483e-36e2-4688-b7f5-ea07361b26a8");
static BLEUUID charUUID3("beb5483e-36e3-4688-b7f5-ea07361b26a8");
void scan1(void*);
static void notifyCallback(
BLERemoteCharacteristic* pBLERemoteCharacteristic,
uint8_t* pData,
size_t length,
bool isNotify) {
ESP_LOGE(LOG_TAG, "Notify callback for characteristic %s of data %s length %d",
pBLERemoteCharacteristic->getUUID().toString().c_str(), ((char*) pData), length);
}
class MyCallbacks : public BLEClientCallbacks {
void onConnect(BLEClient* pC){
// xTaskCreate(scan1, "scan", 4048, NULL, 5, NULL);
}
void onDisconnect(BLEClient* pC) {
// pBLEScan->erase(pC->getPeerAddress());
}
};
esp_ble_addr_type_t type;
class MyClient: public Task {
void run(void* data) {
ESP_LOGI(LOG_TAG, "Advertised Device: %s", ((BLEAddress*)data)->toString().c_str());
BLEAddress addr = *(BLEAddress*)data;
BLEClient* pClient = BLEDevice::createClient();
pClient->setClientCallbacks(new MyCallbacks());
// esp_ble_gap_set_prefer_conn_params(*addr.getNative(), 100,125, 2, 0x03e8);
pClient->connect(addr, type);
// xTaskCreate(scan1, "scan", 4048, NULL, 5, NULL);
BLERemoteService* pRemoteService = pClient->getService(serviceUUID);
if (pRemoteService == nullptr) {
ESP_LOGD(LOG_TAG, "Failed to find our service UUID: %s", serviceUUID.toString().c_str());
pClient->disconnect();
stop();
return;
}
BLERemoteCharacteristic* pRemoteCharacteristic = pRemoteService->getCharacteristic(charUUID1);
if (pRemoteCharacteristic != nullptr) {
ESP_LOGW(LOG_TAG, "Found our characteristic UUID1: %s", charUUID1.toString().c_str());
goto ready;
}
pRemoteCharacteristic = pRemoteService->getCharacteristic(charUUID2);
if (pRemoteCharacteristic != nullptr) {
ESP_LOGW(LOG_TAG, "Found our characteristic UUID2: %s", charUUID2.toString().c_str());
goto ready;
}
pRemoteCharacteristic = pRemoteService->getCharacteristic(charUUID3);
if (pRemoteCharacteristic == nullptr) {
ESP_LOGD(LOG_TAG, "Failed to find our characteristic UUID: %s, disconnecting", charUUID1.toString().c_str());
pClient->disconnect();
stop();
return;
}
ready:
pRemoteCharacteristic->registerForNotify(notifyCallback);
// handle = xTaskGetHandle("btuT");
xTaskCreate(scan1, "scan", 4048, NULL, 1, NULL);
TickType_t last_wake_time;
last_wake_time = xTaskGetTickCount();
while(pClient->isConnected()) {
// ESP_LOGI(LOG_TAG, "5--> %d", uxTaskGetStackHighWaterMark(NULL));
std::ostringstream stringStream;
struct timeval tv;
gettimeofday(&tv, nullptr);
stringStream << "Time sent to uuid: " << pRemoteCharacteristic->getUUID().toString().c_str() << tv.tv_sec << "." << tv.tv_usec;
pRemoteCharacteristic->writeValue(stringStream.str());
vTaskDelayUntil(&last_wake_time, TICKS_TO_DELAY/portTICK_PERIOD_MS);
// if(handle)
// ESP_LOGW(LOG_TAG, "btuT highwater--> %d", uxTaskGetStackHighWaterMark(handle));
// heap_caps_print_heap_info(MALLOC_CAP_EXEC | MALLOC_CAP_8BIT );
}
// pClient->disconnect();
ESP_LOGD(LOG_TAG, "%s", pClient->toString().c_str());
ESP_LOGD(LOG_TAG, "-- End of task");
stop();
} // run
}; // MyClient
class MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks {
void onResult(BLEAdvertisedDevice advertisedDevice) {
ESP_LOGI(LOG_TAG, "Advertised Device: %s", advertisedDevice.toString().c_str());
ESP_LOG_BUFFER_HEX_LEVEL(__func__, advertisedDevice.getPayload(), advertisedDevice.getPayloadLength(), ESP_LOG_WARN);
if (advertisedDevice.haveServiceUUID() && advertisedDevice.isAdvertisingService(BLEUUID("00001234"))) {
pBLEScan->stop(); // <--- it is required to always stop scan before we try to connect to another device, if we wont stop app will stall in esp-idf bt stack
type = advertisedDevice.getAddressType();
MyClient* pMyClient = new MyClient();
pMyClient->setStackSize(5000);
pMyClient->start(new BLEAddress(*advertisedDevice.getAddress().getNative()));
}
}
};
static void my_gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t* param) {
ESP_LOGW(LOG_TAG, "custom gap event handler, event: %d", (uint8_t)event);
}
static void my_gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if, esp_ble_gattc_cb_param_t* param) {
ESP_LOGW(LOG_TAG, "custom gattc event handler, event: %d", (uint8_t)event);
}
static void my_gatts_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gattc_if, esp_ble_gatts_cb_param_t* param) {
ESP_LOGW(LOG_TAG, "custom gatts event handler, event: %d", (uint8_t)event);
}
void SampleClient2(void) {
esp_log_level_set("*", ESP_LOG_INFO);
esp_log_level_set("BLEUtils", ESP_LOG_NONE);
// heap_caps_print_heap_info(MALLOC_CAP_EXEC | MALLOC_CAP_8BIT );
// new BLEUUID("00001234-0000-1000-8000-00805f9b34fb");
BLEDevice::init("esp32");
nvs_flash_erase();
BLEDevice::setCustomGapHandler(my_gap_event_handler);
BLEDevice::setCustomGattsHandler(my_gatts_event_handler);
BLEDevice::setCustomGattcHandler(my_gattc_event_handler);
BLEDevice::setMTU(100);
handle = xTaskGetHandle("btuT");
pBLEScan = BLEDevice::getScan();
pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());
pBLEScan->setActiveScan(true);
pBLEScan->setInterval(1389);
pBLEScan->setWindow(349);
xTaskCreate(scan1, "scan", 4048, NULL, 1, NULL);
} // SampleClient
void scan1(void*){
ESP_LOGI(LOG_TAG, "start scan");
pBLEScan->start(0, true);
ESP_LOGI(LOG_TAG, "scan stop success");
vTaskDelete(NULL);
}
// this code is only for debug purpose, to see if we have problem wit esp-idf btuT task stack
TaskHandle_t xTaskGetHandle( const char *pcWriteBuffer )
{
TaskStatus_t *pxTaskStatusArray;
volatile UBaseType_t uxArraySize, x;
uint32_t ulTotalRunTime;
uxArraySize = uxTaskGetNumberOfTasks();
pxTaskStatusArray = (TaskStatus_t *)pvPortMalloc( uxArraySize * sizeof( TaskStatus_t ) );
if( pxTaskStatusArray != NULL )
{
uxArraySize = uxTaskGetSystemState( pxTaskStatusArray, uxArraySize, &ulTotalRunTime );
for( x = 0; x < uxArraySize; x++ )
{
ESP_LOGW(LOG_TAG, "%s highwater--> %d, state: %d ", pxTaskStatusArray[x].pcTaskName, uxTaskGetStackHighWaterMark(pxTaskStatusArray[x].xHandle), (uint8_t)pxTaskStatusArray[x].eCurrentState);
if(strncmp(pxTaskStatusArray[x].pcTaskName, pcWriteBuffer, strlen(pcWriteBuffer)) == 0){
vPortFree( pxTaskStatusArray );
return pxTaskStatusArray[x].xHandle;
}
}
vPortFree( pxTaskStatusArray );
}
return nullptr;
}
This is very old code and its for sure not production ready, but it should works:
/** * Create a sample BLE client that connects to a BLE server and then retrieves the current * characteristic value. It will then periodically update the value of the characteristic on the * remote server with the current time since boot. */ #include <freertos/FreeRTOS.h> #include <freertos/task.h> #include <esp_log.h> #include <string> #include <sstream> #include <sys/time.h> #include "BLEDevice.h" #include "FreeRTOS.h" #include <nvs_flash.h> #include "BLEAdvertisedDevice.h" #include "BLEClient.h" #include "BLEScan.h" #include "BLEUtils.h" #include "Task.h" #include "sdkconfig.h" #define TICKS_TO_DELAY 1000 BLEScan *pBLEScan; static const char* LOG_TAG = "TEST"; // esp_ble_addr_type_t addressType; TaskHandle_t handle; TaskHandle_t xTaskGetHandle( const char *pcWriteBuffer ); static BLEUUID serviceUUID("4fafc201-1fb5-459e-8fcc-c5c9c331914b"); static BLEUUID charUUID1("beb5483e-36e1-4688-b7f5-ea07361b26a8"); static BLEUUID charUUID2("beb5483e-36e2-4688-b7f5-ea07361b26a8"); static BLEUUID charUUID3("beb5483e-36e3-4688-b7f5-ea07361b26a8"); void scan1(void*); static void notifyCallback( BLERemoteCharacteristic* pBLERemoteCharacteristic, uint8_t* pData, size_t length, bool isNotify) { ESP_LOGE(LOG_TAG, "Notify callback for characteristic %s of data %s length %d", pBLERemoteCharacteristic->getUUID().toString().c_str(), ((char*) pData), length); } class MyCallbacks : public BLEClientCallbacks { void onConnect(BLEClient* pC){ // xTaskCreate(scan1, "scan", 4048, NULL, 5, NULL); } void onDisconnect(BLEClient* pC) { // pBLEScan->erase(pC->getPeerAddress()); } }; esp_ble_addr_type_t type; class MyClient: public Task { void run(void* data) { ESP_LOGI(LOG_TAG, "Advertised Device: %s", ((BLEAddress*)data)->toString().c_str()); BLEAddress addr = *(BLEAddress*)data; BLEClient* pClient = BLEDevice::createClient(); pClient->setClientCallbacks(new MyCallbacks()); // esp_ble_gap_set_prefer_conn_params(*addr.getNative(), 100,125, 2, 0x03e8); pClient->connect(addr, type); // xTaskCreate(scan1, "scan", 4048, NULL, 5, NULL); BLERemoteService* pRemoteService = pClient->getService(serviceUUID); if (pRemoteService == nullptr) { ESP_LOGD(LOG_TAG, "Failed to find our service UUID: %s", serviceUUID.toString().c_str()); pClient->disconnect(); stop(); return; } BLERemoteCharacteristic* pRemoteCharacteristic = pRemoteService->getCharacteristic(charUUID1); if (pRemoteCharacteristic != nullptr) { ESP_LOGW(LOG_TAG, "Found our characteristic UUID1: %s", charUUID1.toString().c_str()); goto ready; } pRemoteCharacteristic = pRemoteService->getCharacteristic(charUUID2); if (pRemoteCharacteristic != nullptr) { ESP_LOGW(LOG_TAG, "Found our characteristic UUID2: %s", charUUID2.toString().c_str()); goto ready; } pRemoteCharacteristic = pRemoteService->getCharacteristic(charUUID3); if (pRemoteCharacteristic == nullptr) { ESP_LOGD(LOG_TAG, "Failed to find our characteristic UUID: %s, disconnecting", charUUID1.toString().c_str()); pClient->disconnect(); stop(); return; } ready: pRemoteCharacteristic->registerForNotify(notifyCallback); // handle = xTaskGetHandle("btuT"); xTaskCreate(scan1, "scan", 4048, NULL, 1, NULL); TickType_t last_wake_time; last_wake_time = xTaskGetTickCount(); while(pClient->isConnected()) { // ESP_LOGI(LOG_TAG, "5--> %d", uxTaskGetStackHighWaterMark(NULL)); std::ostringstream stringStream; struct timeval tv; gettimeofday(&tv, nullptr); stringStream << "Time sent to uuid: " << pRemoteCharacteristic->getUUID().toString().c_str() << tv.tv_sec << "." << tv.tv_usec; pRemoteCharacteristic->writeValue(stringStream.str()); vTaskDelayUntil(&last_wake_time, TICKS_TO_DELAY/portTICK_PERIOD_MS); // if(handle) // ESP_LOGW(LOG_TAG, "btuT highwater--> %d", uxTaskGetStackHighWaterMark(handle)); // heap_caps_print_heap_info(MALLOC_CAP_EXEC | MALLOC_CAP_8BIT ); } // pClient->disconnect(); ESP_LOGD(LOG_TAG, "%s", pClient->toString().c_str()); ESP_LOGD(LOG_TAG, "-- End of task"); stop(); } // run }; // MyClient class MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks { void onResult(BLEAdvertisedDevice advertisedDevice) { ESP_LOGI(LOG_TAG, "Advertised Device: %s", advertisedDevice.toString().c_str()); ESP_LOG_BUFFER_HEX_LEVEL(__func__, advertisedDevice.getPayload(), advertisedDevice.getPayloadLength(), ESP_LOG_WARN); if (advertisedDevice.haveServiceUUID() && advertisedDevice.isAdvertisingService(BLEUUID("00001234"))) { pBLEScan->stop(); // <--- it is required to always stop scan before we try to connect to another device, if we wont stop app will stall in esp-idf bt stack type = advertisedDevice.getAddressType(); MyClient* pMyClient = new MyClient(); pMyClient->setStackSize(5000); pMyClient->start(new BLEAddress(*advertisedDevice.getAddress().getNative())); } } }; static void my_gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t* param) { ESP_LOGW(LOG_TAG, "custom gap event handler, event: %d", (uint8_t)event); } static void my_gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if, esp_ble_gattc_cb_param_t* param) { ESP_LOGW(LOG_TAG, "custom gattc event handler, event: %d", (uint8_t)event); } static void my_gatts_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gattc_if, esp_ble_gatts_cb_param_t* param) { ESP_LOGW(LOG_TAG, "custom gatts event handler, event: %d", (uint8_t)event); } void SampleClient2(void) { esp_log_level_set("*", ESP_LOG_INFO); esp_log_level_set("BLEUtils", ESP_LOG_NONE); // heap_caps_print_heap_info(MALLOC_CAP_EXEC | MALLOC_CAP_8BIT ); // new BLEUUID("00001234-0000-1000-8000-00805f9b34fb"); BLEDevice::init("esp32"); nvs_flash_erase(); BLEDevice::setCustomGapHandler(my_gap_event_handler); BLEDevice::setCustomGattsHandler(my_gatts_event_handler); BLEDevice::setCustomGattcHandler(my_gattc_event_handler); BLEDevice::setMTU(100); handle = xTaskGetHandle("btuT"); pBLEScan = BLEDevice::getScan(); pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks()); pBLEScan->setActiveScan(true); pBLEScan->setInterval(1389); pBLEScan->setWindow(349); xTaskCreate(scan1, "scan", 4048, NULL, 1, NULL); } // SampleClient void scan1(void*){ ESP_LOGI(LOG_TAG, "start scan"); pBLEScan->start(0, true); ESP_LOGI(LOG_TAG, "scan stop success"); vTaskDelete(NULL); } // this code is only for debug purpose, to see if we have problem wit esp-idf btuT task stack TaskHandle_t xTaskGetHandle( const char *pcWriteBuffer ) { TaskStatus_t *pxTaskStatusArray; volatile UBaseType_t uxArraySize, x; uint32_t ulTotalRunTime; uxArraySize = uxTaskGetNumberOfTasks(); pxTaskStatusArray = (TaskStatus_t *)pvPortMalloc( uxArraySize * sizeof( TaskStatus_t ) ); if( pxTaskStatusArray != NULL ) { uxArraySize = uxTaskGetSystemState( pxTaskStatusArray, uxArraySize, &ulTotalRunTime ); for( x = 0; x < uxArraySize; x++ ) { ESP_LOGW(LOG_TAG, "%s highwater--> %d, state: %d ", pxTaskStatusArray[x].pcTaskName, uxTaskGetStackHighWaterMark(pxTaskStatusArray[x].xHandle), (uint8_t)pxTaskStatusArray[x].eCurrentState); if(strncmp(pxTaskStatusArray[x].pcTaskName, pcWriteBuffer, strlen(pcWriteBuffer)) == 0){ vPortFree( pxTaskStatusArray ); return pxTaskStatusArray[x].xHandle; } } vPortFree( pxTaskStatusArray ); } return nullptr; }
Hello @chegewara , I am trying the same example and i am getting guru meditation error which i opened as other issue , my application is same as mentioend in this example, i am working on that error since a month, could you give me step by step guidance on this one, i think i am missing somehting, i coulnt thank you more !
Regards,
I can try to help with errors, but you need to provide some more info and logs.
hi @luizahiginoss @chegewara @mangooose
I'm trying to develop a bluetooth network with one client and several servers, but they communicate with the client based on "notify". each server is connected to a sensor (DHT11). i am able to connect to one server and get the temp characteristic.
i need a code for one esp32 client connecting to multiple ESP32 server .
I'm using the BLE examples
i came across this "multi-connection example’s main source file is gattc_multi_connect.c." https://github.com/espressif/esp-idf/blob/a6f33a9d366e8179fa7d18a81f205254a15db117/examples/bluetooth/bluedroid/ble/gattc_multi_connect/main/gattc_multi_connect.c but it seems its not for arduino IDE
hi @AS123-y
I am currently attempting to build a bluetooth network of ESP32s one client and about 3 servers, similar to your project. each server would be connected to accelerometers. I just plan on sending the different accelerometer values to the client, which would display them on some LCD display. Were you able to figure out your project?
hi @guevaj5 no, I still didn't figure out a solution. Please keep me updated on the status of things.
Can you send me WhatsApp please 00201121106662
On Thu, 25 Nov 2021 at 12:05 PM AS123-y @.***> wrote:
hi @guevaj5 https://github.com/guevaj5 no, I still didn't figure out a solution. Please keep me updated on the status of things.
— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/nkolban/esp32-snippets/issues/538#issuecomment-979053226, or unsubscribe https://github.com/notifications/unsubscribe-auth/AMHM6L4ZFIHPWRY2A2KS3C3UNYC6LANCNFSM4FCCGN2Q . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.
@luizahiginoss @mangooose @AS123-y Do you find solution to connect multiple ESP32 BLE servers with one ESP32 BLE client on Arduino IDE?
@luizahiginoss [BLE_client.txt] Did you solved the issue?
Hello Yes I had do it Send me your issue and we will discuss it
On Thu, 9 Feb 2023 at 8:58 AM Sireevenkat @.***> wrote:
@luizahiginoss https://github.com/luizahiginoss @mangooose https://github.com/mangooose @AS123-y https://github.com/AS123-y Do you find solution to connect multiple ESP32 BLE servers with one ESP32 BLE client on Arduino IDE? @luizahiginoss https://github.com/luizahiginoss [BLE_client.txt] Did you solved the issue?
— Reply to this email directly, view it on GitHub https://github.com/nkolban/esp32-snippets/issues/538#issuecomment-1423723842, or unsubscribe https://github.com/notifications/unsubscribe-auth/AMHM6L5DTKPHZ7DCYX5EZC3WWSIS5ANCNFSM4FCCGN2Q . You are receiving this because you commented.Message ID: @.***>
@luizahiginoss @mangooose @AS123-y Do you find solution to connect multiple ESP32 BLE servers with one ESP32 BLE client on Arduino IDE? @luizahiginoss [BLE_client.txt] Did you solved the issue?
Hi @Sireevenkat i still did not find a solution @helmym can you share your findings?
Send me WhatsApp please 00201121106662
On Thu, 9 Feb 2023 at 1:44 PM Helmy Mohamed @.***> wrote:
Hello Yes I had do it Send me your issue and we will discuss it
On Thu, 9 Feb 2023 at 8:58 AM Sireevenkat @.***> wrote:
@luizahiginoss https://github.com/luizahiginoss @mangooose https://github.com/mangooose @AS123-y https://github.com/AS123-y Do you find solution to connect multiple ESP32 BLE servers with one ESP32 BLE client on Arduino IDE? @luizahiginoss https://github.com/luizahiginoss [BLE_client.txt] Did you solved the issue?
— Reply to this email directly, view it on GitHub https://github.com/nkolban/esp32-snippets/issues/538#issuecomment-1423723842, or unsubscribe https://github.com/notifications/unsubscribe-auth/AMHM6L5DTKPHZ7DCYX5EZC3WWSIS5ANCNFSM4FCCGN2Q . You are receiving this because you commented.Message ID: @.***>
Hi, @helmym,@chegewara,@AS123-y I am working with ESP32-S3 module on Arduino IDE.I need to connect multiple BLE servers to one client and able send and receive data from client to all servers at a time. Can You share your findings. Thanks
I'm trying to develop a bluetooth network with one client and several servers, but they communicate with the client based on "notify". If they have the same service UUID and characteristic UUID i won't be able to do that? Probably i'm just getting confused with GATT and GAP aplications for BLE... Can u help me?
I haven't started the tests yet, but I'm using the BLE examples...