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

How to Read 16 bit ADC Value on nRF Master app? not 8 bit!

FormerMember
FormerMember

Hello!

I'm trying to read 16 bit ADC Value on nRF Master app instead of only 8 bit, and I know that there is the example code on github which is only send me the 8 bit "uint8_t adc_result" data to nRF mater app

/* Interrupt handler for ADC data ready event */
void ADC_IRQHandler(void)
{
	uint8_t adc_result;
	
	/* Clear dataready event */
  NRF_ADC->EVENTS_END = 0;	

  /* Write ADC result both to the UART and over BLE */
	adc_result = NRF_ADC->RESULT;
	app_uart_put(adc_result);
	ble_nus_send_string(&m_nus, &adc_result, 1);
	nrf_gpio_pin_toggle(LED_3);        //indicate on LED that the ADC interrupt handler is executing
	
	//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();
}	

where it sends the ADC value over Bluetooth by the "ble_nus_send_string()" command:

uint32_t ble_nus_send_string(ble_nus_t * p_nus, uint8_t * string, uint16_t length)
{
    ble_gatts_hvx_params_t hvx_params;

    if (p_nus == NULL)
    {
        return NRF_ERROR_NULL;
    }
    
    if ((p_nus->conn_handle == BLE_CONN_HANDLE_INVALID) || (!p_nus->is_notification_enabled))
    {
        return NRF_ERROR_INVALID_STATE;
    }
    
    if (length > BLE_NUS_MAX_DATA_LEN)
    {
        return NRF_ERROR_INVALID_PARAM;
    }
    
    memset(&hvx_params, 0, sizeof(hvx_params));

    hvx_params.handle = p_nus->rx_handles.value_handle;
    hvx_params.p_data = string;
    hvx_params.p_len  = &length;
    hvx_params.type   = BLE_GATT_HVX_NOTIFICATION;
    
    return sd_ble_gatts_hvx(p_nus->conn_handle, &hvx_params);
}

if I just similarly change the 'uint8_t adc_result' to 'uint16_t adc_result' it will show me endless ERROR.

Does anyone have any solutions for reading the ADC value on the nRF Mater Control panel app 16 bits instead of only 8 bits?

Any help is appreciated!

  • FormerMember
    0 FormerMember in reply to RK

    But, on the MCP it only received the ADC value as 0xDF (as 8 bit) and it stay unchanged.

  • well you are doing something wrong then, go check your code. Use something other than the MCP, like Lightblue, see what the actual data sent it, Lightblue doesn't try to interpret it. If you are only getting one byte, you are only sending one byte. adc_len must be 2 to send 2 bytes. What is it? Try debugging.

  • FormerMember
    0 FormerMember in reply to RK

    Could you please help me check following of my code?enter code here

  • FormerMember
    0 FormerMember

    ADC_IRQHandler :

    /* Interrupt handler for ADC data ready event */
    void ADC_IRQHandler(void)
    {
       static uint16_t adc_result;
    
        /* Clear dataready event */
      NRF_ADC->EVENTS_END = 0;  
    
      /* Write ADC result both to the UART and over BLE */
        adc_result = NRF_ADC->RESULT;
        app_uart_put(adc_result);
        ble_nus_send_string(&m_nus, &adc_result);
        nrf_gpio_pin_toggle(LED_3);        //indicate on LED that the ADC interrupt handler is executing
    
        //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();
    }
    

    ble_nus_send_string :

    uint32_t ble_nus_send_string(ble_nus_t * p_nus, uint16_t * string)
        {
            ble_gatts_hvx_params_t hvx_params;
        
            if (p_nus == NULL)
            {
                return NRF_ERROR_NULL;
            }
        
            if ((p_nus->conn_handle == BLE_CONN_HANDLE_INVALID) || (!p_nus->is_notification_enabled))
            {
                return NRF_ERROR_INVALID_STATE;
            }
        
            if (length > BLE_NUS_MAX_DATA_LEN)
            {
                return NRF_ERROR_INVALID_PARAM;
            }
        
    static uint16_t adc_len = sizeof(string);
    
            memset(&hvx_params, 0, sizeof(hvx_params));
        
            hvx_params.handle = p_nus->rx_handles.value_handle;
            hvx_params.p_data = (uint8_t*)&string;
            hvx_params.p_len  = &adc_len;
            hvx_params.type   = BLE_GATT_HVX_NOTIFICATION;
        
            return sd_ble_gatts_hvx(p_nus->conn_handle, &hvx_params);
        }
    
  • No that's complete rubbish. You already passed the address of the data into your function, then you're taking the address of it again and sending that. Similarly adc_len is the size of 'string' and string is a pointer to uint16_t so that's 4. So you are now sending 4 bytes which represent the address of the static variable adc_result, which will always be the same.

    sorry but this is basic C. Instead of just guessing around trying random things you need to understand what a pointer is, what a length is and how to convert from one to another.

Related