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

NRF52832 SAADC not reading ADC Values after pairing with NRFConnect App

Hi all,

My aim is to " read Four ADC Channels data and sent them to nRF Connect bluetooth app".

For doing this i used "saadc " and " ble_app_uart" examples.

Till now I am able to read four adc values before pairing my board(NRF52832) to NRFConnect bluettoth app but after pairing it(NRF52832) with NRFConnect app i am not able to receive ADC

values. Below i attached my program saadc and bluetooth source code.  

Please help me to come out of this problem

void saadc_init(void)
{
ret_code_t err_code;

nrf_drv_saadc_config_t saadc_config = NRF_DRV_SAADC_DEFAULT_CONFIG;
saadc_config.resolution = NRF_SAADC_RESOLUTION_10BIT;

nrf_saadc_channel_config_t channel_0_config =
NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(NRF_SAADC_INPUT_AIN0);
channel_0_config.gain = NRF_SAADC_GAIN1_6;
channel_0_config.reference = NRF_SAADC_REFERENCE_INTERNAL;

nrf_saadc_channel_config_t channel_1_config =
NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(NRF_SAADC_INPUT_AIN1);
channel_1_config.gain = NRF_SAADC_GAIN1_6;
channel_1_config.reference = NRF_SAADC_REFERENCE_INTERNAL;

nrf_saadc_channel_config_t channel_2_config =
NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(NRF_SAADC_INPUT_AIN2);
channel_2_config.gain = NRF_SAADC_GAIN1_6;
channel_2_config.reference = NRF_SAADC_REFERENCE_INTERNAL;

nrf_saadc_channel_config_t channel_3_config =
NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(NRF_SAADC_INPUT_AIN3);
channel_3_config.gain = NRF_SAADC_GAIN1_6;
channel_3_config.reference = NRF_SAADC_REFERENCE_INTERNAL;

err_code = nrf_drv_saadc_init(&saadc_config, saadc_callback);
APP_ERROR_CHECK(err_code);

err_code = nrf_drv_saadc_channel_init(0, &channel_0_config);
APP_ERROR_CHECK(err_code);
err_code = nrf_drv_saadc_channel_init(1, &channel_1_config);
APP_ERROR_CHECK(err_code);
err_code = nrf_drv_saadc_channel_init(2, &channel_2_config);
APP_ERROR_CHECK(err_code);
err_code = nrf_drv_saadc_channel_init(3, &channel_3_config);
APP_ERROR_CHECK(err_code);

err_code = nrf_drv_saadc_buffer_convert(m_buffer_pool[0],SAMPLES_IN_BUFFER);
APP_ERROR_CHECK(err_code);
err_code = nrf_drv_saadc_buffer_convert(m_buffer_pool[1],SAMPLES_IN_BUFFER);
APP_ERROR_CHECK(err_code);

}

void saadc_sampling_event_enable(void)
{
ret_code_t err_code = nrf_drv_ppi_channel_enable(m_ppi_channel);
APP_ERROR_CHECK(err_code);
}


void timer_handler(nrf_timer_event_t event_type, void* p_context)
{
printf("we are in timer_handler \n\r");
}

void saadc_sampling_event_init(void)
{
ret_code_t err_code;

err_code = nrf_drv_ppi_init();
APP_ERROR_CHECK(err_code);

nrf_drv_timer_config_t timer_cfg = NRF_DRV_TIMER_DEFAULT_CONFIG;
timer_cfg.bit_width = NRF_TIMER_BIT_WIDTH_32;
err_code = nrf_drv_timer_init(&m_timer, &timer_cfg, timer_handler);
APP_ERROR_CHECK(err_code);

/* setup m_timer for compare event every 400ms */
uint32_t ticks = nrf_drv_timer_ms_to_ticks(&m_timer, 400); //adc value reading every 400ms
nrf_drv_timer_extended_compare(&m_timer,
NRF_TIMER_CC_CHANNEL0,
ticks,
NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK,
false);
nrf_drv_timer_enable(&m_timer);

uint32_t timer_compare_event_addr = nrf_drv_timer_compare_event_address_get(&m_timer,
NRF_TIMER_CC_CHANNEL0);
uint32_t saadc_sample_task_addr = nrf_drv_saadc_sample_task_get();

/* setup ppi channel so that timer compare event is triggering sample task in SAADC */
err_code = nrf_drv_ppi_channel_alloc(&m_ppi_channel);
APP_ERROR_CHECK(err_code);

err_code = nrf_drv_ppi_channel_assign(m_ppi_channel,
timer_compare_event_addr,
saadc_sample_task_addr);
APP_ERROR_CHECK(err_code);


}


/* ADC CMOS Bateery --------> AIN0
ADC_1_MCU_12V -----------> AIN1
MCU_F_Motor_Limit_SW1 --->AIN2
MCU_H_Motor_Limit_SW1 --->AIN3 */

void saadc_callback(nrf_drv_saadc_evt_t const * p_event)
{
if (p_event->type == NRF_DRV_SAADC_EVT_DONE)
{
ret_code_t err_code;

// err_code = nrf_drv_saadc_buffer_convert(p_event->data.done.p_buffer, SAMPLES_IN_BUFFER); amarr commented
// APP_ERROR_CHECK(err_code);

int i,neg_buffer;
uint8_t percentage_batt_lvl;
char per = '%';

//printf("ADC event number: %d \n\r", (int)m_adc_evt_counter);

for (i = 0; i < SAMPLES_IN_BUFFER; i++)
{
neg_buffer = p_event->data.done.p_buffer[i];

if(neg_buffer > 0)
{
if( i == 0)
{
ADC_CMOS_Battery = p_event->data.done.p_buffer[i];
printf("ADC_CMOS_Battery Channel[%d] = %d \n\r",i, p_event->data.done.p_buffer[i]);
percentage_batt_lvl_CMOS = battery_level_in_percent(ADC_CMOS_Battery);
// printf("ADC_CMOS_Battery percentage = %d%c\r\n",percentage_batt_lvl_CMOS,per);

}
else if(i == 1)
{
ADC_1_MCU_12V = p_event->data.done.p_buffer[i];
printf("ADC_1_MCU_12V Channel[%d] = %d \n\r",i, p_event->data.done.p_buffer[i]);
percentage_batt_lvl_CMOS = battery_level_in_percent(ADC_1_MCU_12V);
//printf("ADC_1_MCU_12V percentage = %d%c\r\n",percentage_batt_lvl_CMOS,per);
}
else if(i == 2)
{
MCU_F_Motor_Limit_SW1 = p_event->data.done.p_buffer[i];
printf("MCU_F_Motor_Limit_SW1 Channel[%d] = %d \n\r",i, p_event->data.done.p_buffer[i]);
}
else
{
MCU_H_Motor_Limit_SW1 = p_event->data.done.p_buffer[i];
printf("MCU_H_Motor_Limit_SW1 Channel[%d] = %d \n\r",i, p_event->data.done.p_buffer[i]);
}
}
else
{
neg_buffer = 0;
printf("ADC channel[%d] = %d \n\r",i,neg_buffer);
}

}
m_adc_evt_counter++;


}
}

Thank you,

Rgds,

amarr

  • Hi

    Can you connect to the example without problems, or is that also problematic?

    I tried embedding your code in the ble_app_uart example, and once I de-commented the call to nrf_drv_saadc_buffer_convert(..) in the SAADC callback I can see it running continuously, and establishing a connection to the DK is no problem. 

    Pairing is not fully supported by the ble_app_uart example, so if you're having issues with pairing and bonding I don't think it is related to the ADC sampling. 

    Best regards
    Torbjørn

  • Hi overbekk.

    Thank you so much for replay.

    Now my source code working continuously after de-commenting nrf_drv_saadc_buffer_convert(..).

    But i want read saadc samples within every 2 seconds, for achieving it. What modification i can do in above source code.

    Please suggest me.

    Thank you,

    Rgds,

    amarr

  • Hi Amarr

    Can you provide a bit more details on what you are trying to do?

    You mean you want to sample continuously, and store the results every 2 seconds?

    Or do you mean you want to only sample for 2 seconds and the stop the sampling?

    You still want to sample every 400ms, or do you need a different sampling frequency?

    What do you want to do with the ADC data after you have read it out from the ADC?

    Best regards
    Torbjørn

  • Hi overbekk,

    Actually i want to sample continuously and use them in every 2 seconds.

    will bluetooth pairing face an issue while i am sampling ADC data continuously?

    Thank you

  • Hi Amarr

    The SAADC is designed to run seamlessly in the background, without interfering with time critical interrupts or radio activity. 

    It uses easyDMA to transfer ADC data to the RAM in parallel with other activity, and the SAADC SDK driver supports double buffering so that you can empty one buffer while the other one is being accessed by the SAADC peripheral. 

    In other words, as long as you scale the buffers according to the sample frequency you require you shouldn't have any problems doing continuous ADC sampling and BLE activity at the same time. 

    Best regards
    Torbjørn

Related