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的。