The SDK version is 16.0.0. I am using NRF 52840 DK and testing the BLE data transmission with the example project BLE_APP_UART. I am using NRF Connect Desktop to communicate with the NRF52840 DK. The example is working well.
So I started modifying the BLE_APP_UART example and tried to simulate a sensor sending data to the NRF_Connect periodically. I used the APP Timer approach and when the timer causes an interrupt, then the program will call the timeout program and send data with ble_nus_data_send() command. When there is a BLE connection, then the program will start the timer with the function app_timer_start(). When the BLE connection is gone, then the program will stop the timer with the function app_timer_stop. The strange thing is that the program only work for the first time when the NRF connect Desktop connects to the NRF52840 DK via BLE. After the NRF connect desktop disconnects and reconnects, it connects for a brief time and then disconnects. The NRF52840 DK runs into error. What could be the reason? The following are the modified codes:
--------------------------------------
#define SENSOR_MEAS_INTERVAL APP_TIMER_TICKS(300) /* sensor interval */
APP_TIMER_DEF(m_sensor_timer_id); /**< sensor timer id. */
// Sensor timer time out handler
static void sensor_meas_timeout_handler(void * p_context)
{
UNUSED_PARAMETER(p_context);
static uint8_t data_array[BLE_NUS_MAX_DATA_LEN];
uint32_t err_code;
uint16_t length = 4;
static int i=0;
if(m_conn_handle!=BLE_CONN_HANDLE_INVALID)
{
i++;
data_array[0]=i;
data_array[1]=i+1;
data_array[2]=i+2;
data_array[3]=i+3;
err_code = ble_nus_data_send(&m_nus, data_array, &length, m_conn_handle);
if ((err_code != NRF_ERROR_INVALID_STATE) &&
(err_code != NRF_ERROR_RESOURCES) &&
(err_code != NRF_ERROR_NOT_FOUND))
{
APP_ERROR_CHECK(err_code);
// NRF_LOG_INFO("Error code is %d\r\n",err_code);
}
else NRF_LOG_INFO("Sending out data %dth time. connection handle %d\r\n",i,m_conn_handle);
}
}
// Timer initialization
static void timers_init(void)
{
ret_code_t err_code = app_timer_init();
APP_ERROR_CHECK(err_code);
// Create timers.
err_code = app_timer_create(&m_sensor_timer_id,
APP_TIMER_MODE_REPEATED,
sensor_meas_timeout_handler);
APP_ERROR_CHECK(err_code);
}
static void application_timers_start(void)
{
ret_code_t err_code;
// Start application timers.
err_code = app_timer_start(m_sensor_timer_id, SENSOR_MEAS_INTERVAL, NULL);
APP_ERROR_CHECK(err_code);
}
static void application_timers_stop(void)
{
ret_code_t err_code;
err_code=app_timer_stop(m_sensor_timer_id);
APP_ERROR_CHECK(err_code);
}
static void ble_evt_handler(ble_evt_t const * p_ble_evt, void * p_context)
{
uint32_t err_code;
switch (p_ble_evt->header.evt_id)
{
case BLE_GAP_EVT_CONNECTED:
NRF_LOG_INFO("Connected");
printf("\r\nconnected.\r\n");
err_code = bsp_indication_set(BSP_INDICATE_CONNECTED);
APP_ERROR_CHECK(err_code);
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);
nrf_delay_ms(200);
application_timers_start();
break;
case BLE_GAP_EVT_DISCONNECTED:
NRF_LOG_INFO("Disconnected\r\n");
// LED indication will be changed when advertising starts.
m_conn_handle = BLE_CONN_HANDLE_INVALID;
application_timers_stop();
break;
....
}