~30uA and ~24uA current peaks in SYSTEM ON with BLE connection

Hello everyone. I am developing a peripheral device capable of connecting to a central device. The device consumes 1.6uA on connection, but there are different current peaks where the highest peaks are 30uA and 20uA every 8 seconds approximately.

Is it normal? is it due to the refresh mode of the DCDC regulator? if there is some way to eliminate this rare (rare for me) peak I woul like to know it.

I am working with:

  1. NRF52832
  2. SDK 16.0
  3. ble_app_template example

regards.

  • Hi,

    How are you measuring this? I ask because he peak currents you describe seem too low, and also a idle consumption of 1.6uA is a bit too low.

    That said, the Bluetooth examples calibrate the LFRC oscillator clock every 8 seconds, so if that is used, it is expected that you see a peak then (though in reality it would be higher but very short).

    Is it normal? is it due to the refresh mode of the DCDC regulator?

    No, this does not sound like the refresh mode. That will happen more frequently (depending on how you measure you may not be able to properly see the refresh mode peaks).


  • How are you measuring this? I ask because he peak currents you describe seem too low, and also a idle consumption of 1.6uA is a bit too low.

    I am using a simple voltimeter, I don't have oscilloscope or the PPK :( . I made the test in two different multimeters, in the one of them the lowest medition is 1.6 uA, in the other the lowest medition is 2.6 uA. I dont have an accurate graph of the current consumtion.

    the Bluetooth examples calibrate the LFRC oscillator clock every 8 seconds, so if that is used, it is expected that you see a peak then (though in reality it would be higher but very short).

     I made the follow configuration of the LFCLKSRC register:

    #define CLOCK_LFCLKSRC_SRC_Xtal (1UL) /*!< 32.768 kHz crystal oscillator */

    #define CLOCK_LFCLKSRC_SRC_Pos (0UL) /*!< Position of SRC field. */

       NRF_CLOCK->LFCLKSRC =CLOCK_LFCLKSRC_SRC_Xtal<<CLOCK_LFCLKSRC_SRC_Pos;

        NRF_CLOCK->TASKS_LFCLKSTART = 1;

        while(NRF_CLOCK->EVENTS_LFCLKSTARTED == 0);

  • eudaldo said:
    I am using a simple voltimeter, I don't have oscilloscope or the PPK :( . I made the test in two different multimeters, in the one of them the lowest medition is 1.6 uA, in the other the lowest medition is 2.6 uA.

    I see. You will not be able to see the peak currents with a multi meter, as they are way to short. An idle current consumption of about 2.6 uA (in system on with the LFCLK and RTC0 running) is a sensible value, though. 

    eudaldo said:
     I made the follow configuration of the LFCLKSRC register:

    You write that you are using BLE right? If so, the SoftDevice will configure the LFCLK so this has no effect (when you initialize the SoftDevice, it will reconfigure it according to the configuration. Using the SDK examples, that is the  NRF_SDH_CLOCK_* defines in sdk_config.h).

  • sorry for the delat answer , but I able to get a PPK2!!!

    I see. You will not be able to see the peak currents with a multi meter, as they are way to short. An idle current consumption of about 2.6 uA (in system on with the LFCLK and RTC0 running) is a sensible value, though. 

    I got the below information from the PPK2:

    the above, is a normal performant?

    I pass my configuration of the NRF52:

    Definitions:

    #define APP_BLE_OBSERVER_PRIO           3                                       /**< Application's BLE observer priority. You shouldn't need to modify this value. */
    #define APP_BLE_CONN_CFG_TAG            1                                       /**< A tag identifying the SoftDevice BLE configuration. */
    
    #define APP_ADV_INTERVAL                1600                                      /**< The advertising interval (in units of 0.625 ms; this value corresponds to 40 ms). */
    #define APP_ADV_DURATION                BLE_GAP_ADV_TIMEOUT_GENERAL_UNLIMITED   /**< The advertising time-out (in units of seconds). When set to 0, we will never time out. */
    
    
    #define MIN_CONN_INTERVAL               MSEC_TO_UNITS(1100, UNIT_1_25_MS)        /**< Minimum acceptable connection interval (0.5 seconds). */
    #define MAX_CONN_INTERVAL               MSEC_TO_UNITS(1200, UNIT_1_25_MS)        /**< Maximum acceptable connection interval (1 second). */
    #define SLAVE_LATENCY                   0                                       /**< Slave latency. */
    #define CONN_SUP_TIMEOUT                MSEC_TO_UNITS(10000, UNIT_10_MS)         /**< Connection supervisory time-out (4 seconds). */
    
    #define FIRST_CONN_PARAMS_UPDATE_DELAY  APP_TIMER_TICKS(5000)                  /**< Time from initiating event (connect or start of notification) to first time sd_ble_gap_conn_param_update is called (15 seconds). */
    #define NEXT_CONN_PARAMS_UPDATE_DELAY   APP_TIMER_TICKS(30000)                   /**< Time between each call to sd_ble_gap_conn_param_update after the first call (5 seconds). */
    #define MAX_CONN_PARAMS_UPDATE_COUNT    3                                       /**< Number of attempts before giving up the connection parameter negotiation. */
    
    #define DEAD_BEEF                       0xDEADBEEF                              /**< Value used as error code on stack dump, can be used to identify stack location on stack unwind. */

    Advertising functions:

    static void advertising_init(void)
    {
        ret_code_t err_code;   
    
        ble_advertising_init_t init;  // <-- structure Init create on base in ble_advertising_init_t
    
        memset(&init,0,sizeof(init)); //<---delete FROM  ble_advertising_init_t the default paramenter to define own paramenters
    
        init.advdata.name_type            =BLE_ADVDATA_FULL_NAME;   // define the name as full name in advertising data
        init.advdata.include_appearance   =true;          //Determines if Appearance shall be included, in this case, yes
        init.advdata.flags                =BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE; //Advertising data Flags field, LE General Discoverable Mode, BR/EDR not supported.
        init.config.ble_adv_fast_enabled  =true;   // Enable or disable fast advertising mode.
        init.config.ble_adv_fast_interval =APP_ADV_INTERVAL;   //Advertising interval for directed advertising (300)
        init.config.ble_adv_fast_timeout  =APP_ADV_DURATION;  //Time-out (in units of 10ms) for fast advertising, (0), always advesiting
        
        init.config.ble_adv_on_disconnect_disabled = true;  // retunr automatic to the advertising
    
        init.advdata.uuids_complete.uuid_cnt = sizeof(adv_uuids) / sizeof(adv_uuids[0]);
        init.advdata.uuids_complete.p_uuids  = adv_uuids;           
    
        init.evt_handler = on_adv_evt;    // asignamos la funcion handler a la estrucura INIT   
    
    
        //INIT THE ADVERTAISING        (local instance, structure with the settings)
        err_code = ble_advertising_init(&m_advertising, &init);
        APP_ERROR_CHECK(err_code);
        
    
        //Function for changing the connection settings tag that will be used for upcoming connections
        ble_advertising_conn_cfg_tag_set(&m_advertising, APP_BLE_CONN_CFG_TAG);
    
    }
    
    
    static void advertising_start(void)
    {
    
        ret_code_t           err_code;
        err_code = ble_advertising_start(&m_advertising, BLE_ADV_MODE_FAST);
        APP_ERROR_CHECK(err_code);
    
    }

    Connection parameters:

    static void conn_params_init(void)
    {
        ret_code_t             err_code;
        ble_conn_params_init_t cp_init;
    
        memset(&cp_init, 0, sizeof(cp_init));
    
        cp_init.p_conn_params                  = NULL;
        cp_init.first_conn_params_update_delay = FIRST_CONN_PARAMS_UPDATE_DELAY;
        cp_init.next_conn_params_update_delay  = NEXT_CONN_PARAMS_UPDATE_DELAY;
        cp_init.max_conn_params_update_count   = MAX_CONN_PARAMS_UPDATE_COUNT;
        cp_init.start_on_notify_cccd_handle    = BLE_GATT_HANDLE_INVALID;
        cp_init.disconnect_on_fail             = false;
        cp_init.evt_handler                    = on_conn_params_evt;
        cp_init.error_handler                  = conn_params_error_handler;
    
        err_code = ble_conn_params_init(&cp_init);
        APP_ERROR_CHECK(err_code);
    }

    GAP parameters

    //gap parameters
        memset(&gap_conn_params, 0, sizeof(gap_conn_params));
    
        gap_conn_params.min_conn_interval = MIN_CONN_INTERVAL;
        gap_conn_params.max_conn_interval = MAX_CONN_INTERVAL;
        gap_conn_params.slave_latency     = SLAVE_LATENCY;
        gap_conn_params.conn_sup_timeout  = CONN_SUP_TIMEOUT;
    
        err_code = sd_ble_gap_ppcp_set(&gap_conn_params);
        APP_ERROR_CHECK(err_code);
    

    SoftDevice clock source.

    /==========================================================
    // <o> NRF_SDH_CLOCK_LF_SRC  - SoftDevice clock source.
     
    // <0=> NRF_CLOCK_LF_SRC_RC 
    // <1=> NRF_CLOCK_LF_SRC_XTAL 
    // <2=> NRF_CLOCK_LF_SRC_SYNTH 
    
    #ifndef NRF_SDH_CLOCK_LF_SRC
    #define NRF_SDH_CLOCK_LF_SRC 1
    #endif
    
    // <o> NRF_SDH_CLOCK_LF_RC_CTIV - SoftDevice calibration timer interval. 
    #ifndef NRF_SDH_CLOCK_LF_RC_CTIV
    #define NRF_SDH_CLOCK_LF_RC_CTIV 0
    #endif
    
    // <o> NRF_SDH_CLOCK_LF_RC_TEMP_CTIV - SoftDevice calibration timer interval under constant temperature. 
    // <i> How often (in number of calibration intervals) the RC oscillator shall be calibrated
    // <i>  if the temperature has not changed.
    
    #ifndef NRF_SDH_CLOCK_LF_RC_TEMP_CTIV
    #define NRF_SDH_CLOCK_LF_RC_TEMP_CTIV 0
    #endif
    
    // <o> NRF_SDH_CLOCK_LF_ACCURACY  - External clock accuracy used in the LL to compute timing.
     
    // <0=> NRF_CLOCK_LF_ACCURACY_250_PPM 
    // <1=> NRF_CLOCK_LF_ACCURACY_500_PPM 
    // <2=> NRF_CLOCK_LF_ACCURACY_150_PPM 
    // <3=> NRF_CLOCK_LF_ACCURACY_100_PPM 
    // <4=> NRF_CLOCK_LF_ACCURACY_75_PPM 
    // <5=> NRF_CLOCK_LF_ACCURACY_50_PPM 
    // <6=> NRF_CLOCK_LF_ACCURACY_30_PPM 
    // <7=> NRF_CLOCK_LF_ACCURACY_20_PPM 
    // <8=> NRF_CLOCK_LF_ACCURACY_10_PPM 
    // <9=> NRF_CLOCK_LF_ACCURACY_5_PPM 
    // <10=> NRF_CLOCK_LF_ACCURACY_2_PPM 
    // <11=> NRF_CLOCK_LF_ACCURACY_1_PPM 
    
    #ifndef NRF_SDH_CLOCK_LF_ACCURACY
    #define NRF_SDH_CLOCK_LF_ACCURACY 0
    #endif

    Is something wrong?

  • Hi,

    eudaldo said:
    the above, is a normal performant?

    I do not know what the device is doing, but if it is only Bluetooth, then the peaks are too high. Other than that, the time axis is so cramped that it is not possible to see any recognizable waveform so even if I knew what the device was doing it would not be possible to say much about it from this plot.

    If you only use Bluetooth, then the average current consumption here is too high (you can compare with the online power profiler to get ballpark numbers). That could be related to a measurement issue, as as mentioned the peaks in your plot are suspiciously high. So I would be interested in details about your HW, how you have connected it to the PPK2, and how you have configured it / how you are measuring.

Related