Wake up event of Target Wake Time (TWT) on nRF7002-DK

Hi,

I'm developing an application to send data via UDP. In order to minimize the power consumption of my application, my idea is to send data during the wake time of TWT.

I start by connecting to the AP. To do this, I based myself on the Wi-Fi: Station sample where I get the following output (Image 1) :

  (Image 1 )

After this, I set up the TWT based on the Wi-Fi: TWT sample with the TWT_WAKE_INTERVAL and TWT_INTERVAL set to 20000us and 5000000us, respectively. I'm obtaining the following output (Image 2):

  ( Image 2 )

I was expecting that I would get an event when the wake up time and sleep time started. However, from what we can see in Image 2, it appears that I'm not obtaining any NET_EVENT_WIFI_TWT_SLEEP_STATE event. For this reason, I thought that my TWT application was not working (since there were no active or sleeping events), but after a quick test with the Joulescope JS110, I was able to verify that these events were being generated as we can see in the following image (Image 3) and  the TWT_WAKE_INTERVAL and TWT_INTERVAL are correct (Image 4):

  ( Image 3 )

  ( Image 4 )

At this moment, my wifi_mgmt_event_handler looks like:

static void wifi_mgmt_event_handler(struct net_mgmt_event_callback *cb,
									uint32_t mgmt_event, struct net_if *iface)
{
	switch (mgmt_event)
	{
	case NET_EVENT_WIFI_CONNECT_RESULT:
		LOG_INF(" ========================= NET_EVENT_WIFI_CONNECT_RESULT event ========================= " );
		handle_wifi_connect_result(cb);
		break;
		
	case NET_EVENT_WIFI_DISCONNECT_RESULT:
		LOG_INF(" ========================= NET_EVENT_WIFI_DISCONNECT_RESULT ========================= ");
		handle_wifi_disconnect_result(cb);
		break;

	case NET_EVENT_WIFI_TWT:
		LOG_INF(" ========================= NET_EVENT_WIFI_TWT event ========================= ");
		handle_wifi_twt_event(cb);
		break;

	case NET_EVENT_WIFI_TWT_SLEEP_STATE:
		LOG_INF(" ========================= NET_EVENT_WIFI_TWT_SLEEP_STATE event ========================= ");
		handle_wifi_twt_state_event(cb);
		break;

	default:
		LOG_ERR("(WIFI) Unknown event: %d ", mgmt_event);
		break;
	}
}

My main function looks like:

int main(void)
{
	int i, ret;

	memset(&context, 0, sizeof(context));

	net_mgmt_init_event_callback(&wifi_shell_mgmt_cb,
								 wifi_mgmt_event_handler,
								 WIFI_SHELL_MGMT_EVENTS);

	net_mgmt_add_event_callback(&wifi_shell_mgmt_cb);

	net_mgmt_init_event_callback(&net_shell_mgmt_cb,
								 net_mgmt_event_handler,
								 NET_EVENT_IPV4_DHCP_BOUND);

	net_mgmt_add_event_callback(&net_shell_mgmt_cb);

	LOG_INF("Starting %s with CPU frequency: %d MHz", CONFIG_BOARD, SystemCoreClock / MHZ(1));
	k_sleep(K_SECONDS(1));

	LOG_INF("Static IP address (overridable): %s/%s -> %s",
			CONFIG_NET_CONFIG_MY_IPV4_ADDR,
			CONFIG_NET_CONFIG_MY_IPV4_NETMASK,
			CONFIG_NET_CONFIG_MY_IPV4_GW);

	while (1)
	{

		wifi_connect();

		for (i = 0; i < CONNECTION_TIMEOUT; i++)
		{
			k_sleep(K_MSEC(STATUS_POLLING_MS));
			cmd_wifi_status();
			if (context.connect_result)
			{
				break;
			}
		}

		if (context.connected)
		{
			LOG_INF("============ Connected to wifi ============");
			break;
		}
		else if (!context.connect_result)
		{
			LOG_ERR("Connection Timed Out");
		}

		k_sleep(K_MSEC(300));
	}

	k_sleep(K_SECONDS(2));

	if (!twt_supported)
	{
		LOG_INF("AP is not TWT capable, exiting the sample\n");
		return 1;
	}
	else
	{
		LOG_INF("AP is TWT capable, establishing TWT");
	}

	ret = setup_twt(true);
	if (ret)
	{
		LOG_ERR("Failed to establish TWT flow: %d\n", ret);
		return 1;
	}

	k_sleep(K_FOREVER);

	return 0;
}

And my setup_twt function looks like:

static int setup_twt(bool enable)
{
	struct net_if *iface = net_if_get_default();
	struct wifi_twt_params params = { };
	int ret;

	params.operation = WIFI_TWT_SETUP;
	params.negotiation_type = WIFI_TWT_INDIVIDUAL;
	params.setup_cmd = WIFI_TWT_SETUP_CMD_REQUEST;
	params.dialog_token = 1;
	params.flow_id = 1;
	params.setup.responder = 0;
	params.setup.implicit = 1;
	params.setup.trigger = IS_ENABLED(CONFIG_TWT_TRIGGER_ENABLE);
	params.setup.announce = IS_ENABLED(CONFIG_TWT_ANNOUNCED_MODE);
	params.setup.twt_wake_interval = CONFIG_TWT_WAKE_INTERVAL;
	params.setup.twt_interval = CONFIG_TWT_INTERVAL;

	ret = net_mgmt(NET_REQUEST_WIFI_TWT, iface, &params, sizeof(params));
	if (ret)
	{
		LOG_INF("TWT setup failed: %d", ret);
		return ret;
	}
	else
	{
		LOG_INF("TWT setup requested");
	}

	return 0;
}

What I want to know is:

  • What am I doing wrong in the wake up and sleep events detection (in order to send data via UDP during the wake time)?
  • How can I fix the problem?

P.S.:

Sometimes looks like the TWT is not set (Image 5):

Thanks a lot! 

Parents
  • Hi,

     

    What am I doing wrong in the wake up and sleep events detection (in order to send data via UDP during the wake time)?

    I would recommend that you first try with a low TWT_INTERVAL, and then increase this when you have a working setup.

    We are continuously improving our handling in this case. Have you looked at the recently updated twt sample in main? It includes handling for this scenario:

    https://github.com/nrfconnect/sdk-nrf/commit/e05d9c964c8d7a5f77418347deda6f5795cf9b7e

     

    Sometimes looks like the TWT is not set (Image 5):

    Q1: Does the firmware run as expected here?

    Q2: Does the current consumption drop after 60 seconds?

    Q3: Which AP are you testing against?

    Kind regards,

    Håkon

  • Hi,

    I decreased the TWT interval to 200ms but the problem remained (I did not detect the wake up and sleep events).

    Regarding your questions:

    • Q1: What is seen in Image 5 does not occur every time. Although the code is always the same, sometimes it presents the result shown in Image 3 and other times it presents the result in Image 5.
    • Q2: When I obtain the result shown in Figure 5, the current consumption always remains around 173mA and never decreases again (even after those 60 seconds).
    • Q3: I'm testing with a Ubiquiti AP. I'm using the UniFi 6+.

    I was also testing the recently updated twt sample in main and I still can't detect the events. In fact, it seems that it doesn't even enter the NET_EVENT_WIFI_TWT_SLEEP_STATE case.

    In this sample I made the following changes:

    • main.c :
      1. Added the NET_EVENT_WIFI_TWT_SLEEP_STATE to the WIFI_SHELL_MGMT_EVENTS:
      2. Added LOG_WRN to the switch...case to check if these events occurred:

    • Kconfig (samples/wifi/twt) :
      1. As I want to use TWT, I changed the default value for SCHEDULED_TX

    • prj.conf :
      1. Added the following configugurations:
        CONFIG_TRAFFIC_GEN_CLIENT=y
        CONFIG_TRAFFIC_GEN_SERVER=n
        CONFIG_TRAFFIC_GEN_DURATION=10
        CONFIG_TRAFFIC_GEN_TYPE_TCP=y
        CONFIG_TRAFFIC_GEN_REMOTE_IPV4_ADDR="10.10.10.76"
        #
        CONFIG_TWT_TRIGGER_ENABLE=y
        CONFIG_TWT_ANNOUNCED_MODE=y
        CONFIG_SCHEDULED_TX=y

    The result is as follows:

    So my questions are:

    • With the changes I've made, if TWT was working correctly, shouldn't I have gotten the LOG_WRN("NET_EVENT_WIFI_TWT_SLEEP_STATE event")?
    • And the LOG_INF("SLEEP state") and LOG_INF("AWAKE state")?

    As far as I can see, I'm still not able to detect these events. Right?

  • Hi,

     

    I set the TWT to 5.24 seconds, and wake interval to 65 ms, and this is my observed current during TWT:

    Are you certain that you actually enter TWT? TWT shall have a floor current of less than 20 uA.

     

    Kind regards,

    Håkon

  • Hi,

    Yes, I believe so. At least, I'm obtaining the following output:

    Now I'm also using SDK v2.4.99-dev2 and a Asus RT-AX53U router.

    This is my sample code:

    twtNordicSample.zip

    Thank you

  • Hi,

     

    I am running on the exact same tag, firmware unchanged, except for SSID/PWD used.

    Here's the current profile:

    And the log output:

    [00:00:00.465,728] <inf> net_config: Waiting interface 1 (0x20001460) to be up...
    [00:00:00.465,850] <inf> net_config: IPv4 address: 192.168.1.99
    [00:00:00.465,911] <inf> net_config: Running dhcpv4 client...
    [00:00:00.466,156] <inf> twt: Starting nrf7002dk_nrf5340_cpuapp with CPU frequency: 64 MHz
    [00:00:01.466,308] <inf> twt: Static IP address (overridable): 192.168.1.99/255.255.255.0 -> 192.168.1.1
    [00:00:03.387,786] <inf> twt: Connection requested
    [00:00:03.387,847] <inf> twt: ==================
    [00:00:03.387,847] <inf> twt: State: SCANNING
    [00:00:03.687,988] <inf> twt: ==================
    [00:00:03.688,018] <inf> twt: State: SCANNING
    [00:00:03.988,159] <inf> twt: ==================
    [00:00:03.988,189] <inf> twt: State: SCANNING
    [00:00:04.288,299] <inf> twt: ==================
    [00:00:04.288,330] <inf> twt: State: SCANNING
    [00:00:04.588,439] <inf> twt: ==================
    [00:00:04.588,470] <inf> twt: State: SCANNING
    [00:00:04.888,580] <inf> twt: ==================
    [00:00:04.888,610] <inf> twt: State: SCANNING
    [00:00:05.188,751] <inf> twt: ==================
    [00:00:05.188,781] <inf> twt: State: SCANNING
    [00:00:05.488,922] <inf> twt: ==================
    [00:00:05.488,952] <inf> twt: State: SCANNING
    [00:00:05.789,062] <inf> twt: ==================
    [00:00:05.789,093] <inf> twt: State: SCANNING
    [00:00:06.089,202] <inf> twt: ==================
    [00:00:06.089,233] <inf> twt: State: SCANNING
    [00:00:06.389,373] <inf> twt: ==================
    [00:00:06.389,404] <inf> twt: State: SCANNING
    [00:00:06.689,514] <inf> twt: ==================
    [00:00:06.689,544] <inf> twt: State: SCANNING
    [00:00:06.989,654] <inf> twt: ==================
    [00:00:06.989,685] <inf> twt: State: SCANNING
    [00:00:07.289,825] <inf> twt: ==================
    [00:00:07.289,855] <inf> twt: State: SCANNING
    [00:00:07.589,996] <inf> twt: ==================
    [00:00:07.590,026] <inf> twt: State: SCANNING
    [00:00:07.890,136] <inf> twt: ==================
    [00:00:07.890,167] <inf> twt: State: SCANNING
    [00:00:08.190,277] <inf> twt: ==================
    [00:00:08.190,307] <inf> twt: State: AUTHENTICATING
    [00:00:08.437,957] <inf> twt: Connected
    [00:00:08.495,849] <inf> net_dhcpv4: Received: 192.168.32.128
    [00:00:08.495,971] <inf> net_config: IPv4 address: 192.168.32.128
    [00:00:08.496,002] <inf> net_config: Lease time: 43200 seconds
    [00:00:08.496,032] <inf> net_config: Subnet: 255.255.255.0
    [00:00:08.496,063] <inf> net_config: Router: 192.168.32.1
    [00:00:08.496,154] <inf> twt: DHCP IP address: 192.168.32.128
    [00:00:08.498,382] <inf> twt: ==================
    [00:00:08.498,382] <inf> twt: State: COMPLETED
    [00:00:08.498,413] <inf> twt: Interface Mode: STATION
    [00:00:08.498,443] <inf> twt: Link Mode: WIFI 6 (802.11ax/HE)
    [00:00:08.498,474] <inf> twt: SSID: OpenWrt                         
    [00:00:08.498,504] <inf> twt: BSSID: FC:34:97:0B:F6:DC
    [00:00:08.498,535] <inf> twt: Band: 5GHz
    [00:00:08.498,535] <inf> twt: Channel: 36
    [00:00:08.498,565] <inf> twt: Security: WPA2-PSK
    [00:00:08.498,565] <inf> twt: MFP: Optional
    [00:00:08.498,596] <inf> twt: RSSI: -60
    [00:00:08.498,596] <inf> twt: TWT: Supported
    [00:00:10.498,687] <inf> twt: AP is TWT capable, establishing TWT
    [00:00:10.511,627] <inf> twt: TWT setup requested
    [00:00:10.519,897] <inf> twt: TWT response: TWT accept
    [00:00:10.519,927] <inf> twt: == TWT negotiated parameters ==
    [00:00:10.519,927] <inf> twt: TWT Dialog token: 1
    [00:00:10.519,927] <inf> twt: TWT flow ID: 0
    [00:00:10.519,958] <inf> twt: TWT negotiation type: TWT individual negotiation
    [00:00:10.519,989] <inf> twt: TWT responder: true
    [00:00:10.520,019] <inf> twt: TWT implicit: true
    [00:00:10.520,019] <inf> twt: TWT announce: false
    [00:00:10.520,050] <inf> twt: TWT trigger: false
    [00:00:10.520,080] <inf> twt: TWT wake interval: 65024 us
    [00:00:10.520,080] <inf> twt: TWT interval: 5005000 us
    [00:00:10.520,080] <inf> twt: ========================
    [00:00:10.520,812] <wrn> twt: TWT SLEEP
    [00:00:15.507,629] <wrn> twt: TWT AWAKE
    [00:00:15.573,364] <wrn> twt: TWT SLEEP
    [00:00:20.513,671] <wrn> twt: TWT AWAKE
    [00:00:20.580,688] <wrn> twt: TWT SLEEP
    [00:00:20.594,268] <wrn> twt: TWT AWAKE
    [00:00:20.594,390] <wrn> twt: TWT SLEEP
    ...
     

    I am not sure what the difference is in our setups. I'm supplying the VBAT from the PPK2, with 3.6V and measuring that current.

    Can you share a picture or similar with your measuring setup? 

    Kind regards,

    Håkon

  • Hi,


    I thought that turning off VCOM0 VCOM1 would be enough to measure the current consumed in this way, but I have seen that there are other components consuming current. By connecting the multimeter to the P22 port, I was able to verify a consumption of approximately 27uA during sleep time.

    Thank you

  • Hi,

     

    Thanks for posting the setup. This explains the difference between our results.

    The problem is that the nRF5340 is not power optimized in this sample (logging is on, qspi etc), it is only the nRF7002, which explains why you're seeing a base current of ~2 mA.

     

    Kind regards,

    Håkon

Reply Children
No Data
Related