Skip to content

BLE Central Arduino Example #45

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
WALLTECH opened this issue Sep 3, 2017 · 66 comments
Closed

BLE Central Arduino Example #45

WALLTECH opened this issue Sep 3, 2017 · 66 comments

Comments

@WALLTECH
Copy link

WALLTECH commented Sep 3, 2017

Hi Neil, as posted on the ESP-Arduino repo, a BLE Central scan for device, connect, enable notifications or other characteristic and read/write the value example would be really useful.

@nkolban
Copy link
Owner

nkolban commented Sep 3, 2017

Howdy John ... noticed and received. Lets see if we can't get specific on what you'd like to see so that we can deliver the example as close as possible to what you want. As we see here, there is ambiguity in phrases like central and peripheral, so I'm going to spell out what I think you'd like to see and then see how close this comes to what you actually want.

You want the ESP32 to be a "client" in that it will perform a scan for a "server" that is continually broadcasting. When it finds a suitable server, it will then connect to that server, enable notifications and start receiving notifications from the server. In addition, the ESP32 will want to read the value of the characteristic and write a new value at any given time.

Is that correct? When you confirm or tweak, we'll start writing the sample for your review.

@WALLTECH
Copy link
Author

WALLTECH commented Sep 3, 2017

Hi Neil, wow, that's very kind, thank you. I'm sorry I couldn't help more, I wanted to try to contribute to the examples. Your description is exactly right in every way! It will also make a wonderful central example.

@nkolban
Copy link
Owner

nkolban commented Sep 3, 2017

Okly dokly ... on it my friend.

@WALLTECH
Copy link
Author

WALLTECH commented Sep 3, 2017

I'd be writing Hex byte arrays if that helps

@nkolban nkolban self-assigned this Sep 3, 2017
nkolban added a commit that referenced this issue Sep 4, 2017
@nkolban
Copy link
Owner

nkolban commented Sep 4, 2017

A first pass at a full BLE Client application running in Arduino has been made available here:

https://github.com/nkolban/esp32-snippets/tree/master/cpp_utils/tests/BLETests/Arduino/BLE_client

The paint is still wet on it and there may very well be problems but built and tested on my system and so far so good. What I'd like you to do is run up the application and give it a whirl.

You will need an external BLE Server such as the nRF Connect application. The sample expects a BLE Server with an exposed service with UUID of 91bad492-b950-4226-aa2b-4ede9fa42f59 that exposes a characteristic with UUID 0d563a58-196a-48ce-ace2-dfec78acc814. These are just generated UUIDs but what your server uses and what your client expects must match. The sample does a few things:

  1. It scans for a suitable advertised server.
  2. It connects to the server.
  3. It downloads from the server the value of the characteristic at the start and logs it.
  4. Every second, it writes a new value of the characteristic to the server.
  5. If the server issues a notification, the client detects that and logs that a notification occurred.

That's a lot of function. Usually much more than we put in a "sample". Please have a read of the code and then we can start the discussions on how much is understandable and work together to make what isn't clear clearer for the next person.

@WALLTECH
Copy link
Author

WALLTECH commented Sep 4, 2017

It looks great! I'll throw in my uuids and give it a go tomorrow. Thank you very much, this is a great help.

@WALLTECH
Copy link
Author

WALLTECH commented Sep 4, 2017

Alright, I put my uuids in and set it up to connect by mac address rather than service as the ones I want aren't advertised, and I get this out with no further data:

Found our device! address: e9:44:8b:41:d7:2d
Forming a connection to e9:44:8b:41:d7:2d

  • Created client
    E (49918) BT: l2cble_start_conn_update, the last connection update command still pending.
    E (49918) BT: l2cble_start_conn_update, the last connection update command still pending.
  • Connected to server
    E (50267) BT: l2cble_start_conn_update, staus = 1, line = 509
    E (50755) BT: set_read_value unformat.len = 18
    The characteristic value was:
    E (51039) BT: bta_gattc_cmpl_cback unknown conn_id = 3, ignore data

@nkolban
Copy link
Owner

nkolban commented Sep 4, 2017

Howdy John,
I'm studying now. If you can learn/use IRC, find me on channel #ESP32 for live chat.

@nklys
Copy link

nklys commented Sep 6, 2017

Hello Neil. When a server is detected, the following error occurs and a cyclic reboot.

ets Jun 8 2016 00:22:57

rst:0x1 (POWERON_RESET),boot:0x17 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0010,len:4
load:0x3fff0014,len:588
load:0x40078000,len:0
load:0x40078000,len:9768
entry 0x400789b8
Starting Arduino BLE Client application...
BLE Advertised Device found: Name: , Address: 63:03:2a:64:67:33, serviceUUID: 91bad492-b950-4226-aa2b-4ede9fa42f59
Found our device! address: Forming a connection to 63:03:2a:64:67:33

  • Created client
    E (37489) BT: l2cble_start_conn_update, the last connection update command still pending.
    E (37489) BT: l2cble_start_conn_update, the last connection update command still pending.
  • Connected to serverGuru Meditation Error: Core 0 panic'ed (Unhandled debug exception)
    Debug exception reason: Stack canary watchpoint triggered (Btc_task)
    Register dump:
    PC : 0x4000c3fa PS : 0x00060536 A0 : 0x800da0fa A1 : 0x3ffde0b0
    A2 : 0x3ffd6479 A3 : 0x3ffd647b A4 : 0xfffffffe A5 : 0x00000000
    A6 : 0x3ffd8ae8 A7 : 0x3ffd1ce6 A8 : 0x00005ce7 A9 : 0x3ffdc160
    A10 : 0x000000a5 A11 : 0x00060f23 A12 : 0x00060d23 A13 : 0x3ffde250
    A14 : 0x02336764 A15 : 0x02336764 SAR : 0x00000018 EXCCAUSE: 0x00000001
    EXCVADDR: 0x00000000 LBEG : 0x400014fd LEND : 0x4000150d LCOUNT : 0xfffffffe

Backtrace: 0x4000c3fa:0x3ffde0b0 0x400da0f7:0x3ffde0d0 0x400da4b1:0x3ffde0f0 0x400da575:0x3ffde120 0x400da585:0x3ffde140 0x400d6222:0x3ffde160 0x400d3d0a:0x3ffde180 0x400d3fdd:0x3ffde210 0x400f2336:0x3ffde230 0x400ef188:0x3ffde2b0

Rebooting...

@nkolban
Copy link
Owner

nkolban commented Sep 6, 2017

Howdy,
Can you paste bin your code and point out the line at which the crash is happening. I have seen this before when using the BLE Server (not client) and the solution was to add a 200msec delay after initialization. I have a "gut feel" that the same thing may be happening with the client. If you can post your sketch, I'll take a good look.

@nklys
Copy link

nklys commented Sep 6, 2017

This is your example BLE_cient.ino. And as a server NRF connect.

@nklys
Copy link

nklys commented Sep 6, 2017

Where do I need to add a delay? After BLEDevice :: init ("") ?

@nkolban
Copy link
Owner

nkolban commented Sep 6, 2017

What I'll need to do is see if I can recreate to pin it down. I have been testing with debugging on which means that my app is slowed down and hence isn't finding the "race condition".

@nkolban
Copy link
Owner

nkolban commented Sep 7, 2017

I sat down to try and recreate the problem. Using nRF Connect and exactly the sample code in the repo, I ran the test. I must have started the device 50 times. Once (and only once) I got the exact same error as you did. It felt like it was somewhere in the range 20-30. The fact that I saw it once does mean that there is something wrong ... however the fact that I can't reproduce it means its going to be a booger to track down. Experience tells me that we have a programming concept called a "race condition" going on. This means that in our multi-tasking environment something gets released/used before it is finished/ready in another task. Since we have multiple tasks at play and when a task runs is mostly non-deterministic, these become royal pains to diagnose. If I could recreate even 1 in 10 times I'd be happy. Switching on trace is likely not going to help as the act of trace is likely to synchronize things and the problem will never show up.

What I'm interested in finding out is why your device keeps hitting the problem every startup. What kind of ESP32 module are you using? I'm using an Espressif DevKit-C. Lets see if you can't liberally sprinkle Serial.println() statements in your source and see if we can't find the last statement entered. That might give us some more hints/clues. If we think it might help, we can maybe arrange a live debug session over the weekend.

@nklys
Copy link

nklys commented Sep 7, 2017

The board is called Wemos Lolin 32 OLED.
My attempts to insert Serial.println (). :)
https://pastebin.com/MvBK5HfV
https://pastebin.com/dAFK7ZpT

@nklys
Copy link

nklys commented Sep 7, 2017

If I set the output #define CONFIG_LOG_DEFAULT_LEVEL 5, then everything works, the characteristic value in the NRF Connect changes.
Here's the log: https://pastebin.com/TpS39wyc

Another bug - if you disable the GATT server in the NRF Connect and leave only the advertiser with the desired UUID, then a cyclic restart occurs.
log: https://pastebin.com/86jvnygu

@nkolban
Copy link
Owner

nkolban commented Sep 7, 2017

Howdy @nklys ... re the new bug ... disabling the GATT server in nRF Connect. Awesome catch. The code didn't check that the request to connect to the BLE Server has succeeded and merrily wen't on its way as thought it had ... even though the variables relating to the characteristics were null. Not pretty. Thankfully the fix was easy and has been done and committed to the repository.

The race condition issue is going to be tricky to track down. As soon as we switch on debug level diagnostics, the problem fails to manifest which means that it is a race condition issue. I call these kinds of problems "Shrodeinger's bugs". As soon as you try and look at them, they no longer exist to be looked at. What we will need to do is continually splatter manually inserted debug statements into the code while not switching on ALL the debug. At some point we will then see that there is a common "last thing BLE APIs do before crash" and that will tell us where we should put in our manual synchronization to prevent the race condition. Another possible solution is to NOT use loop() but instead put 100% of our code in setup() and control our execution ourselves. My gut says that will also resolve the issue. How does that feel to you? Do you actually need "loop()" in your code?

@nklys
Copy link

nklys commented Sep 8, 2017

With an empty "loop()", nothing has changed. Bug stayed.
I added to "setup()"
pBLEScan->start(30);
delay(1000);
connect To server(*pServerAddress);

I do not know where to insert println (), there are closed libraries. An error, perhaps when calling esp_ble_gattc_open.

@nkolban
Copy link
Owner

nkolban commented Sep 9, 2017

Hmm the mystery continues. What kind of ESP32 module are you running? I have many/most types and have been testing with DevKitC. If you tell me which one you are using, I can test against that to eliminate another possibility.

@nklys
Copy link

nklys commented Sep 9, 2017

The board is called Wemos Lolin 32 OLED.
img_20170909_121752

@nkolban
Copy link
Owner

nkolban commented Sep 9, 2017

Perfect ... I have two of those on my desk right now still in their wrappers. I haven't soldered the pins on yet so that will have to be tomorrow now. If this is more urgent than that, you can always ping me live on channel #ESP32 on IRC.

@nklys
Copy link

nklys commented Sep 12, 2017

Hello Neil.
Have you found a solution to my problem? This simple code, also causes a reboot:
#include "BLEDevice.h"
static BLEAddress pServerAddress;
void setup() {
Serial.begin(115200);
Serial.println("Starting Arduino BLE Client application...");
BLEDevice::init("");
delay(1000);
pServerAddress = new BLEAddress("c8:0f:10:54:bd:00");
delay(1000);
Serial.print("Forming a connection to ");
Serial.println(pServerAddress->toString().c_str());
BLEClient
pClient = BLEDevice::createClient();
Serial.println("Created client");
pClient->connect(*pServerAddress);
Serial.println("Connected to server");
}
void loop() {}

Log:
rst:0x1 (POWERON_RESET),boot:0x17 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0010,len:4
load:0x3fff0014,len:588
load:0x40078000,len:0
load:0x40078000,len:9768
entry 0x400789b8
Starting Arduino BLE Client application...
Forming a connection to c8:0f:10:54:bd:00
Created client
Guru Meditation Error of type LoadStoreAlignment occurred on core 1. Exception was unhandled.
Register dump:
PC : 0x40085847 PS : 0x00060533 A0 : 0x800868e2 A1 : 0x3ffdaeb0
A2 : 0x62184045 A3 : 0x00060523 A4 : 0x00060520 A5 : 0x00000000
A6 : 0x00000000 A7 : 0x3ffd61f8 A8 : 0xb33f0001 A9 : 0xb33fffff
A10 : 0x00060523 A11 : 0x3f401b1b A12 : 0x00000007 A13 : 0x3ffdaf6e
A14 : 0x00000074 A15 : 0x00000063 SAR : 0x00000008 EXCCAUSE: 0x00000009
EXCVADDR: 0x62184045 LBEG : 0x4000c349 LEND : 0x4000c36b LCOUNT : 0xffffffff

Backtrace: 0x40085847:0x3ffdaeb0 0x400868df:0x3ffdaed0 0x40085fd8:0x3ffdaef0 0x400d5787:0x3ffdaf30 0x400d34d4:0x3ffdaf50 0x400d29dd:0x3ffdafc0 0x4018386a:0x3ffdb000

Rebooting...

If enable debug information output, everything starts working. Did you succeed in repeating this bug?

@nkolban
Copy link
Owner

nkolban commented Sep 12, 2017

I tried your sketch but it all seemed to work on my board. Here is the sketch I used:

#include "BLEDevice.h"
static BLEAddress *pServerAddress;
void setup() {
   Serial.begin(115200);
   Serial.println("Starting Arduino BLE Client application...");
   BLEDevice::init("");
   delay(1000);
   pServerAddress = new BLEAddress("12:3B:6A:1A:E2:FD");
   delay(1000);
   Serial.print("Forming a connection to ");
   Serial.println(pServerAddress->toString().c_str());
   BLEClient* pClient = BLEDevice::createClient();
   Serial.println("Created client");
   pClient->connect(*pServerAddress);
   Serial.println("Connected to server");
}
void loop() {}

I'm hearing you loud and clear that switching on debug "masks" the problem. So here is another idea ... I haven't had the opportunity to test it myself ... but Ive heard good things. See the following:

https://github.com/me-no-dev/EspExceptionDecoder

Follow those instructions and get it working. Now when the exception occurs again, follow that recipe and we will decode the backtrace addresses to be able to see where within the code the exception is occurring. Run it a few times, I want to see if it is always the same place that the exception happens.

@nklys
Copy link

nklys commented Sep 12, 2017

Thank you for helping. Here is the output of the exception decoder
for BLE_Client.ino- https://pastebin.com/iE8X4XzV

for code from my past message -https://pastebin.com/uJHaCL9i

@nklys
Copy link

nklys commented Sep 13, 2017

After updating arduino-esp32 in the log another line was added. With multiple starts, the backtrace sometimes changes, there are three variants:
https://pastebin.com/Umr6uTFk - log
https://pastebin.com/st5dsrMp - decoder

@nkolban
Copy link
Owner

nkolban commented Sep 13, 2017

Argh ... that's the problem with asynchronous callbacks and race conditions. Each run can produce a distinct result and when we switch on tracing, things are "slowed down" enough that we have trouble recreating.

Before we go too much further, I'd like to see the content of the "sdkconfig.h" in play in your environment. Find your Arduino IDE install directory and south of there, we will find a file called "sdkconfig.h". Likely in hardware/espressif/tools/sdk/include/config (or something similar to that). I'm explicitly looking for the BT task stack size but if we pastebin the whole file, that would be useful.

What has me puzzles is that you are experiencing the problem but yet we don't have the same reports from others. This makes me want to look at what is "special" in your environment. I'm going to re-read this whole thread from the start and see if I can't find some other clues.

@nklys
Copy link

nklys commented Sep 13, 2017

sdkconfig.h - https://pastebin.com/t51hSjf7

@elloza
Copy link

elloza commented Oct 18, 2017

Hello every one! I am in the same situation that @nklys. @nklys did you make the UART.ino example work? I'm trying with a Wemos Lolin 32 (without OLED) and always get the same result (the rebooting loop). I set the debug configuration at 5 but nothing different happens and I changed the target device to "ESP32 Dev Module". Thanks a lot for your help and congratulation for your great job 👍 👍

@nkolban
Copy link
Owner

nkolban commented Oct 18, 2017

Howdy .... in this document:

https://github.com/nkolban/esp32-snippets/blob/master/cpp_utils/ArduinoBLE.md

At the bottom in a section titled "Decoding an exception stack trace" there is a recipe for getting information from a stack trace. Can I ask you to recreate the problem, copy the stack trace and paste it into the exception decoder. From there, can you post back what you find?

@elloza
Copy link

elloza commented Oct 20, 2017

Thank you for your help @nkolban and sorry for the delay in the response. This is the result:

Rebooting...
ets Jun  8 2016 00:22:57
rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0010,len:4
load:0x3fff0014,len:716
load:0x40078000,len:0
load:0x40078000,len:11572
entry 0x40078a14
abort() was called at PC 0x40083a7f on core 0
Backtrace: 0x400893a8:0x3ffe3bc0 0x400894a7:0x3ffe3be0 0x40083a7f:0x3ffe3c00 0x40083c1c:0x3ffe3c30 0x4007886a:0x3ffe3c50 0x400788d1:0x3ffe3c80 0x40078a0e:0x3ffe3cb0 0x40078b33:0x3ffe3e70 0x40007c31:0x3ffe3eb0 0x4000073d:0x3ffe3f20
Rebooting...

0x400893a8: invoke_abort at /Users/ficeto/Espressif/ESP32/esp-idf/components/esp32/./panic.c line 553
0x400894a7: abort at /Users/ficeto/Espressif/ESP32/esp-idf/components/esp32/./panic.c line 553
0x40083a7f: start_cpu0_default at /Users/ficeto/Espressif/ESP32/esp-idf/components/esp32/./cpu_start.c line 340
0x40083c1c: call_start_cpu0 at /Users/ficeto/Espressif/ESP32/esp-idf/components/esp32/./cpu_start.c line 207

@nkolban
Copy link
Owner

nkolban commented Oct 21, 2017

@elloza Many thanks for the traces ... that helps. The good news is that we have a match for your problem ... see issues #110 and #81. In that story, the problem can be traced back to an attempt to run WiFi and BLE at the same time and running out of RAM. In your application, can we examine the nature of it. Does it attempt to use WiFi and BLE together? Would you be able to pastebin your script so that we can take a look at it?

@elloza
Copy link

elloza commented Oct 22, 2017

Hello again @nkolban! I have been seeing the issues #110 and #81. My code is exactly this:
BLE UART Arduino and I'm using BLE ESP Arduino Library Version 4.2.

I don't know if someone have a simple example using only BLE comunication (in fact, I only need BLE for my current project). If I can help in any way please let me know it. 👍 👍

@elloza
Copy link

elloza commented Oct 23, 2017

Hi @nkolban! Thank you so much for your help! I was reading deeply the issues #110 and #81 and I have updated my ESP32 core libraries to the last commit available. Now the UART example is working great! :) I will continue developing with the LOLIN32 board so I will give you more feedback :)

Thanks so so much!!!! 👍 👍

@nkolban
Copy link
Owner

nkolban commented Oct 23, 2017

Excellent... that is great news. My tinkering hours on the libraries are evenings and weekends but I'll try and assist as quickly as I can if new issues appear.

@nkolban
Copy link
Owner

nkolban commented Nov 9, 2017

Closing for now. Re-open as needed.

@nkolban nkolban closed this as completed Nov 9, 2017
@venkyyalagala
Copy link

Hai neil, how to enter into AT mode for ESP32 ?? PLEASE HELP

@raghuds
Copy link

raghuds commented Jul 19, 2018

Hi all, I am using ESP32 "BLE Client" and "BLE uart". I can do Scan well and connect, able to read notify data sent from "Server/BLE uart" in "BLE Client". Reverse way I want to read data in "BLE uart" from "BLE Client" to "BLE Server".
I am expecting to read below data sending in BLE Client,
String newValue = "Time since boot: " + String(millis()/1000);
Serial.println("Setting new characteristic value to "" + newValue + """);

// Set the characteristic's value to be the array of bytes that is actually a string.
pRemoteCharacteristic->writeValue(newValue.c_str(), newValue.length());

The above data sending on every second, how can I read it from the "Server/BLE uart", I am getting no callbacks to,

class MyCallbacks: public BLECharacteristicCallbacks {

void onRead(BLECharacteristic *pCharacteristic) {
    Serial.println("Test01");
  
}

void onWrite(BLECharacteristic *pCharacteristic) {
    Serial.println("Test01");

}

@chegewara
Copy link
Collaborator

How client code looks like to send that data?

@raghuds
Copy link

raghuds commented Jul 19, 2018

/**

  • 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");

#define SERVICE_UUID "6E400001-B5A3-F393-E0A9-E50E24DCCA9E" // UART service UUID
#define CHARACTERISTIC_UUID_RX "6E400002-B5A3-F393-E0A9-E50E24DCCA9E"
#define CHARACTERISTIC_UUID_TX "6E400003-B5A3-F393-E0A9-E50E24DCCA9E"

static BLEAddress pServerAddress;
static boolean doConnect = false;
static boolean connected = false;
static BLERemoteCharacteristic
pRemoteCharacteristic;

BLEClient* pClient;
BLERemoteService* pRemoteService;
std::string value;

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("The Recieved value was: ");

// Serial.println(value.c_str());
for(int i=0; i<length; i++){
Serial.print(char(pData[i]));
}

Serial.println();

}

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

// BLEClient* pClient = BLEDevice::createClient();
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);
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.
value = pRemoteCharacteristic->readValue();
Serial.print("The characteristic value was: ");
Serial.println(value.c_str());

const uint8_t v[]={0x1,0x0};
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());
      // Serial.print("BLE Advertised Device Name: ");
      // Serial.println(advertisedDevice.getName().c_str());

      if(advertisedDevice.getName() == "BLE01"){
      Serial.println("My Device Found");
      advertisedDevice.getScan()->stop();

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

} // onResult
}; // MyAdvertisedDeviceCallbacks

void setup() {
Serial.begin(9600);
Serial.println("Starting Arduino BLE Client application...");
BLEDevice::init("NEC_BLE_CLIENT");

// 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() {

  Serial.print(".");

// 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 + """);

// 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

@raghuds
Copy link

raghuds commented Jul 19, 2018

Hi chegewara, I am using the same "BLE CLient" in the BLE examples of ESP32

@chegewara
Copy link
Collaborator

Ok, but if your server device is esp32 with BLE_uart example code, then you have to write to characteristic with this UUID:
CHARACTERISTIC_UUID_RX.

This part of code is useless for you:

// 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");

@raghuds
Copy link

raghuds commented Jul 19, 2018

Hi chegewara, thank you for figure out my fault. Now I am getting call back to here
void onRead(BLECharacteristic *pCharacteristic) {
Serial.println("Test01");
std::string value = pCharacteristic->getValue();

  if (value.length() > 0) {
    Serial.print("Read : ");
    for (int i = 0; i < value.length(); i++)
    {
      Serial.print(value[i]);
    }

    Serial.println();
  }
    
}

After "Test01", nothing is printing. Am doing write here to read value in "BLE uart".

@chegewara
Copy link
Collaborator

This should be onWrite, not onRead:

void onRead(BLECharacteristic *pCharacteristic) {
Serial.println("Test01");
std::string value = pCharacteristic->getValue();

  if (value.length() > 0) {
    Serial.print("Read : ");
    for (int i = 0; i < value.length(); i++)
    {
      Serial.print(value[i]);
    }

    Serial.println();
  }
    
}

@raghuds
Copy link

raghuds commented Jul 19, 2018

I have both onRead() and onWrite()

class MyCallbacks: public BLECharacteristicCallbacks {

void onRead(BLECharacteristic *pCharacteristic) {
    Serial.println("Test01");
  std::string value = pCharacteristic->getValue();

  if (value.length() > 0) {
    Serial.print("Read : ");
    for (int i = 0; i < value.length(); i++)
    {
      Serial.print(value[i]);
    }

    Serial.println();
  }
    
}

void onWrite(BLECharacteristic *pCharacteristic) {
    Serial.println("Test02");
  std::string value = pCharacteristic->getValue();

  if (value.length() > 0) {
    Serial.print("Recieved : ");
    for (int i = 0; i < value.length(); i++)
    {
      Serial.print(value[i]);
      readVal[i] = value[i];
    }

    Serial.println();
    
  }

}
};

Not calling onWrite();, The same "BLE uart" when I tried with Android BLE Scanner app its calling onWrite() only but not now. Why this issue?

@chegewara
Copy link
Collaborator

I dont really know, you have 2 apps and hard to say why its not working.
Try to use nRF connect on android device. You can do 2 things:

  • connect nRF connect to BLE_uart and send some data,
  • clone esp32 on android device (not hard if you know what to do) and test your client code.

@raghuds
Copy link

raghuds commented Jul 19, 2018

Hi I am always getting this,
My Device Found
.Forming a connection to 24:0a:c4:82:7a:ca

  • Created client
  • Connected to server
    abort() was called at PC 0x40183bb3 on core 1

Backtrace: 0x40092dbc:0x3ffd5a30 0x40092fbf:0x3ffd5a50 0x40183bb3:0x3ffd5a70 0x40183bfa:0x3ffd5a90 0x4017166f:0x3ffd5ab0 0x400d2e91:0x3ffd5ad0 0x400d2f9b:0x3ffd5b30 0x400d1592:0x3ffd5b80 0x400d17ca:0x3ffd5bd0 0x4018b770:0x3ffd5c30

Rebooting...
⸮�r⸮���1⸮�B⸮⸮⸮:��!y⸮�⸮⸮⸮�⸮�1⸮8⸮⸮Starting Arduino BLE Client application...
BLE Advertised Device found: Name: , Address: 23:7d:74:a8:f0:24, manufacturer data: 06000109200080a0e54a773cc3c591faffe203546b34ed9bf836dc9868
BLE Advertised Device found: Name: , Address: 38:9b:a2:6f:d8:c3, manufacturer data: 060001092000c16dfd021e6bbd242438315ca1cce63fcbb490adb753d8
BLE Advertised Device found: Name: , Address: 3f:9f:aa:ed:fa:60, manufacturer data: 060001092000f1e851948925d72828b875edadf5212cc33d518286de45
BLE Advertised Device found: Name: , Address: 0d:f1:aa:28:a0:e1, manufacturer data: 0600010920000141e8c2bc0cacb6572b1ea7e89766649786cbb93a1d9b
BLE Advertised Device found: Name: , Address: 2b:c0:0c:2e:d8:d8, manufacturer data: 060001092002003661633914801e2257ce53caf3d8334acf4adb329c27
BLE Advertised Device found: Name: NEC_BLE01, Address: 24:0a:c4:82:7a:ca, txPower: -21
My Device Found
.Forming a connection to 24:0a:c4:82:7a:ca

  • Created client
  • Connected to server
  • Found our service
  • Found our characteristic
    The characteristic value was:
    Guru Meditation Error: Core 1 panic'ed (LoadProhibited). Exception was unhandled.
    Core 1 register dump:
    PC : 0x400d41c3 PS : 0x00060730 A0 : 0x800d163d A1 : 0x3ffd5b50
    A2 : 0x00000000 A3 : 0x3ffd5b92 A4 : 0x00000002 A5 : 0x00000001
    A6 : 0x3ffe8bd0 A7 : 0x3f015bd0 A8 : 0x800d381d A9 : 0x3ffd5b00
    A10 : 0x3ffd5b4c A11 : 0xf35487c4 A12 : 0x3ffc7e6c A13 : 0xf35487c4
    A14 : 0x3ffd5b00 A15 : 0x00016e40 SAR : 0x00000008 EXCCAUSE: 0x0000001c
    EXCVADDR: 0x00000030 LBEG : 0x4000c2e0 LEND : 0x4000c2f6 LCOUNT : 0x00000000

Backtrace: 0x400d41c3:0x3ffd5b50 0x400d163a:0x3ffd5b80 0x400d17ca:0x3ffd5bd0 0x4018b770:0x3ffd5c30

Rebooting...

Why its happening

@raghuds
Copy link

raghuds commented Jul 19, 2018

Hi I got it, the problem occurs because of this,

const uint8_t v[]={0x1,0x0};
pRemoteCharacteristic->registerForNotify(notifyCallback);
pRemoteCharacteristic->getDescriptor(BLEUUID((uint16_t)0x2902))->writeValue((uint8_t*)v,2,true);

instead of this,

pRemoteCharacteristic->registerForNotify(notifyCallback);

I made this change to get the callbacks to "notifyCallback" on every notify from server. without adding above 2 lines I won't getting calback's on notify data from server.
If add above 2 lines device will always reeboot and data will not receive at the server sending as
pRemoteCharacteristic->writeValue(newValue.c_str(), newValue.length());

@raghuds
Copy link

raghuds commented Jul 19, 2018

Please tell me write way to get the callbacks in BLE Client for every notify from Server
Thank you

@chegewara
Copy link
Collaborator

Im guessing You are trying to write to descriptor to wrong characteristic (this characteristic does not have descriptor 2902):
pRemoteCharacteristic->getDescriptor(BLEUUID((uint16_t)0x2902))->writeValue((uint8_t*)v,2,true);

@raghuds
Copy link

raghuds commented Jul 19, 2018

Hi,
what characteristics I have to write?

I am using below UUID's at server
#define SERVICE_UUID "6E400001-B5A3-F393-E0A9-E50E24DCCA9E"
#define CHARACTERISTIC_UUID_RX "6E400002-B5A3-F393-E0A9-E50E24DCCA9E"
#define CHARACTERISTIC_UUID_TX "6E400003-B5A3-F393-E0A9-E50E24DCCA9E"

@chegewara
Copy link
Collaborator

The same you have set with NOTIFY flag in BLE_uart code.

@raghuds
Copy link

raghuds commented Jul 19, 2018

Hi chegewara, I have not understood what you are trying to say. Can you please brief
I am doing notify in Server like this,

char valuetosend[8];
("Live " + String(Cnt)).toCharArray(valuetosend, ("Live " + String(Cnt)).length()+2);
pCharacteristic->setValue(valuetosend);
pCharacteristic->notify(); // Send the value to the app!

@ThingEngineer
Copy link

I came across this issue while looking for a full client UART example. This was close but fell short on the client sending data back to the server. If anyone else ends up here looking for the same thing this is my solution, built on Niel's BLE_client example.

https://github.com/ThingEngineer/ESP32_BLE_client_uart

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

9 participants