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

[nRF52] Best practise for ultra low power SAADC 4 channel conversion

What is the best practise for multichannel SAADC conversion in ultra low power devices? For example I have to measured 4 channel in interval 250ms. Below what I try:

  1. I'm set RTC for interupt 250ms. In RTC handler I initialized SAADC channel 0 and start conversion. In SAADC end of conversion handler i uintialized SAADC, get result from channel 0 and initialized for channel 1 and start conversion. Same for channels 3 and 4 but in channel 4 I'm not start new conversion but Im set RTC for 333ms Handler. I try it and I get strange result.

If I have only one channel I've get current consuption: image description

avarage current is around 10uA ( it's ok for my aplication ). but if I enabled conversion for 4 channel, one by one ( as I descripted above ) I've got something like that: image description

Current is 2 times higher! I don't know why density of the current spikes is in that level.

Mayby I should use PPI? i read this topic: devzone.nordicsemi.com/.../

or maybe different method?

Parents
  • Hi,

    It seems there is some issues with using scan mode when the low-power mode in the SAADC driver is enabled. I will look into this.

    I ported the method used in the saadc_low_power example from SDK 11, and added this to SDK 13 example:

    main.c

    This gives me an average current draw of just over 4 uA.

    Best regards,

    Jørgen

  • Hello Jorgen,

    Was this issue resolved?

    I am having the same issue with a nRF52840 using SDK 15.2 and S140 v6.1.

    I get ~140uA on 256Hz with single channel but it goes up to 740uA with 2 channels and 760uA with 4 channels.

    It seems like something is triggered like the HFCLK causing the baseline current to go high.

  • Hello Jorgen,

    Let me elaborate a little, the code you provided me meets the specs i need but I am trying to not init and un-init the SAADC every time I have to take a sample.

    I believe that once the channels are configured the Easy-DMA never goes to sleep even in low power mode giving a much larger current average than I would like. I wanted to use the non blocking call to store like 1000 values at a stretch with the SAADC connected to the RTC TICK via PPI but the higher current read makes that impossible.

    I could not find anything related to this in the errata, could you please tell me if there is any way of doing that?

  • The DMA current will be present whenever the SAADC is in STARTED state. The driver triggers the START task when the buffer is setup, in order to be ready to sample. There is a low power mode in the driver, that will delay triggering the start task until the sample task is triggered, to reduce the current when no samples are taking place.

    This is not mentioned in the errata, as this is the base current for all DMA operations. It is not considered a bug.

    If you do not want any CPU operations, and you have two RTCs and 4 PPI channels to spare, you can start and sample the SAADC as shown in this diagram:

    If you configure the buffer to take 1000 samples, and make sure you do not start the SAADC when setting up the buffer, this should give you low current consumption. You should configure the second RTC to give you a compare event after each sample interval, to reduce the time between samples as much as possible. With this solution you can take 1000 samples quickly at a regular interval.

  • I have attached the project: saadc_low_power_multichannel_sdk15_3_0.zip

    In that Project, in main.c line 68, I see:

    #define SAADC_SAMPLES_IN_BUFFER 4                 //Number of SAADC samples in RAM before returning a SAADC event. For low power SAADC set this constant to 1. Otherwise the EasyDMA will be enabled for an extended time which consumes high current.
    

    The comment says,

    "For low power SAADC set this constant to 1"

    So, as this is supposed to be specifically a low-power example, why is it set to 4 ?!

  • Another question on that Project:

    In the saadc_callback, nrf_drv_saadc_buffer_convert() is called, and immediately followed by  nrf_drv_saadc_uninit():

            err_code = nrf_drv_saadc_buffer_convert(p_event->data.done.p_buffer, SAADC_SAMPLES_IN_BUFFER);  //Set buffer so the SAADC can write to it again. This is either "buffer 1" or "buffer 2"
            APP_ERROR_CHECK(err_code);
            
            :
            : // UART logging stuff
            :
    
            nrf_drv_saadc_uninit();                                                                   //Unintialize SAADC to disable EasyDMA and save power
            NRF_SAADC->INTENCLR = (SAADC_INTENCLR_END_Clear << SAADC_INTENCLR_END_Pos);               //Disable the SAADC interrupt
            NVIC_ClearPendingIRQ(SAADC_IRQn);                                                         //Clear the SAADC interrupt if set
            m_saadc_initialized = false;  
    doesn't the nrf_drv_saadc_uninit() render the nrf_drv_saadc_buffer_convert() pointless?

  • awneil said:
    So, as this is supposed to be specifically a low-power example, why is it set to 4 ?!

    Because this is a modified version of the single-channel example, with low power support for 4 channels. I did not modify the comments, as this is just a quick modification of the example that I posted in this support case. Setting this to 1 would not make enough space in the buffer to sample all 4 channels.

    awneil said:
    doesn't the nrf_drv_saadc_uninit() render the nrf_drv_saadc_buffer_convert() pointless?

    Yes, it does. It can be removed. Note that this is not production quality code or example, it is simply posted to help customers understand how low power sampling can be achieved with multiple channels enabled.

Reply
  • awneil said:
    So, as this is supposed to be specifically a low-power example, why is it set to 4 ?!

    Because this is a modified version of the single-channel example, with low power support for 4 channels. I did not modify the comments, as this is just a quick modification of the example that I posted in this support case. Setting this to 1 would not make enough space in the buffer to sample all 4 channels.

    awneil said:
    doesn't the nrf_drv_saadc_uninit() render the nrf_drv_saadc_buffer_convert() pointless?

    Yes, it does. It can be removed. Note that this is not production quality code or example, it is simply posted to help customers understand how low power sampling can be achieved with multiple channels enabled.

Children
No Data
Related