Exercise 2

In this exercise, we will turn on both the GNSS and the LTE modem and connect to the UDP echo server used in Lesson 3. Then, pushing button 1 on your device will send GPS information to the server.

This will let us observe how the LTE and GNSS coexist in the same application, and how the <Active-Timer> plays into this.

Exercise Steps

1. In the GitHub repository for this course, go to the base code for this exercise, found in lesson6/cellfund_less6_exer2.

3. Modify print_fix_data() to create a string we can send.

3.1 Declare the buffer send_buf to be used when sending data to the echo server

static uint8_t gps_data[MESSAGE_SIZE];

3.2 Modify print_fix_data() to create a string containing the latitude and longitude and write it to send_buf.

int err = snprintf(gps_data, MESSAGE_SIZE, "Latitude: %.06f, Longitude: %.06f", pvt_data->latitude, pvt_data->longitude);		
if (err < 0) {
	LOG_ERR("Failed to print to buffer: %d", err);

3.3 In button_handler(), send this string to the UDP server upon button 1 push.

switch (has_changed) {
case DK_BTN1_MSK:
	if (button_state & DK_BTN1_MSK){	
		int err = send(sock, &gps_data, sizeof(gps_data), 0);
		if (err < 0) {
			LOG_INF("Failed to send message, %d", errno);


Without power saving techniques

Let’s look at how the modem handles it if we enable the LTE modem and the GNSS receiver at the same time.

4. In gnss_init_and_start(), set the modem to normal mode.

if (lte_lc_func_mode_set(LTE_LC_FUNC_MODE_NORMAL) != 0) {
	LOG_ERR("Failed to activate GNSS functional mode");
	return -1;

5. Check the PVT data flags to see if the GNSS is being blocked.

Check the flags field of pvt_data, to see of:

NRF_MODEM_GNSS_PVT_FLAG_DEADLINE_MISSED: the GNSS has been blocked by LTE activity

NRF_MODEM_GNSS_PVT_FLAG_NOT_ENOUGH_WINDOW_TIME: the average time window length is too short

Recall that these two flags will never be set at the same time.

	LOG_INF("GNSS blocked by LTE activity");
	LOG_INF("Insufficient GNSS time windows");

6. Build the exercise and flash it to your board. Run the application for around 5 minutes, pressing button 1 occasionally to send a UDP packet.

6.1 Let’s take a look at the resulting log output, which has been a bit reduced for readability.

It’s evident from the log that the RRC Inactivity Timer is 6 seconds. That’s the time it takes from the UE has connected to the server until it’s released from RRC Connected mode and goes into RRC Idle mode.

When the UE is in RRC Connected mode, the GNSS is blocked by LTE activity. When the device is released from RRC Connected mode, it takes a little while (around 13 seconds) before the average time window granted to GNSS is below the threshold of 10 seconds and the NOT_ENOUGH_WINDOW_TIME flag is raised. This is most likely due to the LTE modem initiating page monitoring.

Even though the GNSS is tracking enough satellites, it is not given the time window required to download the satellite information and be able to calculate a valid fix.


We also know the RRC Inactivity Timer for this connection is 6 seconds through communication with the network provider. This is not a timer value the UE is given when connecting, so it is not something that can be read through AT commands.

6.2 Now press button 1 to send a packet to the UDP server, and observe the output.

In our case, we get the following log output.

As soon as button 1 is pushed, the UE is in RRC Connected mode, and the GNSS is therefore blocked by LTE activity. When the UE is released from RRC Connected and enters RRC Idle mode, the GNSS has insufficient time windows, due to the average time window (taken before and after RRC Idle mode) is smaller than 10 seconds.

Notice that the flag is disabled for a short period of time after being put in RRC Idle mode, before being enabled again.

This is because the NOT_ENOUGH_WINDOW_TIME flag is based on the current average time window length given to the GNSS, and is raised if this time window is less than 10 seconds. In this case, the average time window right after being released from RRC Connected mode is very small because the time window in RRC Connected mode is very small. It takes around 9 seconds for the average time window to become larger than 10 seconds, at which point the flag is disabled. This doesn’t last long, however, as the LTE modem initiates page monitoring not long after and the average time window is again decreased to lower than 10 seconds and the flag is raised again.

It is important to note that the behavior of the modem heavily depends on the network parameters given to your UE and can vary from what is being shown here.

With power saving techniques

We have now seen that when the LTE modem is active, the GNSS receiver will not have enough time to actually produce a valid fix. Even when the modem is in RRC Idle mode, it is paging intermittently which doesn’t give GNSS a large enough time window to download satellite information and calculate a valid fix.

The solution to this is to enable PSM or eDRX in your application.

Enabling PSM puts the LTE modem in deep sleep and the GNSS receiver will be able to run freely until the LTE modem has to wake up to send the TAU.

Enabling eDRX will extend the amount of time the LTE modem sleeps between paging, and will give the GNSS large enough time windows to perform the necessary operations.


If your network operator and/or SIM card does not support either PSM nor eDRX, you will have to manually deactivate and activate the modem when wanting to use the GNSS in your application.

There is a workaround, by giving the GNSS priority over LTE events to help get a fix. This is not recommended, as it interferes with LTE operations.

7. Set the Kconfigs to enable eDRX and PSM in prj.conf

7.1 Enable requesting the use of eDRX, through CONFIG_LTE_EDRX_REQ.

7.2 Request the values for periodic TAU and the active timer, through CONFIG_LTE_PSM_REQ_RPTAU and CONFIG_LTE_PSM_REQ_RAT.

Here we are requesting periodic TAU of 8 hours and an active time of 16 seconds.

8. In modem_configure(), request both PSM and eDRX by calling the following functions

err = lte_lc_psm_req(true);
if (err) {
	LOG_ERR("lte_lc_psm_req, error: %d", err);
err = lte_lc_edrx_req(true);
if (err) {
	LOG_ERR("lte_lc_edrx_req, error: %d", err);

9. Expand the lte_handler() to notify us on the power saving events LTE_LC_EVT_PSM_UPDATE and LTE_LC_EVT_EDRX_UPDATE.

9.1 On the PSM update, we print the PSM parameters given by the network, and check the value of active time to confirm if PSM was granted.

	LOG_INF("PSM parameter update: TAU: %d, Active time: %d",
		evt->psm_cfg.tau, evt->psm_cfg.active_time);
	if (evt->psm_cfg.active_time == -1){
		LOG_ERR("Network rejected PSM parameters. Failed to setup network");

9.2 On the eDRX update, we print the eDRX parameters given by the network (if any). If this event is never triggered, eDRX was not enabled by the network.

	LOG_INF("eDRX parameter update: eDRX: %f, PTW: %f",
		evt->edrx_cfg.edrx, evt->edrx_cfg.ptw);

If you are not able to enable either PSM or eDRX, there is a work-around to be able to achieve a GNSS fix. This is by enabling GNSS priority mode, which will give GNSS operations priority over LTE events and will allow the GNSS enough time to get a valid fix. This is not recommended and will therefore not be in the base exercise or the exercise solution.

In gnss_init_and_start(), before starting GNSS, you can enable GNSS priority mode.

if (nrf_modem_gnss_prio_mode_enable() != 0) {
	LOG_ERR("Failed to set priority mode for GNSS");
} else {
	LOG_INF("GNSS priority mode set");

10. Build the exercise and flash it to your board.


Let’s look at the scenario where PSM is enabled with the requested value, and eDRX is not.

At first glance, this log output might seems strange. We know that 16 seconds (Active Timer) after being in RRC Idle mode, the LTE modem should be in power saving mode, and the GNSS should have sufficient time windows. So why is the log saying something else?

We are seeing the same thing that we noticed in step 6, in which the NOT_ENOUGH_TIME_WINDOW flag takes a bit of time to adjust to the current average time window.

Shortly after RRC Idle mode, some higher level LTE activity is starting (probably related to page monitoring) and making the time windows granted to GNSS too short. When the modem is put in power saving mode 3 seconds later (because the Active-Timer of 16 seconds has run out) the flag is not disabled immediately because the average time window is still lower than 10 seconds. It takes some time before the average is raised above the threshold.

Let’s also illustrate another scenario, whereby we set the requested Active-Timer to 6 seconds.

In this case, the log output looks something like this

Now the UE is put in power saving mode before this higher-level LTE activity is started (or at least, before it decreases the average GNSS time window below the threshold), and the NOT_ENOUGH_WINDOW_TIME flag is never raised. Notice that the TTFF is almost the same, so this flag does not actually interfere with the GNSS performance.

Note that you might not be able to recreate this log when connected to your network, since this all depends on network provider-specific configurations.


Let’s look at the scenario where eDRX is enabled with the requested value, and PSM is not.

As we know, the GNSS is not able to run when the modem is in RRC Connected mode. As soon as we go to RRC Idle mode, the GNSS starts running and is able to find a fix in 36 seconds.

This is much lower than the previous case, with just PSM, because the GNSS starts running right after RRC Idle mode, and isn’t limited by the page monitoring during the Active Time, like we were with PSM.

PSM and eDRX

Let’s look at the scenario where both PSM and eDRX are enabled.

Register an account
Already have an account? Log in
(All fields are required unless specified optional)

Forgot your password?
Enter your email address, and we will send a link to reset your password.