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

power consumption problem

Hi,

I'm using nrf51822 / sd130 / sdk 12.1. I am doing minimizing current consumption. My main function is like below. I checked no wakeup in sleep mode. But, current consumption changes variously. It is wide from ~30uA to 1.5mA. What should I do additionally? I'm trying various condition.

thanks.


while (1)
{
        // fucntion execute


	NRF_CLOCK->TASKS_HFCLKSTART = 0;       // for test
	NRF_CLOCK->TASKS_HFCLKSTOP = 1;        // for test

	NRF_POWER->TASKS_LOWPWR = 1;           // for test
//	NRF_POWER->SYSTEMOFF = 1;              // for test

	// Make sure any pending events are cleared
	__SEV();
	__WFE();
	// Enter System ON sleep mode
	__WFE();

         // watchdog
	nrf_drv_wdt_channel_feed(m_channel_id);	// wdt feed

	NRF_CLOCK->TASKS_HFCLKSTOP = 0;        // for test
	NRF_CLOCK->TASKS_HFCLKSTART = 1;       // for test
   }

watchdog setting

// <1=> Run in SLEEP, Pause in HALT 
// <8=> Pause in SLEEP, Run in HALT 
// <9=> Run in SLEEP and HALT 
// <0=> Pause in SLEEP and HALT 

    #ifndef WDT_CONFIG_BEHAVIOUR
    #define WDT_CONFIG_BEHAVIOUR 8					// 8, mtkim modified, 1 : original
    #endif
  • I'll recheck to turn off all peripherals. Thanks for your reply.

  • *** 1st question *** I use timer1/2 for 2 - PWM. I turn on(POWER = 1) each timer before PWM start(init()) and turn off(POWER = 0) each timer after PWM stop(uninit()). I get current save by doing this. But, Reset occurs after several above PWM action - mainly when PWM1 is called. I use makeSound() to change beep sound level. It’s called by different sound level. I don’t know there is anything wrong. Sure, reset never occurs without using turn on/off.


    ENABLE_TIMER1;

    void makeSound(uint16_t level) // PWM1 { ret_code_t err_code;

    app_pwm_uninit(&PWM_BUZZER);
    app_pwm_config_t pwm1_cfg = APP_PWM_DEFAULT_CONFIG_1CH(level, BUZZER_PIN);
    pwm1_cfg.pin_polarity[0] = APP_PWM_POLARITY_ACTIVE_HIGH;
    
    err_code = app_pwm_init(&PWM_BUZZER, &pwm1_cfg, NULL);
    APP_ERROR_CHECK(err_code);
    app_pwm_enable(&PWM_BUZZER);
    

    }


    *** 2nd question *** I set CLOCK_CONFIG_LF_SRC 0 (RC). This makes current consumption be lower than XTAL setting. Is XTAL setting essential in BLE function environment? Is calibration essential for the exact timing (RTC)? I don’t want calibration for lower current consumption.

    1. "But, Reset occurs after several above PWM action " Does the nRF51 reset? This is a sign of of an error passed to the APP_ERROR_CHECK() macro. See this post about debugging.

    2. To run BLE on NRF51 you will need an external 16 MHz crystal for the HFCLK(HFXO). As LFCLK you can then either use external 32 kHz crystal(LFXO) or interal RC oscillator(LFRC). The LFRC will have a slighlty higher current than the LFXO.

    The TIMER peripheral uses the HFCLK. Using the interal 64 MHz internal oscillator(HFINT) as HFCLK you will have less current consumption, but the accuracy of the HFINT is not good enough to run BLE. The HFXO will have higher current consumption, but it have much better accuracy(ppm) and is needed to run BLE.

  • I use below code for beep sound output. MCU is always in sleep status except these function execution. MCU wakes up by SW input and onSound() is 1st called after wakeup. When using makeSound() I can saw abnormal or reset nrf51. But without using makeSound() it works well. I don't know why. I'll check more.

    Thanks.

    // 1st call for beep sound from main void onSound(uint8_t Num) { // offSound();

    timerBuzzer(STOP, NULL);
    
    BUZZER_USE;
    ENABLE_TIMER1;
    
    if(Num != BEEP_DOOR_ALARM)
    	doorAlarmBeepCnt = 0;						// door open alarm beep cancel
    
    beepOrder = 0;
    beepCnt = beepCntInfo[Num];
    soundNum = Num;
    
    makeSound(beepLevel[soundNum][beepOrder]);
    controlLed(ledInfo[soundNum][beepOrder]);
    timerBuzzer(START, beepTime[soundNum][beepOrder]);			
    

    }

    // for buzzer disable void disableBuzzer(void) { ret_code_t err_code;

    app_pwm_disable(&PWM_BUZZER);
    

    // err_code = app_pwm_end(&PWM_BUZZER); // APP_ERROR_CHECK(err_code); DISABLE_TIMER1;

    nrf_gpio_pin_clear(BUZZER_PIN);
    nrf_gpio_cfg_output(BUZZER_PIN);
    
    BUZZER_NO_USE;
    

    }

    // for beep strength/tone, called by onSound() and buzzer timer handler void makeSound(uint16_t level) { ret_code_t err_code;

    err_code = app_pwm_uninit(&PWM_BUZZER);
    

    // APP_ERROR_CHECK(err_code); // app_pwm_disable(&PWM_BUZZER); app_pwm_config_t pwm1_cfg = APP_PWM_DEFAULT_CONFIG_1CH(level, BUZZER_PIN); pwm1_cfg.pin_polarity[0] = APP_PWM_POLARITY_ACTIVE_HIGH;

    err_code = app_pwm_init(&PWM_BUZZER, &pwm1_cfg, NULL);			// callback_pwmBuz);
    APP_ERROR_CHECK(err_code);
    app_pwm_enable(&PWM_BUZZER);
    
    // sound level check
    

    #if !TEST_SOUND_OFF if(fireStatus) while(app_pwm_channel_duty_set(&PWM_BUZZER, 0, SOUND_MAX) == NRF_ERROR_BUSY); else if(batteryStatusSave == BATTERY_LOW) while(app_pwm_channel_duty_set(&PWM_BUZZER, 0, SOUND_MIN) == NRF_ERROR_BUSY);

    else if(soundLevelTemp == 0)
    	while(app_pwm_channel_duty_set(&PWM_BUZZER, 0, soundLevelInfo[lockInfo.soundLevel]) == NRF_ERROR_BUSY);
    else
    	while(app_pwm_channel_duty_set(&PWM_BUZZER, 0, soundLevelTemp) == NRF_ERROR_BUSY);
    

    #else while(app_pwm_channel_duty_set(&PWM_BUZZER, 0, SOUND_OFF) == NRF_ERROR_BUSY); #endif }

    // buzzer timer handler void handler_buzzer(void * p_context) { UNUSED_PARAMETER(p_context);

    beepOrder++;
    beepCnt--;
    
    if(beepCnt)
    {
    	timerBuzzer(START, beepTime[soundNum][beepOrder]);			
    	makeSound(beepLevel[soundNum][beepOrder]);
    	controlLed(ledInfo[soundNum][beepOrder]);
    }
    else
    {
    	timerBuzzer(STOP, NULL);
    	disableBuzzer();
    	soundLevelTemp = 0;
    

    } }

    // buzzer handler make err_code = app_timer_create(&BUZZER_TIMER_ID, APP_TIMER_MODE_SINGLE_SHOT, handler_buzzer); APP_ERROR_CHECK(err_code);

    // buzzer timer : various period from 10mS ~ 300mS void timerBuzzer(uint8_t type, uint32_t interval) { uint32_t err_code = NRF_SUCCESS;

    if(type == START)
    {
    	err_code = app_timer_stop(BUZZER_TIMER_ID);
    	APP_ERROR_CHECK(err_code);
    	err_code = app_timer_start(BUZZER_TIMER_ID, interval, NULL);
    	APP_ERROR_CHECK(err_code);
    }
    else if(type == STOP)
    {
    	err_code = app_timer_stop(BUZZER_TIMER_ID);
    	APP_ERROR_CHECK(err_code);
    }
    

    }

  • #define DISABLE_TIMER1 {NRF_TIMER1->POWER = 0;} #define DISABLE_TIMER2 {NRF_TIMER2->POWER = 0;} #define ENABLE_TIMER1 {NRF_TIMER1->POWER = 1;} #define ENABLE_TIMER2 {NRF_TIMER2->POWER = 1;}

    I know timer1 enters shutdown mode in app_pwm_disable(&PWM_BUZZER). But, without these definition it consumes current more.

Related