从机例程目录:
…\nRF5_SDK_15.3.0_59ac345\examples\ble_peripheral\experimental\ble_app_multiperipheral
将例程改为收发多个数据
修改函数
uint32_t ble_nus_init(ble_nus_t * p_nus, ble_nus_init_t const * p_nus_init)
// Add Button characteristic.TX
memset(&add_char_params, 0, sizeof(add_char_params));
add_char_params.uuid = LBS_UUID_BUTTON_CHAR;
add_char_params.uuid_type = p_lbs->uuid_type;
add_char_params.init_len = sizeof(uint8_t);
add_char_params.max_len = BLE_LBS_MAX_DATA_LEN;//sizeof(uint8_t);
add_char_params.is_var_len = true;
add_char_params.char_props.read = 1;
add_char_params.char_props.notify = 1;
add_char_params.char_props.write = 1;
add_char_params.read_access = SEC_OPEN;
add_char_params.cccd_write_access = SEC_OPEN;
err_code = characteristic_add(p_lbs->service_handle,
&add_char_params,
&p_lbs->button_char_handles);
if (err_code != NRF_SUCCESS)
{
return err_code;
}
// Add LED characteristic.RX
memset(&add_char_params, 0, sizeof(add_char_params));
add_char_params.uuid = LBS_UUID_LED_CHAR;
add_char_params.uuid_type = p_lbs->uuid_type;
add_char_params.init_len = sizeof(uint8_t);
add_char_params.is_var_len = true;
add_char_params.max_len = BLE_LBS_MAX_DATA_LEN;//sizeof(uint8_t);
add_char_params.char_props.read = 1;
add_char_params.char_props.write = 1;
add_char_params.read_access = SEC_OPEN;
add_char_params.write_access = SEC_OPEN;
上面在原例程基础上修改了:
按键部分增加write属性:add_char_params.char_props.write = 1;
led和button都增加:
add_char_params.is_var_len = true;//TRUE表示长度可变
led和button都修改:
add_char_params.max_len = BLE_LBS_MAX_DATA_LEN;//最大长度
BLE_LBS_MAX_DATA_LEN我是拷贝的串口例程的宏改了个名字:
/**@brief Maximum length of data (in bytes) that can be transmitted to the peer by the Nordic LBS service module. */
#if defined(NRF_SDH_BLE_GATT_MAX_MTU_SIZE) && (NRF_SDH_BLE_GATT_MAX_MTU_SIZE != 0)
#define BLE_LBS_MAX_DATA_LEN (NRF_SDH_BLE_GATT_MAX_MTU_SIZE - OPCODE_LENGTH - HANDLE_LENGTH)
#else
#define BLE_LBS_MAX_DATA_LEN (BLE_GATT_MTU_SIZE_DEFAULT - OPCODE_LENGTH - HANDLE_LENGTH)
#warning NRF_SDH_BLE_GATT_MAX_MTU_SIZE is not defined.
#endif
add_char_params.max_len不改的话测试收发多个数据会出现
例程中接收的函数类型
typedef void (*ble_lbs_led_write_handler_t) (uint16_t conn_handle, ble_lbs_t * p_lbs, uint8_t new_state);
改成
typedef void (*ble_lbs_led_write_handler_t) (uint16_t conn_handle, ble_lbs_t * p_lbs, uint8_t const* data,uint8_t len);
我构造的发送函数
uint32_t BleSnd(uint16_t conn_handle, ble_lbs_t * p_lbs, uint8_t * p_data, uint16_t len)
{
ble_gatts_hvx_params_t params;
memset(¶ms, 0, sizeof(params));
params.type = BLE_GATT_HVX_NOTIFICATION;
params.handle = p_lbs->button_char_handles.value_handle;
params.p_data = p_data;
params.p_len = &len;
return sd_ble_gatts_hvx(conn_handle, ¶ms);
}
Nordic的按键库写地有个问题
实际由于在app_button_init中
#if defined(BUTTON_HIGH_ACCURACY_ENABLED) && (BUTTON_HIGH_ACCURACY_ENABLED == 1)
nrf_drv_gpiote_in_config_t config = GPIOTE_CONFIG_IN_SENSE_TOGGLE(p_btn->hi_accuracy);
#else
nrf_drv_gpiote_in_config_t config = GPIOTE_CONFIG_IN_SENSE_TOGGLE(false);
#endif
不会按你设置的false触发而是有变化就触发
所以要增加一段
#if defined(BUTTON_HIGH_ACCURACY_ENABLED) && (BUTTON_HIGH_ACCURACY_ENABLED == 1)
nrf_drv_gpiote_in_config_t config = GPIOTE_CONFIG_IN_SENSE_TOGGLE(p_btn->hi_accuracy);
#else
nrf_drv_gpiote_in_config_t config = GPIOTE_CONFIG_IN_SENSE_TOGGLE(false);
#endif
//增加的
if(p_buttons->active_state == false)
config.sense = NRF_GPIOTE_POLARITY_HITOLO;
if(p_buttons->active_state == true)
config.sense = NRF_GPIOTE_POLARITY_LOTOHI;
我实现的是按按键1给第一个连接主机发消息按按键2给第二个连接的主机发消息按按键3发给两个设备
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[] =
{
{BSP_BUTTON_0, false, BUTTON_PULL, button_event_handler},
{BSP_BUTTON_1, false, BUTTON_PULL, button_event_handler},
{BSP_BUTTON_2, false, BUTTON_PULL, button_event_handler},
};
err_code = app_button_init(buttons, ARRAY_SIZE(buttons),
BUTTON_DETECTION_DELAY);
APP_ERROR_CHECK(err_code);
}
static void button_event_handler(uint8_t pin_no, uint8_t button_action)
{
ret_code_t err_code;
static uint8_t buff[10] = {'a','b','c','d',0, 'A','B','C','D',0};
switch (pin_no)
{
case BSP_BUTTON_0:
// err_code = led_status_send_to_all(button_action);
// if (err_code == NRF_SUCCESS)
// {
// NRF_LOG_INFO("Sent button state change to all connected centrals.");
// }
buff[4]++;
err_code = BleSnd(0, &m_lbs, buff, 5);
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);
NRF_LOG_DEBUG("<Err> ... Ble snd on connection handle -0-");
}
if (err_code == NRF_SUCCESS)
{
NRF_LOG_DEBUG("<SUCC> ... Ble snd on connection handle -0-.");
}
break;
case BSP_BUTTON_1:
buff[9]++;
err_code = BleSnd(1, &m_lbs, &buff[5], 5);
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);
NRF_LOG_DEBUG("<Err> ... Ble snd on connection handle -1-");
}
if (err_code == NRF_SUCCESS)
{
NRF_LOG_DEBUG("<SUCC> ... Ble snd on connection handle -1-.");
}
break;
case BSP_BUTTON_2:
err_code = led_status_send_to_all(button_action);
if (err_code == NRF_SUCCESS)
{
NRF_LOG_INFO("Sent button state change to all connected centrals.");
}
break;
default:
APP_ERROR_HANDLER(pin_no);
break;
}
}