Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs

Read multiple ADC samples on single channel

Hi,

I'm trying to read the battery voltage of a custom board from the VDDHDIV5  channel. I'm using FreeRTOS in my project. I would like to read trigger the ADC to read 5 samples(non-blocking) once every hour. I tried the below pseudo code to trigger the read but I noticed that only one reading is present in the buffer.

nrf_saadc_value_t raw_value[5] = {0};

void saadc_handler(nrf_drv_saadc_evt_t const * p_event)
{
    if(p_event->type == NRF_DRV_SAADC_EVT_DONE)
    {
        raw_val = *(p_event->data.done.p_buffer);
        test = (raw_val*10/1024);
        
        //Notify saadc_thread
    }

}

void saadc_init()
{
    uint32_t err_code;

    //SAADC peripheral configuration
    nrf_drv_saadc_config_t m_saadc_config = 
    {
        .interrupt_priority = APP_IRQ_PRIORITY_LOW,
        .low_power_mode = false,
        .oversample = NRF_SAADC_OVERSAMPLE_DISABLED,
        .resolution = NRF_SAADC_RESOLUTION_10BIT
    };

    // Channel configuration
    //Internal reference is 0.6V
    nrf_saadc_channel_config_t m_channel_config = NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(NRF_SAADC_INPUT_VDDHDIV5);
    m_channel_config.acq_time = NRF_SAADC_ACQTIME_10US;
    m_channel_config.gain = NRF_SAADC_GAIN1_6;

    err_code = nrf_drv_saadc_init(&m_saadc_config, saadc_handler);
    APP_ERROR_CHECK(err_code);

    err_code = nrf_drv_saadc_channel_init(0, &m_channel_config);
    APP_ERROR_CHECK(err_code);
}

void saadc_sample()
{
    nrf_drv_saadc_buffer_convert(raw_value, 5);
    
    for(uint8_t i=0; i<5; ++i)
        nrf_drv_saadc_sample();
}

static void saadc_thread(void * arg)
{
    // Call saadc_sample and wait for a notification. And then delay for 1 hour
}


I tried two more things and noticed different output

  • The SAADC example in the SDK. The code was running fine and the ADC values were correct.
  • Call saadc_sample in the SAADC handler on NRF_DRV_SAADC_EVT_DONE. The ADC values were correct but this is not a desirable situation as I don't need the SAADC to constantly sample
  • Change the size of raw_value to 1. The ADC value was wrong. I tried this with and without oversampling.

MCU - nRF52833-QDAAA0

SDK - nRF5 SDK 17.1.0

With FreeRTOS

Parents
  • Gowtham,

    Thanks for waiting. Have you tried your application in the debugger mode? 

    It seems like there might be some race conditions in your application causing some deadlock somewhere in your application context. Maybe wrong priorities within other tasks. It is hard to say without knowing all the contexts running in your application. 

    If you do not find any race conditions or deadlocks in your application when you run this in the debug mode. Then please share your project so that I try to find the context which probably is starving other contexts.

  • Hi Susheel,

    I've attached 2 projects.

    1. blink_freertos-adc-test: Based on the blinky_freertos project. I've added a task to sample the SAADC VDDHDIV5 channel. The ADC value read is around 600 when the VDD value is around 4.06V

    2. saadc-pcb-test: Based on the saadc peripheral example. I've changed the channel to VDDHDIV5. The ADC value read is around 230 when the VDD value is around 4.06V.

    Both the projects are based on the nRF5 SDK v17.1.0 and were tested on the same PCB.

    I feel that this seems to be an issue with how the values are read rather than FreeRTOS. 

    blinky_freertos-adc-test.zip
    saadc-pcb-test.zip

  • Hey Vidar,

    Sorry for the delay in replying. I was able to make a recording of this issue. The battery voltage at the time of recording was around 3.97V.  You can notice that the first sample had a value close to the expected value while the next sample onwards it's completely wrong.

  • Hi,

    Do you see the same if you comment the 'raw_value = *(p_event->data.done.p_buffer);' line in your saadc_handler() callback, and does it make any difference if you use the 'Debug' build configuration instead of 'Release'?

  • Hi Vidar,

    I've tried commenting the line you have mentioned and I'm still facing the same issue. I tried the Debug variant and the issue is still seen.

  • Hi Gowtham,

    What I noticed from the video recording you made is that the false readings appear to be left-shifted by 1 (i.e. multiplied by 2), which isn't something I have seen before. I also noticed that you made some changes to the code compared to what you sent me.

  • Hi Vidar,

    I think I made some changes in that project after I had uploaded the project zip here. I downloaded the same zip file I had uploaded and tested it. I can still observe the same issue.

    Can you help me with understanding the difference in the method of using the SAADC between the 2 projects I had uploaded since the saadc-pcb-test.zip project gives the correct values.

    Is this something to do with the usage of tasks?

    I'm ruling out a hardware issue since I'm getting proper values from the saadc-pcb-test project

Reply
  • Hi Vidar,

    I think I made some changes in that project after I had uploaded the project zip here. I downloaded the same zip file I had uploaded and tested it. I can still observe the same issue.

    Can you help me with understanding the difference in the method of using the SAADC between the 2 projects I had uploaded since the saadc-pcb-test.zip project gives the correct values.

    Is this something to do with the usage of tasks?

    I'm ruling out a hardware issue since I'm getting proper values from the saadc-pcb-test project

Children
Related