Как использовать функцию esp_bt_gap_read_rssi_delta, чтобы получить классический RSSI Bluetooth из ESP32?

Классический Bluetooth GAP API в ESP-IDF Framework имеет функцию:

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

со следующим описанием:

"Эта функция вызывается для чтения дельты RSSI по адресу после подключения. Значение RSSI, возвращаемое ESP_BT_GAP_READ_RSSI_DELTA_EVT.

Возврат: ESP_OK: Успех; ESP_FAIL: другие

Параметры: remote_addr: - адрес удаленного устройства, соответствующий определенному дескриптору соединения. "

Хорошо, что я делаю (после подключения к устройству BT): определяю структуру, которая, как мне кажется, будет содержать нужный мне результат:

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

и вызовем функцию:

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

он возвращает err_code = ESP_OK (0, успех), но структура read_rssi_delta содержит только все нули.

Я чувствую, что делаю что-то не так, потому что нужно задействовать еще одну вещь: этот ESP_BT_GAP_READ_RSSI_DELTA_EVT (см. Описание выше). Это определено в перечислении:

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

В одних источниках это называется «событие», в других - «функция обратного вызова», но ничего о том, как ее использовать!

Итак, возникает вопрос: как собрать все это вместе, чтобы получить RSSI с устройства?

Примечание: Bluetooth классический, а не BLE!


person Andrei Douglas    schedule 29.09.2018    source источник
comment
Просто интересно, сдались ли вы или как-то нашли решение?   -  person Jay Marm    schedule 09.02.2019
comment
Я сдался (или сделал вид, что мне все равно: o) ...   -  person Andrei Douglas    schedule 10.02.2019


Ответы (2)


После нескольких попыток я заставил работать esp_bt_gap_read_rssi_delta ().

Первое, что нужно понять (если вы еще не получили его), - это обратный вызов / событие. Функция обратного вызова - это функция в вашем коде, которая будет вызываться ESP-IDF, когда происходит что-то особенное (событие). Вы регистрируете свою функцию обратного вызова, вызывая esp_bt_gap_register_callback () после инициализации стека bluetooth.

Когда вы вызываете esp_bt_gap_read_rssi_delta () (после подключения к устройству), он немедленно возвращается со статусом Ok или ошибкой. Фактическое значение RSSI будет возвращено позже фреймворком, вызывающим вашу функцию обратного вызова.

Функция обратного вызова имеет два параметра. Первая идентифицирует произошедшее событие, вторая - данные, связанные с событием. Этот второй параметр является указателем на одну из структур, определенных в объединении esp_bt_gap_cb_param_t.

Вот некоторый скелетный код (не тестовые коды возврата и т. Д.) Для Arduino IDE, использующий BluetoothSerial для соединения:

#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);
  }
}
person dquadros    schedule 10.04.2019
comment
Да, это работает. Спасибо! Остались и другие проблемы: 1) Чтобы заставить его работать, мне нужно передать MAC-адрес однорангового устройства в функцию esp_bt_gap_read_rssi_delta (addr). В этом есть смысл: чтобы получить RSSI подключения к устройству, нам нужно знать адрес этого устройства, верно? Но что странно: если я передам любой другой случайный адрес, даже 0: 0: 0: 0: 0: 0, значение параметра param- ›read_rssi_delta.stat (чтение статуса rssi) в любом случае будет ESP_BT_STATUS_SUCCESS! Хотя значение дельты RSSI (read_rssi_delta.rssi_delta) реально, только если переданный адрес является фактическим MAC-адресом сопряженного устройства! - person Andrei Douglas; 12.04.2019
comment
2) Другая проблема заключается в самом значении дельты RSSI ^ это нормально, хорошее значение - 0! Это означает, что все, что я получаю RSSI - реальный или неправильный, - сначала я получаю как 0! И единственный способ узнать, является ли RSSI реальным, - это перенести одно устройство от другого или положить что-то (лист фольги в моем случае) между устройствами - тогда только вы можете увидеть, что значение RSSI изменилось - оно падает. до -10, -20 и т. д. Примечание: статус чтения rssi в любом случае обеспечивает тот же ESP_BT_ STATUS_SUCCESS, как я писал выше! - person Andrei Douglas; 12.04.2019
comment
3) Эти две вышеуказанные проблемы на самом деле не являются проблемами, если у вас правильный АДРЕС СОПРЯЖЕННОГО УСТРОЙСТВА. Итак, возникает следующий вопрос: как получить этот MAC-адрес сопряженного устройства? Примечание: не MAC-адрес устройства ESP32, который легко получить с помощью функции esp_bt_dev_get_address (), а адрес УДАЛЕННОГО устройства. . - person Andrei Douglas; 12.04.2019
comment
Вы можете получить MAC-адрес устройства, подключенного к SPP, через событие ESP_SPP_SRV_OPEN_EVT, переданное функции обратного вызова, зарегистрированной BluetoothSerial.register_callback () (у меня нет опыта работы с другими протоколами BT). Как сказано в названии функции, esp_bt_gap_read_rssi_delta выдаст дельты, а не фактическое значение, я тоже считаю это немного ограничивающим, но это лучше, чем полное отсутствие информации. - person dquadros; 15.04.2019
comment
Спасибо, dquadros, за то, что указали мне на класс Bluetooth - вот эта функция! Зная, что я сразу нашел полный пример на techtutorialsx.com/2018/12/11/ Что касается дельт RSSI - означает ли это, что это просто разница между фактическим уровнем RSSI и предыдущим значением RSSI ?! Какой предыдущий тогда? Секунду назад? Минута? При последнем обратном звонке? - person Andrei Douglas; 17.04.2019
comment
Я протестировал свой код RSSI и пришел к выводу: ESP32 возвращает уровень RSSI (наиболее вероятно) в дБм следующим образом: значение от 0 до -20 (ESP_BT_GAP_RSSI_HIGH_THRLD - высокий порог RSSI) означает ХОРОШИЙ сигнал, затем от -20 до -45 (ESP_BT_GAP_RSSI_LOW_THRLD - Низкий порог RSSI) означает силу сигнала от 100% до 0%, пороговое значение ниже -45, при котором соединение обычно прерывается. - person Andrei Douglas; 19.04.2019

Итак, окончательное решение моего вопроса (благодаря @dquadros):

//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....
}
person Andrei Douglas    schedule 19.04.2019