nrf52832学习笔记(2)获取rssi信号强度

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

  • 1
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
获取nrf52832设备的2.4G信号强度指示(RSSI),您需要在nrf52832上运行适当的代码并使用BLE协议栈 API。以下是一个示例代码片段,可以在nrf52832获取连接设备的RSSI值: ```c #include <stdbool.h> #include <stdint.h> #include "nrf_delay.h" #include "nrf_log.h" #include "nrf_log_ctrl.h" #include "nrf_sdh.h" #include "nrf_sdh_ble.h" #include "ble.h" #include "ble_gap.h" // 定义一个 ble_gap_evt_handler_t 类型的函数, // 用于处理 GAP (Generic Access Profile) 事件 void ble_gap_evt_handler(ble_gap_evt_t const * p_gap_evt, void * p_context) { switch (p_gap_evt->params.rssi_changed.rssi) { case BLE_GAP_RSSI_INVALID: // RSSI无效 NRF_LOG_INFO("RSSI无效"); break; default: // RSSI有效 NRF_LOG_INFO("RSSI = %d dBm", p_gap_evt->params.rssi_changed.rssi); break; } } // 初始化 BLE Stack static void ble_stack_init(void) { ret_code_t err_code; err_code = nrf_sdh_enable_request(); APP_ERROR_CHECK(err_code); // 等待 SoftDevice 启动 while (nrf_sdh_is_enabled() == false) { // Empty. } // 初始化 BLE Stack err_code = nrf_sdh_ble_default_cfg_set(APP_BLE_CONN_CFG_TAG, &cfg); APP_ERROR_CHECK(err_code); err_code = nrf_sdh_ble_enable(&ram_start); APP_ERROR_CHECK(err_code); } // 初始化 GAP (Generic Access Profile) static void gap_params_init(void) { ret_code_t err_code; ble_gap_conn_params_t gap_conn_params = {0}; ble_gap_conn_sec_mode_t sec_mode; BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode); err_code = sd_ble_gap_device_name_set(&sec_mode, (const uint8_t *) DEVICE_NAME, strlen(DEVICE_NAME)); APP_ERROR_CHECK(err_code); err_code = sd_ble_gap_appearance_set(BLE_APPEARANCE_GENERIC_TAG); APP_ERROR_CHECK(err_code); memset(&gap_conn_params, 0, sizeof(gap_conn_params)); gap_conn_params.min_conn_interval = MIN_CONN_INTERVAL; gap_conn_params.max_conn_interval = MAX_CONN_INTERVAL; gap_conn_params.slave_latency = SLAVE_LATENCY; gap_conn_params.conn_sup_timeout = CONN_SUP_TIMEOUT; err_code = sd_ble_gap_ppcp_set(&gap_conn_params); APP_ERROR_CHECK(err_code); } // 初始化连接参数 static void conn_params_init(void) { ret_code_t err_code; ble_conn_params_init_t conn_params_init; memset(&conn_params_init, 0, sizeof(conn_params_init)); conn_params_init.p_conn_params = NULL; conn_params_init.first_conn_params_update_delay = FIRST_CONN_PARAMS_UPDATE_DELAY; conn_params_init.next_conn_params_update_delay = NEXT_CONN_PARAMS_UPDATE_DELAY; conn_params_init.max_conn_params_update_count = MAX_CONN_PARAMS_UPDATE_COUNT; conn_params_init.start_on_notify_cccd_handle = BLE_GATT_HANDLE_INVALID; conn_params_init.disconnect_on_fail = true; conn_params_init.evt_handler = NULL; conn_params_init.error_handler = NULL; err_code = ble_conn_params_init(&conn_params_init); APP_ERROR_CHECK(err_code); } // 初始化服务 static void services_init(void) { ret_code_t err_code; // 添加服务代码... } // 初始化广播 static void advertising_init(void) { ret_code_t err_code; ble_advertising_init_t init; memset(&init, 0, sizeof(init)); init.advdata.name_type = BLE_ADVDATA_FULL_NAME; init.advdata.include_appearance = true; init.advdata.flags = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE; init.advdata.uuids_complete.uuid_cnt = sizeof(m_adv_uuids) / sizeof(m_adv_uuids[0]); init.advdata.uuids_complete.p_uuids = m_adv_uuids; init.config.ble_adv_fast_enabled = true; init.config.ble_adv_fast_interval = APP_ADV_INTERVAL; init.config.ble_adv_fast_timeout = APP_ADV_DURATION; init.evt_handler = NULL; err_code = ble_advertising_init(&advdata, NULL); APP_ERROR_CHECK(err_code); } int main(void) { // 初始化日志模块 ret_code_t err_code = NRF_LOG_INIT(NULL); APP_ERROR_CHECK(err_code); // 初始化 BLE Stack ble_stack_init(); // 初始化 GAP (Generic Access Profile) gap_params_init(); // 初始化连接参数 conn_params_init(); // 初始化服务 services_init(); // 初始化广播 advertising_init(); // 开始广播 err_code = ble_advertising_start(&m_advertising, BLE_ADV_MODE_FAST); APP_ERROR_CHECK(err_code); // 连接设备并获取 RSSI 值 err_code = sd_ble_gap_rssi_start(m_conn_handle, 5, 0); APP_ERROR_CHECK(err_code); // 进入主循环 while (true) { // 处理 BLE 事件 nrf_ble_qwr_on_ble_evt(&m_qwr, p_ble_evt); ble_conn_params_on_ble_evt(p_ble_evt); ble_advertising_on_ble_evt(p_ble_evt); ble_nus_on_ble_evt(&m_nus, p_ble_evt); on_ble_evt(p_ble_evt); } } ``` 在上面的示例代码中,我们使用 `sd_ble_gap_rssi_start()` 函数来启动 RSSI 读取过程。该函数的第一个参数为连接句柄,第二个参数为 RSSI 读取周期,单位为 100 毫秒。在上面的示例代码中,我们设置周期为 5,即每 500 毫秒读取一次 RSSI。 当 RSSI 值发生变化时,`ble_gap_evt_handler()` 函数将被调用,从而可以获取 RSSI 值。注意,要在应用程序初始化期间注册 `ble_gap_evt_handler()` 以处理 GAP 事件。 希望这可以回答您的问题!
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值