Esp32-snippets: BLE RSSI of connected device

Created on 17 Aug 2019  路  12Comments  路  Source: nkolban/esp32-snippets

Hello,

I'm trying to display the RSSI of any client connected to the ESP32 BLE Server in the Serial Monitor using your BLE_Server Example. This is easily possible while scanning for devices but I can't seem to figure out a way to obtain RSSI after a device is connected, is this possible?

Note: I know this might seem like irrelevant data to want after a device is connected, but I'm trying to use the RSSI to notify the user if they are going out of range of the device, and yes, I do realize finding distance using BLE is very inaccurate but I just want to use it as a measure of being close or far.

Thanks

Most helpful comment

Thank you @chegewara , it works great.
For the noobs like myself, it worked by inserting BLEDevice::setCustomGapHandler(my_gap_event_handler); in void setup()
and declaring the function before void setup()

static void my_gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t* param) {

  Serial.print("RSSI status");Serial.println(param->read_rssi_cmpl.status);
  Serial.print("RSSI ");Serial.println(param->read_rssi_cmpl.rssi);
  Serial.print("Address ");Serial.println(BLEAddress(param->read_rssi_cmpl.remote_addr).toString().c_str());

}
Everytime we have a new event, it prints in serial the 3 informations.

All 12 comments

@Sigmaaaa i should state i have never actually had to deal with this issue, but perhaps are you looking at this backwards?

You state that you want your server to determine if a client is getting out of range, but I believe this is a responsibility of a client. The client adjusted its scan settings to find and made the decision to connected to the server, is it not the clients responsibility to determine range for themselves.

Also, how does the server know what is 'out of range' is for a particular client, perhaps that client's radio is very sensitive and works fine at -90db but another seems spotty at -60.
In that case then perhaps the client can adjust its scanning power and attempt to not connect to weak servers.

Besides not having the info, it seems improper to give the server the responsibility to monitor each and every client that is connected when a client can do this better for themselves.

The more I conciser it the more i believe it is up to the client not server.
Then in that case, the client object has an RSSI value available.
But what do i know....

Here is function for BLEClient:
https://github.com/nkolban/esp32-snippets/blob/master/cpp_utils/BLEClient.cpp#L366-L384
Since its GAP functionality to get RSSI you can easy add function use it in server.

@chegewara OP stated he wanted rssi of clients connected to esp32 server, not the rssi of an esp32 client.
Is that even possible in any way?

Like i said, this is GAP function which means can be used by server of client:
esp_ble_gap_read_rssi
It just needs to be implemented in BLEServer or used like regular C function.

@chegewara do you have an example of how this might look like for Arduino IDE?

As the above comments, I'm not using BLEClient.cpp; ony BLEServer and BLEUtils. I'm gonna have to dig deeper, thanks :D

Thats not a problem. This idf function is gap function and can be used in server or client, you just have to copy it:
https://github.com/nkolban/esp32-snippets/blob/master/cpp_utils/BLEClient.cpp#L376

You can use this code as is (copy/paste) and add to custom gap event handler:

        case ESP_GAP_BLE_READ_RSSI_COMPLETE_EVT: {
            ESP_LOGV(LOG_TAG, "[status: %d, rssi: %d, remote_addr: %s]",
                    param->read_rssi_cmpl.status,
                    param->read_rssi_cmpl.rssi,
                    BLEAddress(param->read_rssi_cmpl.remote_addr).toString().c_str()
            );
            break;

https://github.com/nkolban/esp32-snippets/issues/711#issuecomment-436278247

Thank you @chegewara , it works great.
For the noobs like myself, it worked by inserting BLEDevice::setCustomGapHandler(my_gap_event_handler); in void setup()
and declaring the function before void setup()

static void my_gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t* param) {

  Serial.print("RSSI status");Serial.println(param->read_rssi_cmpl.status);
  Serial.print("RSSI ");Serial.println(param->read_rssi_cmpl.rssi);
  Serial.print("Address ");Serial.println(BLEAddress(param->read_rssi_cmpl.remote_addr).toString().c_str());

}
Everytime we have a new event, it prints in serial the 3 informations.

That's good, @Consistometru, but you need to check the event type. The RSSI info you are printing is only valid when the event type is ESP_GAP_BLE_READ_RSSI_COMPLETE_EVT. That's what @chegewara's "case" statement was all about. Since you don't care about other event types, you can just surround your code with

if (event == ESP_GAP_BLE_READ_RSSI_COMPLETE_EVT) {...}

Was this page helpful?
0 / 5 - 0 ratings

Related issues

minwinmin picture minwinmin  路  9Comments

elloza picture elloza  路  10Comments

jim-ber picture jim-ber  路  8Comments

wegunterjr picture wegunterjr  路  7Comments

mahdikan picture mahdikan  路  4Comments