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

power consumption increases 1.1mA after first ADC sample

Hello,

I am experiencing a power issue after the first ADC sample is triggered. Sampling 2 ADC channels using PPI and TIMER as the triggering mechanism. Here is a capture using PPK2.

It is alright to have a spike in power but in this case, once the power increases it never decreases.

Is there a way to fix this?

TIA

Parents
  • Hello,

    I know this was marked at verified, but I still have a problem. Init is called at the beginning of the program. When the ADC channel is init'ed, The power goes up about .5mA. After the first sample is taken, the current goes up another 1.5mA. The code below should not use DMA. I can not find an option to disable EASY_DMA for the ADC. The lowest power consumption is when the ADC is only enabled long enough to take a sample. Would SAADC_API_V2 help address this issue? 3.5mA is too high for our battery powered application. Enabling and disabling the ADC with each sample is causing other electrical issues.

    #define SAADC_CONFIG_RESOLUTION 3
    
    #define SAADC_CONFIG_LP_MODE 1
    


    static void saadc_sample_init() { ENABLE_TEMP_OUTPUT(); // Setup for double buffer, continuous sampling nrf_drv_saadc_config_t cfg = NRF_DRV_SAADC_DEFAULT_CONFIG; ret_code_t err_code = NRF_SUCCESS; err_code = nrf_drv_saadc_init(&cfg, saadc_callback); APP_ERROR_CHECK(err_code); // battery_init() - configure the SAADC interface nrf_saadc_channel_config_t vbatt_channel_config = NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(ADC_VBATT_AIN); err_code = nrf_drv_saadc_channel_init(BATTERY_ADC_CHANNEL, &vbatt_channel_config); APP_ERROR_CHECK(err_code); // lmt70_init() - configure temperature ADC channel nrf_saadc_channel_config_t temp_channel_config = NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(ADC_TEMPOUT_AIN); err_code = nrf_drv_saadc_channel_init(TEMPERATURE_ADC_CHANNEL, &temp_channel_config); APP_ERROR_CHECK(err_code);

        ret_code_t err_code = app_timer_start(sample_timer_id, ADC_SAMPLE_TIMEOUT, NULL);
        APP_ERROR_CHECK(err_code);
    
    } 
    static void sample_timer_handler(void * p_context)
    {
        app_sched_event_put(NULL, 0, sample_timer_task);
    }
    
    static void sample_timer_task(void * data, uint16_t len)
    {
        UNUSED_PARAMETER(data);
        UNUSED_PARAMETER(len);
    
        // Sample all channels
        nrf_drv_saadc_buffer_convert(m_buffer_pool[m_samples], NUM_ADC_CHANNELS);
        nrf_drv_saadc_sample(); // trigger sample
    
    }
    


Reply
  • Hello,

    I know this was marked at verified, but I still have a problem. Init is called at the beginning of the program. When the ADC channel is init'ed, The power goes up about .5mA. After the first sample is taken, the current goes up another 1.5mA. The code below should not use DMA. I can not find an option to disable EASY_DMA for the ADC. The lowest power consumption is when the ADC is only enabled long enough to take a sample. Would SAADC_API_V2 help address this issue? 3.5mA is too high for our battery powered application. Enabling and disabling the ADC with each sample is causing other electrical issues.

    #define SAADC_CONFIG_RESOLUTION 3
    
    #define SAADC_CONFIG_LP_MODE 1
    


    static void saadc_sample_init() { ENABLE_TEMP_OUTPUT(); // Setup for double buffer, continuous sampling nrf_drv_saadc_config_t cfg = NRF_DRV_SAADC_DEFAULT_CONFIG; ret_code_t err_code = NRF_SUCCESS; err_code = nrf_drv_saadc_init(&cfg, saadc_callback); APP_ERROR_CHECK(err_code); // battery_init() - configure the SAADC interface nrf_saadc_channel_config_t vbatt_channel_config = NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(ADC_VBATT_AIN); err_code = nrf_drv_saadc_channel_init(BATTERY_ADC_CHANNEL, &vbatt_channel_config); APP_ERROR_CHECK(err_code); // lmt70_init() - configure temperature ADC channel nrf_saadc_channel_config_t temp_channel_config = NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(ADC_TEMPOUT_AIN); err_code = nrf_drv_saadc_channel_init(TEMPERATURE_ADC_CHANNEL, &temp_channel_config); APP_ERROR_CHECK(err_code);

        ret_code_t err_code = app_timer_start(sample_timer_id, ADC_SAMPLE_TIMEOUT, NULL);
        APP_ERROR_CHECK(err_code);
    
    } 
    static void sample_timer_handler(void * p_context)
    {
        app_sched_event_put(NULL, 0, sample_timer_task);
    }
    
    static void sample_timer_task(void * data, uint16_t len)
    {
        UNUSED_PARAMETER(data);
        UNUSED_PARAMETER(len);
    
        // Sample all channels
        nrf_drv_saadc_buffer_convert(m_buffer_pool[m_samples], NUM_ADC_CHANNELS);
        nrf_drv_saadc_sample(); // trigger sample
    
    }
    


Children
  • Hi,

    It is not possible to disable EasyDMA in the SAADC peripheral. Even with the buffer size set to a single sample, EasyDMA will be used to store the sample directly in RAM. ~0.5mA sounds like the current from the HFCLK running, while 1.5mA could be the EasyDMA current.

    Have you defined NUM_ADC_CHANNELS to 2?

    Your base current looks very high, even with the SAADC running. Are you running at 3.0V supply? Are you using the DCDC regulator, or just LDO?

    Could you share the full project for us to reproduce and debug the current consumption?

    Best regards,
    Jørgen

  • Hello Jørgen,

    Yes, NUM_ADC_CHANNELS is defined as 2.

    This is custom hardware. Besides the 52832 module, then is a NAND, ECG ADC, Accelerometer and LM70 temperature sensor. The DCDC regulator feature is enabled. I could provide a schematic if necessary.

    I would be happy to share the project. However without the hardware it probably will not be of much use. 1.4mA at 4V is the lowest operating power I have been able to achieve. This is only possible if the SAADC is init/sample/uninit. Is the SAADC the only peripheral that would require HFCLK? We are using SPI and I2C as well.

    There is a secondary issue where the power profile is very noisy from power-on. However it is clean when the application is started using the debugger. (all the graphs above are debugger starts) Can you think of anything  in the start sequence would be different when debug mode is enabled?

  • Allen said:
    I would be happy to share the project. However without the hardware it probably will not be of much use.

    Are you not able to reproduce the increased current consumption on a nRF52 DK?

    Allen said:
    1.4mA at 4V is the lowest operating power I have been able to achieve. This is only possible if the SAADC is init/sample/uninit.

    I assume then that the high current is caused by the other peripherals on your board? The SAADC should be able to get down to the "few uA average" range with multiple channels (dependent on the sample rate).

    Allen said:
    Is the SAADC the only peripheral that would require HFCLK?

    Many peripherals requires HFCLK, including SAADC, TIMERs, RADIO, UART, SPI, TWI, I2S, PWM, etc. The difference between the SAADC and most other peripherals is that it will have high current consumption once it is started, not just when transmitting/operating. Peripherals like SPI and TWI starts a transfer that will finish quite quickly, which will give high current consumption during the transfer, but not when transfer is done. Other peripherals with high current consumption over a long period of time is UART started in RX mode, which requires the HFCLK (and EasyDMA if UARTE is used) to be running, as you do not know when data is incoming. Similar for the SAADC, you do not know when the sample task will be triggered through PPI, so you need to be ready at all times.

    Allen said:
    There is a secondary issue where the power profile is very noisy from power-on. However it is clean when the application is started using the debugger.

    Which PPK version are you using? If using PPK2, are you measuring in Source or Ampere meter mode? There may be some noise from the USB, but I would expect this to be the same for debug and non-debug modes.

    Allen said:
    Can you think of anything  in the start sequence would be different when debug mode is enabled?

    Debug mode will enable clock source and low latency mode in order to quickly halt CPU, etc. I do not see how this could remove any noises from the power capture though.

Related