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

sending data with ble problem

Hello, I am encountering with problems with sending 20 bytes of data.
My initial code worked using two timer and I successfully displayed it on an android phone but I wanted to power optimize the code resulting with the changes below but with the change the code is able to advertise but not sent data.

What am i doing wrong?

My code was based off of heart rate example.

In main.c

void ADC_IRQHandler(void)
{
	/* Clear dataready event */
  NRF_ADC->EVENTS_END = 0;	

  /* Write ADC result to port 2 */


		adcresult[count] = NRF_ADC->RESULT;
		//Use the STOP task to save current. Workaround for PAN_028 rev1.5 anomaly 1.
  NRF_ADC->TASKS_STOP = 1;
	
	//Release the external crystal
	sd_clock_hfclk_release();

	if(count==19)
	{ 
		
		count =7;
			
	spi_master_init(SPI_MASTER_0, spi_master_0_event_handler, false);
  spi_master_send_recv(SPI_MASTER_0, &reg_x0, 1, m_rx_data_spi, 7);  
	
	
	 	  adcresult[1] =m_rx_data_spi[1];
  		adcresult[2] =m_rx_data_spi[2];
			adcresult[3] =m_rx_data_spi[3];
			adcresult[4] =m_rx_data_spi[4];
			adcresult[5] =m_rx_data_spi[5];
			adcresult[6] =m_rx_data_spi[6];
		
	heart_rate_meas_timeout_handler(p_context);
	
	}
	else
	{
		count++;
	}
	

}	



static void heart_rate_meas_timeout_handler(void * p_context) {

uint32_t        err_code;

UNUSED_PARAMETER(p_context);

    err_code = ble_hrs_heart_rate_measurement_send(&m_hrs, adcresult);

    if ((err_code != NRF_SUCCESS) &&
    (err_code != NRF_ERROR_INVALID_STATE) &&
    (err_code != BLE_ERROR_NO_TX_BUFFERS) &&
    (err_code != BLE_ERROR_GATTS_SYS_ATTR_MISSING)
)
{
    APP_ERROR_HANDLER(err_code);
}


}

This is the send function

uint32_t ble_hrs_heart_rate_measurement_send(ble_hrs_t * p_hrs, uint8_t *adc_result)
{
    uint32_t err_code;

    // Send value if connected and notifying
    if (p_hrs->conn_handle != BLE_CONN_HANDLE_INVALID)
    {
        uint8_t                encoded_hrm[MAX_HRM_LEN];
        uint16_t               len;
        uint16_t               hvx_len;
        ble_gatts_hvx_params_t hvx_params;
				adc_result[0] = 0;

        len     = hrm_encode(p_hrs, adc_result, encoded_hrm);
        hvx_len = 20;

        memset(&hvx_params, 0, sizeof(hvx_params));

        hvx_params.handle = p_hrs->hrm_handles.value_handle;
        hvx_params.type   = BLE_GATT_HVX_NOTIFICATION;
        hvx_params.offset = 0;
        hvx_params.p_len  = &hvx_len;
        hvx_params.p_data = adc_result;

        err_code = sd_ble_gatts_hvx(p_hrs->conn_handle, &hvx_params);
        if ((err_code == NRF_SUCCESS) && (hvx_len != len))
        {
            err_code = NRF_ERROR_DATA_SIZE;
        }
    }
    else
    {
        err_code = NRF_ERROR_INVALID_STATE;
    }

    return err_code;
}
Parents
  • It seems that your tasks are somewhat time consuming. Too heavy-duty task inside an interrupt handler is not recommended, especially with communications stack. You should restructure your program. For example,

    Before:

    void event_handler_a(...)
    {
        TASK_A
    }
    
    void event_handler_b(...)
    {
        TASK_B
    }
    
    void event_handler_c(...)
    {
        TASK_C
    }
    
    int main(void)
    {
        ...
        while (1) {
            power_manage();
        }
    }
    

    After:

    typedef struct {
        bool ready_a;
        bool ready_b;
        bool ready_c;
    } event_flag_t;
    
    event_flag_t evt_flag = { false, false, false };
    
    void event_handler_a(...)
    {
        ESSENTIAL_TASK_A    /* like clearing event and writing adc result... */
        evt_flag.ready_a = true;
    }
    
    void event_handler_b(...)
    {
        ESSENTIAL_TASK_B
        evt_flag.ready_b = true;
    }
    
    void event_handler_c(...)
    {
        ESSENTIAL_TASK_C
        evt_flag.ready_c = true;
    }
    
    int main(void)
    {
        ...
        while (1) {
            if (evt_flag.ready_a) {
                TASK_A
                evt_flag.ready_a = false;
            }
    
            if (evt_flag.ready_b) {
                TASK_B
                evt_flag.ready_b = false;
            }
    
            if (evt_flag.ready_c) {
                TASK_C
                evt_flag.ready_c = false;
            }
    
            power_manage();
        }
    }
    
Reply
  • It seems that your tasks are somewhat time consuming. Too heavy-duty task inside an interrupt handler is not recommended, especially with communications stack. You should restructure your program. For example,

    Before:

    void event_handler_a(...)
    {
        TASK_A
    }
    
    void event_handler_b(...)
    {
        TASK_B
    }
    
    void event_handler_c(...)
    {
        TASK_C
    }
    
    int main(void)
    {
        ...
        while (1) {
            power_manage();
        }
    }
    

    After:

    typedef struct {
        bool ready_a;
        bool ready_b;
        bool ready_c;
    } event_flag_t;
    
    event_flag_t evt_flag = { false, false, false };
    
    void event_handler_a(...)
    {
        ESSENTIAL_TASK_A    /* like clearing event and writing adc result... */
        evt_flag.ready_a = true;
    }
    
    void event_handler_b(...)
    {
        ESSENTIAL_TASK_B
        evt_flag.ready_b = true;
    }
    
    void event_handler_c(...)
    {
        ESSENTIAL_TASK_C
        evt_flag.ready_c = true;
    }
    
    int main(void)
    {
        ...
        while (1) {
            if (evt_flag.ready_a) {
                TASK_A
                evt_flag.ready_a = false;
            }
    
            if (evt_flag.ready_b) {
                TASK_B
                evt_flag.ready_b = false;
            }
    
            if (evt_flag.ready_c) {
                TASK_C
                evt_flag.ready_c = false;
            }
    
            power_manage();
        }
    }
    
Children
No Data
Related