【问题标题】:How to use esp_bt_gap_read_rssi_delta function to get bluetooth classic RSSI from ESP32?如何使用 esp_bt_gap_read_rssi_delta 函数从 ESP32 获取蓝牙经典 RSSI?
【发布时间】:2018-09-29 21:28:43
【问题描述】:

ESP-IDF 框架中的经典蓝牙 GAP API 有一个功能:

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

带有以下描述:

"连接后调用该函数按地址读取RSSI增量。ESP_BT_GAP_READ_RSSI_DELTA_EVT返回的RSSI值。

返回: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, success) 但 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?

注意:蓝牙是经典的,不是 BLE!

【问题讨论】:

  • 只是好奇你是放弃了还是找到了解决办法?
  • 我放弃了(或者假装我不在乎:o)...

标签: c bluetooth rssi esp32


【解决方案1】:

经过几次尝试,我得到了 esp_bt_gap_read_rssi_delta() 的工作。

首先要了解(如果您还没有得到它)​​是回调/事件的事情。回调函数是代码中的一个函数,当发生特殊事件(事件)时,ESP-IDF 将调用该函数。初始化蓝牙堆栈后调用 esp_bt_gap_register_callback() 注册回调函数。

当您调用 esp_bt_gap_read_rssi_delta() 时(连接到设备后),它会立即返回正常或错误状态。实际的 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);
  }
}

【讨论】:

  • 是的,它有效。谢谢!其他问题仍然存在: 1) 为了使其工作,我需要将对等设备的 MAC 地址传递给 esp_bt_gap_read_rssi_delta (addr) 函数。这是有道理的:要获得连接到设备的 RSSI,我们需要知道该设备的地址,对吧?但奇怪的是:如果我传递任何其他随机地址,即使是 0:0:0:0:0:0,param->read_rssi_delta.stat ("read rssi status") 值在任何情况下都将是 ESP_BT_STATUS_SUCCESS!虽然只有当传递的地址是配对设备的实际 MAC 地址时,RSSI 增量值 (read_rssi_delta.rssi_delta) 才是真实的!
  • 2) 另一个问题在于RSSI delta值本身^它是“正常的”,好的值为0!这意味着我得到的任何 RSSI - 真实或错误,起初我得到的都是 0!判断 RSSI 是否真实的唯一方法是将一个设备从另一个设备带走,或者在设备之间放置一些东西(在我的情况下是箔片) - 然后只有你可以看到 RSSI 值发生了变化 - 它下降了低至 -10、-20 等。注意:“读取 rssi 状态”在任何情况下都与我在上面写的一样重复 ESP_BT_STATUS_SUCCESS!
  • 3) 如果您拥有正确的配对设备地址,上述两个“问题”实际上并不是问题。那么接下来的问题是:如何获取配对设备的这个MAC地址? 注意:不是ESP32设备的MAC地址,用esp_bt_dev_get_address()函数很容易得到,而是REMOTE设备的地址.
  • 可以通过 ESP_SPP_SRV_OPEN_EVT 事件获取 SPP 连接设备的 MAC 地址,并传递给 BluetoothSerial.register_callback() 注册的回调函数(我对其他 BT 协议没有经验)。正如函数名称所说,esp_bt_gap_read_rssi_delta 会给出增量,而不是实际值,我也觉得它有点限制,但总比没有信息要好。
  • 谢谢你,dquadros,你把我指向蓝牙类——这个功能恰好在那里!知道我立即在techtutorialsx.com/2018/12/11/… 上找到了关于 RSSI 增量的完整示例 - 这是否意味着它只是实际 RSSI 水平和之前的 RSSI 值之间的差异?!那之前是哪个?一秒钟前?一分钟?最后回拨电话了吗?
【解决方案2】:

所以我的问题的最终解决方案(感谢@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....
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-01-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-24
    • 2015-03-12
    • 2013-10-31
    相关资源
    最近更新 更多