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

nRF51 ADC example confusion

I'm using the ble_app_hrs_adc_battery_measurement example ADC code in my project

However, I don't understand what these lines do

github.com/.../main.c

As far as I can tell, the while loop seems to call nrf_drv_adc_sample() for the number of samples that are required in the buffer

However, nrf_drv_adc_sample() is no blocking, but there is while() loop

while((NRF_ADC->BUSY & ADC_BUSY_BUSY_Msk) == ADC_BUSY_BUSY_Busy) {}   //Wait until the ADC is finished sampling

Which appears to make the code be blocking.

Looking at the adc complete callback, it only gets called once per call to adc_sample()

Not for all 6 calls.

Can someone explain why this is ?

Edit. I initially had a problems because I was not using the App Scheduler to call the adc_sample()

I now understand that the ADC code will only run in the main context and the App Scheduler is required to effective mode the call to adc_sample to the main loop

I would still be interested in understanding about why the code appears to use blocking.

  • Hi,

    It is not possible to start the sampling task if the ADC is busy. This loop is just added to not start the task until the ADC is available. In the implementation of nrf_drv_adc_sample(), there is an assert that checks that the ADC is not busy before starting the task. The call to nrf_drv_adc_sample() is not blocking in itself, but calling it while the ADC is busy will cause the assert to fire. You could remove this while loop to do other tasks while the sampling is performed, and start the next sample at a later stage. Notice that a check whether the ADC is busy would still be needed before calling nrf_drv_adc_sample(), to avoid firing the assert.

    Best regards,

    Jørgen

  • Thanks Jørgen

    Are you saying that elsewhere in my code I would need to keep checking if the ADC is busy (from time to time)?

    Ideally, when each ADC conversion was complete, a callback would be called, and the callback could thencall nrf_drv_adc_sample().

    However, as far as I can tell, the call to nrf_drv_adc_buffer_convert(adc_buffer, ADC_BUFFER_SIZE); seems to change the mode of operation, so that the callback only occurs when the ADC has completely filled the buffer.

    Perhaps the more efficient way to do this, is set the buffer size to 1, so that perhaps the callback is called after each sample. Then in the callback, store the sample in a buffer and if the buffer is not full, then call nrf_drv_adc_sample() again.

    But I know that some ADC drv funcs can only be called from the main tread, so perhaps this is not possible.

  • You only need to check if the ADC is busy before calling nrf_drv_adc_sample(). The best solution depends on what you are using the ADC for. Often a combination of a timer and a PPI task triggering the sampling, as described in the ADC driver documentaion of the SDK, is a good solution.

  • Can you clarify.

    If ADC_BUFFER_SIZE = 6 and I do this (much code omitted)

    nrf_drv_adc_init(&adc_config, adc_event_handler); //Initialize the ADC
    
    nrf_drv_adc_buffer_convert(adc_buffer, ADC_BUFFER_SIZE);
    
    nrf_drv_adc_sample(); 
    

    Does adc_event_handler get called when the ADC has finished sampling, or does nrf_drv_adc_sample() need to be called for 6 times (in this case), before adc_event_handler gets called ?

    Looking at the example code, it looks like adc_event_handler does not get called until adc_buffer is full, which requires multiple calls to nrf_drv_adc_sample

    Thanks

    Roger

  • From the documentation: If more than one channel is enabled, the function emulates scanning, and a single START task will trigger conversion on all enabled channels. For example: If 3 channels are enabled and the user requests 6 samples, the completion event handler will be called after 2 START tasks. If you want the done event to be called for each sample, you should set the buffer to 1. The point of the buffer is to limit the number of times you have to handle the data.

Related