This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Little problem with send data to BLE

Good afternoon.

I´m using nrf51-dk with SDK 9.0.0, s110 softdevice and uart nordic app on mobile. I have a program in my nrf51-dk that it sends and receives data between nrf51-dk and mobile device.

I want to send a data when mobile device establishes connection with my nrf51-dk, the problem is that the first time that mobile device establishes the connection doesn´t receive "Pulse c para calibra" but when I disconnect and connect again the mobile device with my nrf51-dk, it receives the data correctly.

I have modified "on_ble_evt" function.

static void on_ble_evt(ble_evt_t * p_ble_evt){
    uint32_t                         err_code;
	uint8_t instrucciones[20] =     "Pulse c para calibra";

switch (p_ble_evt->header.evt_id){
    case BLE_GAP_EVT_CONNECTED:
                                conectado = true;
                   				nrf_delay_ms(1500);
        						ble_nus_string_send(&m_nus, instrucciones, 20);
            					app_timer_start(timer_id,  APP_TIMER_TICKS(500, APP_TIMER_PRESCALER), NULL);   //10 segundos para configurar
                                err_code = bsp_indication_set(BSP_INDICATE_CONNECTED);
                                APP_ERROR_CHECK(err_code);
                                m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
                                break;
        
    case BLE_GAP_EVT_DISCONNECTED:
					            conectado = false;
         						temporizador_menu = tiempo_espera_menu;
	            				limpiar_datos_recibidos_bluetooth();
        						app_timer_stop(timer_id);
                                err_code = bsp_indication_set(BSP_INDICATE_IDLE);
                                APP_ERROR_CHECK(err_code);
                                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;

    default:
        // No implementation needed.
        break;
}
}

Screen of data received by mobile device:

image description

Thank you.

  • The information, whether an indication is send to a GATT client (your phone) or not, is stored on the GATT server (nrf51-dk) and is usually edited by the GATT client (subscription). So in your case, you send an indication to the GATT client, before the GATT client subscribed to the characteristic.

    You could see, if you find a way to subscribe the client on the server side (I don’t know the Nordic API). But if this works, you must make sure, that on the client side is some kind of callback that actually receives the (unexpected) data.

    Or you simply change your client to read the instrucciones text without indication.

    The same goes for your attempt to indicate the client, when the connection was just closed. There will be no connection, where the indication could be transported on.

    Maybe you could just finder better times to send the indications.

    Cheers, Torsten

  • I have checked err_code when I send the first time, data "Pulse c para calibra", and I receive "error 8", so i will try you comment me.

    I have changed a bit the code. My program has some steps in wich it waits the client sends "c" to calibrate it and then go to the next step, in case the client loses the connection, when he connects again, he has to receive a data that says in what step he was when he lost the connection. So I only can send it when he connect.

    Javier.

  • You should not send data on the connect event, (unless you are already bonded and HVX is enabled) as the peer hasn't had the chance to subscribe to your indications/notifications by writing to the CCCD. Instead you should wait for HVX to be enabled. Look at e.g. the HRS example. There you can see that HRs has it's own handler that calls on_write when a ble_gatts_evt_write is received. In on write there is a check to see if the cccd was written to, and if it is it's starts to send notifications. If you try to send a notification or indication when it's not enabled sd_ble_gatts_hvx will return NRF_ERROR_INVALID_STATE.

  • you mean to (in ble_hrs.c):

    /**@brief Function for handling the Write event.
    *
    * @param[in]   p_hrs       Heart Rate Service structure.
    * @param[in]   p_ble_evt   Event received from the BLE stack.
    */
    static void on_write(ble_hrs_t * p_hrs, ble_evt_t * p_ble_evt)
    {
    ble_gatts_evt_write_t * p_evt_write = &p_ble_evt->evt.gatts_evt.params.write;
    
    if (p_evt_write->handle == p_hrs->hrm_handles.cccd_handle)
    {
        on_hrm_cccd_write(p_hrs, p_evt_write);
    }
    }
    
    void ble_hrs_on_ble_evt(ble_hrs_t * p_hrs, ble_evt_t * p_ble_evt)
    {
      switch (p_ble_evt->header.evt_id)
      {
     ......
    }
    }
    
  • Yes, in on_write you can see that we check if notifications has been enabled (on_hrm_cccd_write). Once they are you can start sending notifications.

Related