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

Continuous periodic nRF52840 ADC sampling with Zephyr

Hello, guys.

We are using Zephyr RTOS (NCS v1.4.2) with nRF52840 development kit.

The idea is to have continuous ADC sampling on two ADC channels. So far, I was able to properly initialize the ADC device, and get one single ADC read with the following piece of code:

const struct adc_sequence sequence = {
	.channels = BIT(ADC_1ST_CHANNEL_ID),
	.buffer = m_sample_buffer,
	.buffer_size = sizeof(m_sample_buffer),
	.resolution = ADC_RESOLUTION,
};

ret = adc_read(adc_dev, &sequence);
if (ret) {
    printk("adc_read() failed with code %d\n", ret);
}

There is an issue even with this piece of code because, when I call adc_read(adc_dev, &sequence) function, only the first value of m_sample_buffer is updated, the rest of the m_sample_buffer values remain 0. What I am missing here?

Other than that, is there any way that we configure ADC device to do periodic sampling in the background without our intervention?

Thanks in advance for your time and efforts.

Sincerely,

Bojan.

  • Thanks, Einar.

    Do you have any idea what is the duration of ADC calibration?

    I thought to perform ADC calibration only once, during the initialization phase rather then to do it every time before taking the sample. Does that make sense?

  • Hi Bojan,

    The ADC calibration time depends on the previously configured acquisition time. If not yet configured, the default acquisition time of 10 us is used. The total calibration time is a few microseconds more as it includes conversion.

    Calibration is done to sets the correct offset, so that measuring GND will give a sample value of 0. This will normally not change over time unless the temperature changes. So you should calibrate after reset, and either regularly or when there are temperature changes.

  • This is what I call great support!

    Thank you very much, Einer!

    No more questions concerning ADC converter! :-)

    By the way, I just noticed that this ticket is private. Can we move it to Public area so that the rest of the people can hopefully benefit from it?

    Cheers,

    Bojan.

  • Thank you for the feedback, Bojan. We are happy to help Slight smile I have requested the case to become public but you need to approve it.

    Einar

  • Hello, Einar.

    I am trying to port your unofficial SAADC example into Zephyr environment.

    As a first goal, I wanted to test only adc_configure() function. According to nrfx use example that shows how to use nrfx drivers in Zephyr, I did the following in my prj.config file:

    CONFIG_ADC=n
    CONFIG_ADC_NRFX_SAADC=y

    I also included nrfx_saadc header file  line in my main.cpp file:

    #include <nrfx_saadc.h>

    When I compile the code, the compiler complains about undefined reference to nrfx_saadc_xxx() functions that are all declared in included nrfx_saadc.h file:

    build/../src/main.cpp:187: undefined reference to `nrfx_saadc_channels_config'
    build/../src/main.cpp:190: undefined reference to `nrfx_saadc_advanced_mode_set'
    build/../src/main.cpp:197: undefined reference to `nrfx_saadc_buffer_set'
    build/../src/main.cpp:200: undefined reference to `nrfx_saadc_buffer_set'
    build/../src/main.cpp:203: undefined reference to `nrfx_saadc_mode_trigger'
    

    Do you have any idea what I am missing here? Do I need to include something more in my prj.config file that will disable the usage of Zephyr ADC APIs and encourage the usage of NRFX SAADC driver?

    Thanks in advance for your time and efforts.

    Sincerely,

    Bojan.

Related