NRF52x属性服务示例

4 篇文章 0 订阅
3 篇文章 0 订阅

本文描述为nrf52810设备添加以下属性服务:

  1. 电池服务
  2. 设备信息服务
  3. 一个触摸按键属性(附加在 uart tx/rx服务中)



开发环境准备

  1. SDK:
    nRF5_SDK_15.3.0_59ac345.zip
  2. 选择工程:
    nRF5_SDK_15.3.0\examples\ble_peripheral\ble_app_uart\pca10040



添加电池服务

  1. 在 sdk_config.h 中 打开宏:
    #define BLE_BAS 1
  1. 在 main.c 找到函数 services_init,添加如下代码:
	ble_bas_init_t     bas_init;
	// Initialize BAS.
    memset(&bas_init, 0, sizeof(bas_init));

    // Here the sec level for the Battery Service can be changed/increased.
    bas_init.bl_cccd_wr_sec = SEC_OPEN;
    bas_init.bl_rd_sec = SEC_OPEN;
    bas_init.bl_report_rd_sec = SEC_OPEN;

    bas_init.evt_handler          = NULL;
    bas_init.support_notification = true;
    bas_init.p_report_ref         = NULL;
    bas_init.initial_batt_level   = 100;

    err_code = ble_bas_init(&m_bas, &bas_init);
    APP_ERROR_CHECK(err_code);
  1. 创建一个app timer 周期性地向客户端播报电池电量:

在ble_bas.c中找到函数:

    ret_code_t ble_bas_battery_level_update(ble_bas_t * p_bas,
                                        uint8_t     battery_level,
                                        uint16_t    conn_handle)

创建 app 周期性任务调度,5秒一次:

   app_timer_create(&task_5s_id, APP_TIMER_MODE_REPEATED, task_5s_timer_handler);
   app_timer_start(task_5s_id, APP_TIMER_TICKS(5000), NULL);//定时5s


   static void task_5s_timer_handler(void *p_context)
   {
	   ble_bas_battery_level_update(&m_bas, bat_level, m_conn_handle);
   }

其中 bat_level 的值是通过ADC测量到的电池曲线,然后转换成电池百分比。



添加设备信息服务

  1. 在 sdk_config.h 中 打开宏,并定义属性服务字段宏:
    #define BLE_DIS 1
    
    //属性服务字段宏
	#define MANUFACTURER_NAME      "XXXXX"
	#define MODEL                  "MMMMM"  
	#define HW_VER                 "HW"     /**< Hardware Revision String. */
	#define FW_VER                 "FW"     /**< Firmware Revision String. */
	#define SW_VER                 "SW"     /**< Software Revision String. */ 
	#define SN                     "SN"	
  1. 在 main.c 函数 services_init 中,添加如下代码:
	// Initialize Device Information Service.
    memset(&dis_init, 0, sizeof(dis_init));

    ble_srv_ascii_to_utf8(&dis_init.manufact_name_str, (char *)MANUFACTURER_NAME);
    ble_srv_ascii_to_utf8(&dis_init.model_num_str, MODEL);
    ble_srv_ascii_to_utf8(&dis_init.serial_num_str, SN);
    ble_srv_ascii_to_utf8(&dis_init.hw_rev_str, HW_VER);
    ble_srv_ascii_to_utf8(&dis_init.fw_rev_str, FW_VER);
    ble_srv_ascii_to_utf8(&dis_init.sw_rev_str, SW_VER);

    dis_init.dis_char_rd_sec = SEC_OPEN;

    err_code = ble_dis_init(&dis_init);
    APP_ERROR_CHECK(err_code);


添加按键通知属性

该属性附加在 uart服务中,由于我的项目是一个触摸片模拟的按键,所以取名 touchpanel 的缩写 TP

  1. 找到uart tx/rx服务对应文件 ble_nus.c,添加如下代码
	/**< The UUID of the TP Characteristic. */
    #define BLE_UUID_NUS_TP_CHARACTERISTIC  0x0005               
  1. 在结构体 struct ble_nus_s 中添加如下成员:
    struct ble_nus_s
    {
        ...
        /**< Handles related to the TP characteristic (as provided by the SoftDevice). */
        ble_gatts_char_handles_t        tp_handles;         
        ...
    };
  1. 在函数 ble_nus_init 中添加如下代码:
    // Add TP characteristic.
    memset(&add_char_params, 0, sizeof(add_char_params));
    add_char_params.uuid              = BLE_UUID_NUS_TP_CHARACTERISTIC;
    add_char_params.uuid_type         = p_nus->uuid_type;
    add_char_params.init_len          = sizeof(uint8_t);
    add_char_params.max_len           = sizeof(uint8_t);
    add_char_params.char_props.read   = 1;
    add_char_params.char_props.notify = 1;//notification 属性

    add_char_params.read_access       = SEC_OPEN;
    add_char_params.cccd_write_access = SEC_OPEN;

    err_code = characteristic_add(
                         p_nus->service_handle, 
                         &add_char_params, 
                         &p_nus->tp_handles);                    

    if (err_code != NRF_SUCCESS) {
        return err_code;
    }
  1. 在 ble_nus.c 中实现如下函数:

	//将按键状态改动通知协议栈
	uint32_t nus_notification_state_change(uint16_t conn_handle, uint16_t handle, uint8_t state)
	{
    	ble_gatts_hvx_params_t params;
    	uint16_t len = sizeof(state);

    	memset(&params, 0, sizeof(params));
    	params.type   = BLE_GATT_HVX_NOTIFICATION;
    	params.handle = handle;
    	params.p_data = &state;
    	params.p_len  = &len;

    	return sd_ble_gatts_hvx(conn_handle, &params);
	}

	#define BUTTON_DETECTION_DELAY   APP_TIMER_TICKS(50)
	#define TP_DET_PIN         25 

	//tp模拟按键事件处理函数
	void button_event_handler(uint8_t pin_no, uint8_t button_action)
	{
    	uint32_t err_code;    

    	if (!is_ble_connect()) {
        	debug_print(
             	"ble disconnect(pin_no=%d,button_action=%d)\r\n", 
             	pin_no, 
             	button_action);
        	return;
    	}

    	switch(pin_no) {
        	case TP_DET_PIN:            
            	err_code = nus_notification_state_change(
                            	m_conn_handle, 
                            	m_nus.tp_handles.value_handle, 
                            	button_action);
            	debug_print("tp button_action=%d \r\n",button_action);
            	if (err_code != NRF_SUCCESS &&
                	err_code != BLE_ERROR_INVALID_CONN_HANDLE &&
                	err_code != NRF_ERROR_INVALID_STATE &&
                	err_code != BLE_ERROR_GATTS_SYS_ATTR_MISSING) {
                	debug_print("tp button_event_handler err_code=%d\r\n",err_code);               
            	} 
            	break;
        	default:
            	debug_print("APP_ERROR_HANDLER(%d)\r\n",pin_no);
            	break;
    	}
	}

	//TP按键初始化
	void tp_button_init() 
	{   
    	uint32_t err_code;
    	static app_button_cfg_t buttons[] = {
        	{TP_DET_PIN, APP_BUTTON_ACTIVE_HIGH, NRF_GPIO_PIN_PULLDOWN, button_event_handler}
    	};
    
    	err_code = app_button_init(buttons,sizeof(buttons)/sizeof(buttons[0]), BUTTON_DETECTION_DELAY);
    	APP_ERROR_CHECK(err_code);
    	app_button_enable();
	}

5.最后在 main函数中调用 tp_button_init



测试工具

可以采用NRF官方提供的测试工具 nRF connect 进行测试,目前最新版本为 v4.19.0,但官方不提供该工具的源码(后面会有文章介绍android客户端<参考nRF Toolbox的源码>实现本文服务及属性的访问 ):

使用方法

  1. 点击 SCANNER 选项卡, 扫描到目标设备,点击 CONNECT选项
  2. 点击已连设备所在的选项卡,然后选择竖着的 三个点 展开菜单,选择 Enable CCCDs 选项
    在这里插入图片描述
  3. 点击属性菜单右边的更新小箭头
  4. 电池服务
    在这里插入图片描述
  5. 设备信息服务
    在这里插入图片描述
  6. 触摸按键属性,手指按住的时候 value 显示 为 (0x)01
    在这里插入图片描述
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值