Andrei Douglas
Andrei Douglas

Reputation: 31

How to use esp_bt_gap_read_rssi_delta function to get bluetooth classic RSSI from ESP32?

Classic Bluetooth GAP API in ESP-IDF Framework has a function:

#include "esp_gap_bt_api.h"
esp_err_t esp_bt_gap_read_rssi_delta(esp_bd_addr_t remote_addr)

with the following description:

"This function is called to read RSSI delta by address after connected. The RSSI value returned by ESP_BT_GAP_READ_RSSI_DELTA_EVT.

Return: ESP_OK : Succeed; ESP_FAIL: others

Parameters: remote_addr: - remote device address, corresponding to a certain connection handle."

Ok, what I am doing (after connection to the BT device): define the structure, that I would think, will contain the result I need:

struct read_rssi_delta_param
{
  esp_bd_addr_t bda; /*remote bluetooth device address*/
  esp_bt_status_t stat; /*read rssi status */
  int8_t rssi_delta; /*rssi delta value in range -128 ~127*/
} read_rssi_delta; /*read rssi parameter struct */

and call the function:

esp_err_t err_code = esp_bt_gap_read_rssi_delta((uint8_t*)esp_bt_dev_get_address());

it returns err_code = ESP_OK (0, success) but read_rssi_delta struct contains just all zeros.

I feel I do something wrong because one more thing should be involved: that ESP_BT_GAP_READ_RSSI_DELTA_EVT (see description above). It's defined in a enumeration:

enum esp_bt_gap_cb_event_t //BT GAP callback events.
..... skip some
ESP_BT_GAP_READ_RSSI_DELTA_EVT //read rssi event
..... etc.

In some sources it's called "event", in others - "callback function" but nothing about how to use it!

So, the question is: how to put all this stuff together to get RSSI from the device?

Note: Bluetooth is classic, not BLE!

Upvotes: 2

Views: 2620

Answers (2)

Andrei Douglas
Andrei Douglas

Reputation: 31

So the final solution of my question (thanks to @dquadros) is:

//ESP32, Classic Bluetooth, SPP
#include "BluetoothSerial.h"
#include "esp_gap_bt_api.h"
#include <esp_spp_api.h>

BluetoothSerial SerialBT;
byte rssi; //RSSI
byte addr[6] = {0,0,0,0,0,0}; //to keep MAC address of the remote device

//RSSI callback function
void gap_callback (esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *param)
{
  if (event == ESP_BT_GAP_READ_RSSI_DELTA_EVT) rssi = param->read_rssi_delta.rssi_delta;
}

//SPP service callback function (to get remote MAC address)
void spp_callback (esp_spp_cb_event_t event, esp_spp_cb_param_t *param)
{
  if (event == ESP_SPP_SRV_OPEN_EVT) memcpy(addr, param->srv_open.rem_bda, 6);
}

void setup()
{
  Serial.begin(9600);
  SerialBT.begin("ESP32");
  //register RSSI callback function:
  esp_bt_gap_register_callback (gap_callback);
  //register SPP service callback to get remote address:
  SerialBT.register_callback(spp_callback);
}

void loop()
{
  //when we need RSSI call this:
  esp_bt_gap_read_rssi_delta (addr); //now variable rssi contains RSSI level
  byte b = rssi; //etc....
}

Upvotes: 1

dquadros
dquadros

Reputation: 43

After a few tries I got esp_bt_gap_read_rssi_delta() to work.

First thing to understand (in case you have not got it yet) is the callback/event thing. A callback function is a function in your code that will be called by the ESP-IDF when something special (an event) happens. You register your callback function by calling esp_bt_gap_register_callback() after initializing the bluetooth stack.

When you call esp_bt_gap_read_rssi_delta() (after connecting to the device), it returns immediately with an Ok or error status. The actual RSSI reading will be returned later by the framework calling your callback function.

The callback function has two parameters. The first identifies the event that happened, the second the data associated to the event. This second parameter is a pointer to one of the structures defined in the esp_bt_gap_cb_param_t union.

Here is some skeleton code (not testing return codes, etc) for the Arduino IDE, using the BluetoothSerial for the connection:

#include "esp_gap_bt_api.h"
#include "BluetoothSerial.h"

BluetoothSerial SerialBT;
byte addr[6] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };

void setup() {
  Serial.begin (115200);
  SerialBT.begin();
  esp_bt_gap_register_callback (gap_callback);
}

void loop() {
  delay(100);
  if (SerialBT.hasClient()) {
    esp_bt_gap_read_rssi_delta (addr);
    delay (10000);    
  }
}

void gap_callback (esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *param) {
  if (event == ESP_BT_GAP_READ_RSSI_DELTA_EVT) {
    Serial.println (param->read_rssi_delta.rssi_delta);
  }
}

Upvotes: 1

Related Questions