SED drawing too much current after autojoin fails

NCS 2.4.1
nRF52840

My project is a battery powered SED based on the coap_client example.  It is configured to autojoin using a hard coded pksd.  I see on Wireshark that my device sends one Discovery Request when it starts up (if it is not already commissioned).  I am testing a situation where there is no commissioner.  The device should try to join, but then go to sleep after 5 minutes until awakened by the user which will cause a reboot.

I need it to go into a low power mode once the joiner times out.  It does not.  I see on the Power Profiler that the current is ~6mA after 5 minutes.  I tried to change the link mode to set mRxOnWhenIdle to false, but the current remained high.

What is the timeout for joining when using autojoin?

Is it possible to re-try joining multiple times before giving up?

How can I force it to go into a low power sleep? Disable Thread?

prj.conf

# Thread Joiner
CONFIG_OPENTHREAD_JOINER=y
CONFIG_OPENTHREAD_JOINER_AUTOSTART=y
CONFIG_OPENTHREAD_JOINER_PSKD="J01NUS"
CONFIG_OPENTHREAD_MANUAL_START=n

main.c

		int wait = 0;
		while(otDatasetGetActive(instance, &dataset) != OT_ERROR_NONE)
		{
			wait++;
			if (wait < 60)				// 5 sec x 60 = 5 min
			{
    			// wait for joining to complete, blink LED up to 5 minutes

				set_led(COLOR_PURPLE);	// blink purple, 5 sec
				k_msleep(100);
				set_led(COLOR_OFF);
				k_msleep(4900);
			}
			else if (wait > (12 * 60))	// 5 sec x 12 x 60 = 60 min, reboot in an hour
			{
				LOG_INF("Active Dataset not found.  Rebooting\r\n");
				g_reboot = true;
			}
			else 
			{
				otError error;
				otLinkModeConfig mode;
				struct openthread_context *context = openthread_get_default_context();

				__ASSERT_NO_MSG(context != NULL);
				
				openthread_api_mutex_lock(context);
				mode = otThreadGetLinkMode(context->instance);
				if (mode.mRxOnWhenIdle)											// disable receiver
				{
					mode.mRxOnWhenIdle = false;
					error = otThreadSetLinkMode(context->instance, mode);
				}
				openthread_api_mutex_unlock(context);

				k_msleep(5000);
			}

			if (g_reboot)
				k_work_submit(&reboot_work);
		}

Thanks,

Mary

Parents
  • I changed the code to call otPlatRadioSleep() instead of otThreadSetLinkMode() and reduced the current quite a bit.

    		while(otDatasetGetActive(instance, &dataset) != OT_ERROR_NONE)
    		{
    			wait++;
    			if (wait < 60)				// 5 sec x 60 = 5 min
    					{
    #ifdef CONFIG_SERIAL				
    				printk(".");			// wait for joining to complete, blink LED up to 30 seconds
    #endif
    				set_led(COLOR_PURPLE);	// blink purple, 5 sec
    				k_msleep(100);
    				set_led(COLOR_OFF);
    				k_msleep(4900);
    			}
    			else if (wait > (12 * 60))	// 5 sec x 12 x 60 = 60 min, reboot in an hour
    			{
    				LOG_INF("Active Dataset not found.  Rebooting in 2 seconds\r\n");
    				//k_msleep(2000);
    				//NVIC_SystemReset();
    				g_reboot = true;
    			}
    			else 
    			{
    				
    				if (otPlatRadioGetState(instance) != OT_RADIO_STATE_SLEEP)
    					otPlatRadioSleep(instance);
    					
    				// openthread_stop(instance);
    
    				// if (otPlatRadioIsEnabled(instance))
    				// 	otPlatRadioDisable(instance);	
    
    				// otError error;
    				// otLinkModeConfig mode;
    				// struct openthread_context *context = openthread_get_default_context();
    
    				// __ASSERT_NO_MSG(context != NULL);
    				// openthread_api_mutex_lock(context);
    				// mode = otThreadGetLinkMode(context->instance);
    				// if (mode.mRxOnWhenIdle)											// disable receiver
    				// {
    				// 	mode.mRxOnWhenIdle = false;
    				// 	error = otThreadSetLinkMode(context->instance, mode);
    				// }
    				// openthread_api_mutex_unlock(context);
    
    				k_msleep(5000);
    
    			}
    
    			if (g_reboot)
    				k_work_submit(&reboot_work);
    		}

    The current looks like this:

    This looks like some peripheral waking up every ~4ms. Maybe a timer?

    See also this similar issue where I found the suggestion to call otPlatRadioSleep():

    github.com/.../10302

    Mary

  • Hello,

    sorry for the late reply. So you managed to get the current consumption quite a lot down, it seems. What hardware are you running this on? Is that current consumption possible to reproduce on a DK? If so, can you please upload your application here? (or a strip down version of the application that replicates this current pattern).

    It is not an alternative to enter system off when it doesn't find a network? You want it to reboot (and I assume retry joining) every hour?

    Best regards,

    Edvin

  • We are using custom hardware.   Yes, I want it to reboot and retry joining every hour.

    I was not able to reproduce the same current on the DK.

    I modified the coap_client example to autojoin, and added otRadioPlatSleep() after running for 10 seconds.

    After 10 seconds, the current is 2.6 mA.

    Changes to prj.conf

    # Same network Master Key for client and server
    #CONFIG_OPENTHREAD_NETWORKKEY="00:11:22:33:44:55:66:77:88:99:aa:bb:cc:dd:ee:ff"
    
    # Thread Joiner
    CONFIG_OPENTHREAD_JOINER=y
    CONFIG_OPENTHREAD_JOINER_AUTOSTART=y
    CONFIG_OPENTHREAD_JOINER_PSKD="J01NUS"
    CONFIG_OPENTHREAD_MANUAL_START=n
    CONFIG_OPENTHREAD_NETWORKKEY=""

    Code added to coap_client.c

    int main(void)
    {
    	int ret;
    
    	LOG_INF("Start CoAP-client sample");
    
    	if (IS_ENABLED(CONFIG_RAM_POWER_DOWN_LIBRARY)) {
    		power_down_unused_ram();
    	}
    
    	ret = dk_buttons_init(on_button_changed);
    	if (ret) {
    		LOG_ERR("Cannot init buttons (error: %d)", ret);
    		return 0;
    	}
    
    	ret = dk_leds_init();
    	if (ret) {
    		LOG_ERR("Cannot init leds, (error: %d)", ret);
    		return 0;
    	}
    
    #if CONFIG_BT_NUS
    	struct bt_nus_cb nus_clbs = {
    		.received = on_nus_received,
    		.sent = NULL,
    	};
    
    	ret = ble_utils_init(&nus_clbs, on_ble_connect, on_ble_disconnect);
    	if (ret) {
    		LOG_ERR("Cannot init BLE utilities");
    		return 0;
    	}
    
    #endif /* CONFIG_BT_NUS */
    
    	coap_client_utils_init(on_ot_connect, on_ot_disconnect, on_mtd_mode_toggle);
    
    	// My Test: added the next two lines
    	k_msleep(10000);		
    	otPlatRadioSleep(openthread_get_default_instance());
    
    	return 0;
    }
    

    Mary

  • Mary said:
    I was not able to reproduce the same current on the DK.

    What does that mean? The current consumption on the DK is lower? Does that mean that you may have some other components on your custom PCB that is drawing more power?

    Best regards,

    Edvin

Reply Children
  • My custom board:

    • once it joins a network successfully and is commissioned, draws ~13 uA on average
    • If it does not join a network, then calls otPlatRadioSleep() draws ~590 uA (see PPK2 plot above)

    nRF52840DK

    • If it does not join a network, then calls otPlatRadioSleep() draws 2.6 mA (see PPK2 plot above)

    Mary

  • 1: Did you cut the solder bridge SB 40 on the DK before doing measurements?

    Is this current consumption only related to the autojoin feature? 

    At this point, I am not sure what those spikes on your custom board are coming from, and I don't know how to, or if it is possible to reproduce them on a DK, or if it is some component on your custom board drawing these current spikes.

    Best regards,

    Edvin

Related