一.Default Test
- Compile and program the application. Observe that LED 1 is on. This indicates that the application is advertising.
- Connect to the device from nRF Connect (the device is advertising as 'Nordic_Blinky').
- Observe that LED 2 is on and LED 1 is off. This indicates that the connections is established.
- Observe that the services are shown in the connected device and that you can enable services for the Button Characteristic by clicking the 'Play' button.
- Notifications are received on the Button Characteristic (0x1524) when pressing or releasing Button 1.
- Write '01' to the LED Characteristic (0x1525) and observe that LED 3 is turned on.
- Write '00' to the LED Characteristic (0x1525) and observe that LED 3 is turned off.
二.修改程序
1.修改广播名字
在main.c
#define DEVICE_NAME "Nordic_Blinky" /**< Name of device. Will be included in the advertising data. */
默认是“Nordic Binky”,可以这里改
2.修改广播间隔
在main.c
#define APP_ADV_INTERVAL 64 /**< The advertising interval (in units of 0.625 ms; this value corresponds to 40 ms). */
虽然设置是40ms,但是手机端看到的不是固定值40ms,而是在40~50ms之间动态变化,原因是防止多链接(1对多)冲突.
3.修改Button Characteristic行为(设备发数据给手机)
3.1官方程序Button Characteristic以及如何实现
3.1.1Button Characteristic: 当按下设备Button1,手机端收到"Button Pressed"提示,放开则显示"Button Release"
3.1.2代码实现
在main.c
(1)button1 定义
#define LEDBUTTON_BUTTON BSP_BUTTON_0 /**< Button that will trigger the notification event with the LED Button Service */
(2)button 初始化
/**@brief Function for initializing the button handler module.
*/
static void buttons_init(void)
{
ret_code_t err_code;
//The array must be static because a pointer to it will be saved in the button handler module.
static app_button_cfg_t buttons[] =
{
{LEDBUTTON_BUTTON, false, BUTTON_PULL, button_event_handler}
};
err_code = app_button_init(buttons, ARRAY_SIZE(buttons),
BUTTON_DETECTION_DELAY);
APP_ERROR_CHECK(err_code);
}
(3)button_event_handler
按下button触发中断回调函数,实现button characteristic
/**@brief Function for handling events from the button handler module.
*
* @param[in] pin_no The pin that the event applies to.
* @param[in] button_action The button action (press/release).
*/
static void button_event_handler(uint8_t pin_no, uint8_t button_action)
{
ret_code_t err_code;
switch (pin_no)
{
case LEDBUTTON_BUTTON:
NRF_LOG_INFO("Send button state change.");
err_code = ble_lbs_on_button_change(m_conn_handle, &m_lbs, 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)
{
APP_ERROR_CHECK(err_code);
}
break;
default:
APP_ERROR_HANDLER(pin_no);
break;
}
}
(4)ble_lbs_on_button_change \components\ble\ble_services\ble_lbs\ble_lbs.c
uint32_t ble_lbs_on_button_change(uint16_t conn_handle, ble_lbs_t * p_lbs, uint8_t button_state)
{
ble_gatts_hvx_params_t params;
uint16_t len = sizeof(button_state);
memset(¶ms, 0, sizeof(params));
params.type = BLE_GATT_HVX_NOTIFICATION;
params.handle = p_lbs->button_char_handles.value_handle; //characteristic value
params.p_data = &button_state;
params.p_len = &len;
return sd_ble_gatts_hvx(conn_handle, ¶ms);
}
#endif // NRF_MODULE_ENABLED(BLE_LBS)
3.1.3增加button charateristic: 按下button2 手机端收到8
(1)
#define LEDBUTTON_BUTTON1 BSP_BUTTON_1 /**< Button that will trigger the notification event with the LED Button Service */
(2)
/**@brief Function for initializing the button handler module.
*/
static void buttons_init(void)
{
ret_code_t err_code;
//The array must be static because a pointer to it will be saved in the button handler module.
static app_button_cfg_t buttons[] =
{
{LEDBUTTON_BUTTON, false, BUTTON_PULL, button_event_handler},
{LEDBUTTON_BUTTON1, false, BUTTON_PULL, button_event_handler} //added by 20201217
};
err_code = app_button_init(buttons, ARRAY_SIZE(buttons),
BUTTON_DETECTION_DELAY);
APP_ERROR_CHECK(err_code);
}
(3)
static void button_event_handler(uint8_t pin_no, uint8_t button_action)
{
ret_code_t err_code;
switch (pin_no)
{
case LEDBUTTON_BUTTON:
NRF_LOG_INFO("Send button state change.");
err_code = ble_lbs_on_button_change(m_conn_handle, &m_lbs, 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)
{
APP_ERROR_CHECK(err_code);
}
break;
//added by 20201217
case LEDBUTTON_BUTTON1:
NRF_LOG_INFO("Send button2 value.");
err_code = ble_button2_send(m_conn_handle, &m_lbs, 8);
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)
{
APP_ERROR_CHECK(err_code);
}
break;
default:
APP_ERROR_HANDLER(pin_no);
break;
}
(4)ble_lbs_button2_send //Ble_lbs.c
//added by 20201217
uint32_t ble_lbs_button2_send(uint16_t conn_handle, ble_lbs_t * p_lbs, uint8_t value)
{
ble_gatts_hvx_params_t params;
uint16_t len = sizeof(value);
memset(¶ms, 0, sizeof(params));
params.type = BLE_GATT_HVX_NOTIFICATION;
params.handle = p_lbs->button_char_handles.value_handle;
params.p_data = &value;
params.p_len = &len;
return sd_ble_gatts_hvx(conn_handle, ¶ms);
}
(5)Ble_lbs.h
//added by 20201217
uint32_t ble_lbs_button2_send(uint16_t conn_handle, ble_lbs_t * p_lbs, uint8_t value);
4.修改LED charateristic(手机发给设备)
4.1官网LED charteristic及代码实现
当设备advertising时,LED1常亮,当手机连接设备时,LED2常亮,手机发“ON””OFF“控制LED3 ”亮“”灭“.
4.2代码实现
4.2.1
#define ADVERTISING_LED BSP_BOARD_LED_0 /**< Is on when device is advertising. */
#define CONNECTED_LED BSP_BOARD_LED_1 /**< Is on when device has connected. */
#define LEDBUTTON_LED BSP_BOARD_LED_2 /**< LED to be toggled with the help of the LED Button Service. */
4.2.2 leds_init
/**@brief Function for the LEDs initialization.
*
* @details Initializes all LEDs used by the application.
*/
static void leds_init(void)
{
bsp_board_init(BSP_INIT_LEDS);
}
\components\boards\boards.c
void bsp_board_init(uint32_t init_flags)
{
#if defined(BOARDS_WITH_USB_DFU_TRIGGER) && defined(BOARD_PCA10059)
(void) nrf_dfu_trigger_usb_init();
#endif
#if LEDS_NUMBER > 0
if (init_flags & BSP_INIT_LEDS)
{
bsp_board_leds_init();
}
#endif //LEDS_NUMBER > 0
#if BUTTONS_NUMBER > 0
if (init_flags & BSP_INIT_BUTTONS)
{
bsp_board_buttons_init();
}
#endif //BUTTONS_NUMBER > 0
}
4.2.2 点亮LED1函数bsp_board_led_on
advertising_start广播开始就把设备上的LED1点亮
/**@brief Function for starting advertising.
*/
static void advertising_start(void)
{
ret_code_t err_code;
err_code = sd_ble_gap_adv_start(m_adv_handle, APP_BLE_CONN_CFG_TAG);
APP_ERROR_CHECK(err_code);
bsp_board_led_on(ADVERTISING_LED);
}
4.2.3 BT Connection时LED2点亮,LED1灭
static void ble_evt_handler(ble_evt_t const * p_ble_evt, void * p_context)
{
ret_code_t err_code;
switch (p_ble_evt->header.evt_id)
{
case BLE_GAP_EVT_CONNECTED:
NRF_LOG_INFO("Connected");
bsp_board_led_on(CONNECTED_LED);
bsp_board_led_off(ADVERTISING_LED);
m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
err_code = nrf_ble_qwr_conn_handle_assign(&m_qwr, m_conn_handle);
APP_ERROR_CHECK(err_code);
err_code = app_button_enable();
APP_ERROR_CHECK(err_code);
break;
case BLE_GAP_EVT_DISCONNECTED:
NRF_LOG_INFO("Disconnected");
bsp_board_led_off(CONNECTED_LED);
m_conn_handle = BLE_CONN_HANDLE_INVALID;
err_code = app_button_disable();
APP_ERROR_CHECK(err_code);
advertising_start();
break;
4.2.4 手机控制LED3亮灭
程序流程: services_init -->ble_lbs_init 注册led_write_handler --> ble_lbs_on_ble_evt(BLE stack事件回调函数)->on_write->led_write_handler
(1) 注册 led_write_handler;
/**@brief Function for initializing services that will be used by the application.
*/
static void services_init(void)
{
ret_code_t err_code;
ble_lbs_init_t init = {0};
nrf_ble_qwr_init_t qwr_init = {0};
// Initialize Queued Write Module.
qwr_init.error_handler = nrf_qwr_error_handler;
err_code = nrf_ble_qwr_init(&m_qwr, &qwr_init);
APP_ERROR_CHECK(err_code);
// Initialize LBS.
init.led_write_handler = led_write_handler;
err_code = ble_lbs_init(&m_lbs, &init);
APP_ERROR_CHECK(err_code);
}
(2)ble_lbs_init_t结构体
/** @brief LED Button Service init structure. This structure contains all options and data needed for
* initialization of the service.*/
typedef struct
{
ble_lbs_led_write_handler_t led_write_handler; /**< Event handler to be called when the LED Characteristic is written. */
} ble_lbs_init_t;
(3)ble_lbs_init //components\ble\ble_services\ble_lbs\ble_lbs.c
(4) LBE Write Event //components\ble\ble_services\ble_lbs\ble_lbs.c
/**@brief Function for handling the Write event.
*
* @param[in] p_lbs LED Button Service structure.
* @param[in] p_ble_evt Event received from the BLE stack.
*/
static void on_write(ble_lbs_t * p_lbs, ble_evt_t const * p_ble_evt)
{
ble_gatts_evt_write_t const * p_evt_write = &p_ble_evt->evt.gatts_evt.params.write;
if ( (p_evt_write->handle == p_lbs->led_char_handles.value_handle)
&& (p_evt_write->len == 1)
&& (p_lbs->led_write_handler != NULL))
{
p_lbs->led_write_handler(p_ble_evt->evt.gap_evt.conn_handle, p_lbs, p_evt_write->data[0]);
}
}
void ble_lbs_on_ble_evt(ble_evt_t const * p_ble_evt, void * p_context)
{
ble_lbs_t * p_lbs = (ble_lbs_t *)p_context;
switch (p_ble_evt->header.evt_id)
{
case BLE_GATTS_EVT_WRITE:
on_write(p_lbs, p_ble_evt);
break;
default:
// No implementation needed.
break;
}
}
(5)static void led_write_handler(uint16_t conn_handle, ble_lbs_t * p_lbs, uint8_t led_state)
{
if (led_state)
{
bsp_board_led_on(LEDBUTTON_LED);
NRF_LOG_INFO("Received LED ON!");
}
else
{
bsp_board_led_off(LEDBUTTON_LED);
NRF_LOG_INFO("Received LED OFF!");
}
}
4.3增加LED3点亮程序
static void led_write_handler(uint16_t conn_handle, ble_lbs_t * p_lbs, uint8_t led_state)
{
if (led_state)
{
bsp_board_led_on(LEDBUTTON_LED);
NRF_LOG_INFO("Received LED ON!");
//added by 20201218
bsp_board_led_invert(BSP_BOARD_LED_3);
}
else
{
bsp_board_led_off(LEDBUTTON_LED);
NRF_LOG_INFO("Received LED OFF!");
}
}