RSSI:接受信号强度指示
Rss = 10lgP
只需要将接受到的信号功率P带入上式就是信号强度
如果P=1mW则
10lg(1mW/1mW)= 10lg1 = 0dbm
如果P=40W则
10lg(40W/1mW) = 10log40000 = 10log4 + 10log10 + 10log1000 = 46dbm
当设备连上手机后,设备可以通过rssi来一定程度判断设备和手机的距离
相关api函数
[in]conn_handle : 当前连接句柄
[in]threshold_dbm: 阈值单位是dbm,当rssi与上一次收到的rssi差值大于等于
这个阈值时就会 产生BLE_GAP_EVT_RSSI_CHANGED 事件
当他等于BLE_GAP_RSSI_THRESHOLD_INVALID时
BLE_GAP_EVT_RSSI_CHANGED事件将被关闭不会产生
[in]skip_count: 连续skip_count次超过threshold_dbm阈值产生
BLE_GAP_EVT_RSSI_CHANGED 事件,相当于一个消除抖动作用
sd_ble_gap_rssi_start(uint16_t conn_handle,
uint8_t threshold_dbm,
uint8_t skip_count));
sd_ble_gap_rssi_stop(uint16_t conn_handle));
[out] *p_rssi 就是rssi
sd_ble_gap_rssi_get(uint16_t conn_handle, int8_t *p_rssi));
下面用来实现两种方式
第一种不使用阈值和事件的方式: 即直接启动,然后在定时器中断中调用函数主动获取
部分代码:
static void on_ble_evt(ble_evt_t * p_ble_evt)
{
uint32_t err_code;
int8_t rssi;
switch (p_ble_evt->header.evt_id)
{
case BLE_GAP_EVT_CONNECTED:
err_code = bsp_indication_set(BSP_INDICATE_CONNECTED);
APP_ERROR_CHECK(err_code);
m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
//连接上手机则rssi start,并打开定时器
sd_ble_gap_rssi_start(m_conn_handle,0,0);
err_code = app_timer_start(m_rssi_timer_id,APP_TIMER_TICKS(1000,APP_TIMER_PRESCALER), NULL);
APP_ERROR_CHECK(err_code);
break;
case BLE_GAP_EVT_DISCONNECTED:
err_code = bsp_indication_set(BSP_INDICATE_IDLE);
APP_ERROR_CHECK(err_code);
//断开实际连接则rssi stop,并关闭定时器
sd_ble_gap_rssi_stop(m_conn_handle);
err_code = app_timer_stop(m_rssi_timer_id);
m_conn_handle = BLE_CONN_HANDLE_INVALID;
break;
case BLE_GAP_EVT_SEC_PARAMS_REQUEST:
// Pairing not supported
err_code = sd_ble_gap_sec_params_reply(m_conn_handle, BLE_GAP_SEC_STATUS_PAIRING_NOT_SUPP, NULL, NULL);
APP_ERROR_CHECK(err_code);
break;
default:
// No implementation needed.
break;
}
}
下面是定时器中断函数
void rssi_timeout_handler(void *p_context)
{
uint32_t err_code;
int8_t rssi;
uint8_t value[2];
sd_ble_gap_rssi_get(m_conn_handle, &rssi);
printf("rssi: %d\r\n",rssi);//串口打印rssi
value[0]=rssi;
err_code = ble_nus_string_send(&m_nus,value, 1);
if ((err_code != NRF_SUCCESS) &&
(err_code != NRF_ERROR_INVALID_STATE) &&
(err_code != BLE_ERROR_GATTS_SYS_ATTR_MISSING)
)
{
APP_ERROR_HANDLER(err_code);
}
}
下面是串口打印
UART Start!
rssi: -46
rssi: -45
rssi: -45
rssi: -44
rssi: -48
rssi: -58
rssi: -58
rssi: -57
rssi: -45
rssi: -59
rssi: -54
rssi: -55
rssi: -54
rssi: -53
rssi: -54
rssi: -53
第二种用事件加上阈值消抖
部分函数如下:
static void on_ble_evt(ble_evt_t * p_ble_evt)
{
uint32_t err_code;
int8_t rssi;
switch (p_ble_evt->header.evt_id)
{
case BLE_GAP_EVT_CONNECTED:
err_code = bsp_indication_set(BSP_INDICATE_CONNECTED);
APP_ERROR_CHECK(err_code);
m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
sd_ble_gap_rssi_start(m_conn_handle,0,0);
err_code = app_timer_start(m_rssi_timer_id,APP_TIMER_TICKS(1000,APP_TIMER_PRESCALER), NULL);
APP_ERROR_CHECK(err_code);
break;
case BLE_GAP_EVT_DISCONNECTED:
err_code = bsp_indication_set(BSP_INDICATE_IDLE);
APP_ERROR_CHECK(err_code);
sd_ble_gap_rssi_stop(m_conn_handle);
err_code = app_timer_stop(m_rssi_timer_id);
m_conn_handle = BLE_CONN_HANDLE_INVALID;
break;
case BLE_GAP_EVT_SEC_PARAMS_REQUEST:
// Pairing not supported
err_code = sd_ble_gap_sec_params_reply(m_conn_handle, BLE_GAP_SEC_STATUS_PAIRING_NOT_SUPP, NULL, NULL);
APP_ERROR_CHECK(err_code);
break;
case BLE_GATTS_EVT_SYS_ATTR_MISSING:
// No system attributes have been stored.
err_code = sd_ble_gatts_sys_attr_set(m_conn_handle, NULL, 0, 0);
APP_ERROR_CHECK(err_code);
break;
case BLE_GAP_EVT_RSSI_CHANGED:
sd_ble_gap_rssi_get(m_conn_handle, &rssi);
printf("evt rssi: %d\r\n",rssi);
printf("changed rssi: %d\r\n",p_ble_evt->evt.gap_evt.params.rssi_changed.rssi);
break;
default:
// No implementation needed.
break;
}
}
下面是串口打印
UART Start!
evt rssi: -47
changed rssi: -47
evt rssi: -52
changed rssi: -52
evt rssi: -46
changed rssi: -46
evt rssi: -54
changed rssi: -54
evt rssi: -45
changed rssi: -45
evt rssi: -53
changed rssi: -53
evt rssi: -46
changed rssi: -46
evt rssi: -55
changed rssi: -55
evt rssi: -44
changed rssi: -44
有2个是看有人用p_ble_evt,通过打印发现这个和sd_ble_gap_rssi_get效果一样,看打印信息能看出每2次打印rssi相差是大于等于5的。