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

Tracking GPS but never get FIX

Hi, 

I wrote a code using gps_controller.c on my thingy:91. However, i could never get a GPS FIX so i decide to try the GPS sample but it doesn't work neither. 

I tried several places. Nevertheless, with the asset_tracker application I can get the location. 

Any idea of what is going on ? 

Regards,  

Parents
  • Hi Ricardo,
    Could you please try to flash the latest modem firmware (v1.2.0) and flash the GPS sample from latest NCS release and test the Thingy:91 in where you have an open sky. (not inside with a window between).

    If you still have issues, could you please update NCS to the master branch (use the following commands: cd ncs/nrf, git checkout master, git pull, west update) then either checkout this PR or add the changes in your sample to get out the extra NMEA strings. If you could do a run with NMEA strings enabled and share the log it would be easier to understand what is going on.

  • Hi ,

    Thanks for you replay

    I reinstalled the firmware v1.2.0. 

    I reinstall the all Toolchain Manager with nRF connect 3.4.0. 

    I changed my GPS sample with the link that you  gave me but I'm still stuck... I can track several satellites but never use it :(

    Here is the code :

    /*
     * Copyright (c) 2019 Nordic Semiconductor ASA
     *
     * SPDX-License-Identifier: LicenseRef-BSD-5-Clause-Nordic
     */
    
    #include <zephyr.h>
    #include <nrf_socket.h>
    #include <net/socket.h>
    #include <stdio.h>
    #include <at_cmd.h>
    #include <at_notif.h>
    
    #ifdef CONFIG_SUPL_CLIENT_LIB
    #include <supl_os_client.h>
    #include <supl_session.h>
    #include "supl_support.h"
    #endif
    
    #define AT_XSYSTEMMODE    "AT\%XSYSTEMMODE=1,0,1,0"
    #define AT_ACTIVATE_GPS   "AT+CFUN=31"
    #define AT_ACTIVATE_LTE   "AT+CFUN=21"
    #define AT_DEACTIVATE_LTE "AT+CFUN=20"
    
    #define GNSS_INIT_AND_START 1
    #define GNSS_STOP           2
    #define GNSS_RESTART        3
    
    #define AT_CMD_SIZE(x) (sizeof(x) - 1)
    
    
    #ifdef CONFIG_BOARD_NRF9160_PCA10090NS
    #define AT_MAGPIO      "AT\%XMAGPIO=1,0,0,1,1,1574,1577"
    #define AT_COEX0       "AT\%XCOEX0=1,1,1570,1580"
    #endif
    
    static const char     update_indicator[] = {'\\', '|', '/', '-'};
    static const char     at_commands[][31]  = {
    				AT_XSYSTEMMODE,
    #ifdef CONFIG_BOARD_NRF9160_PCA10090NS
    				AT_MAGPIO,
    				AT_COEX0,
    #endif
    				AT_ACTIVATE_GPS
    			};
    
    static int            gnss_fd;
    static char           nmea_strings[10][NRF_GNSS_NMEA_MAX_LEN];
    static u32_t          nmea_string_cnt;
    
    static bool                  got_fix;
    static u64_t                 fix_timestamp;
    static nrf_gnss_data_frame_t last_pvt;
    
    K_SEM_DEFINE(lte_ready, 0, 1);
    
    void bsd_recoverable_error_handler(uint32_t error)
    {
    	printf("Err: %lu\n", (unsigned long)error);
    }
    
    static int setup_modem(void)
    {
    	for (int i = 0; i < ARRAY_SIZE(at_commands); i++) {
    
    		if (at_cmd_write(at_commands[i], NULL, 0, NULL) != 0) {
    			return -1;
    		}
    	}
    
    	return 0;
    }
    
    #ifdef CONFIG_SUPL_CLIENT_LIB
    /* Accepted network statuses read from modem */
    static const char status1[] = "+CEREG: 1";
    static const char status2[] = "+CEREG:1";
    static const char status3[] = "+CEREG: 5";
    static const char status4[] = "+CEREG:5";
    
    static void wait_for_lte(void *context, char *response)
    {
    	if (!memcmp(status1, response, AT_CMD_SIZE(status1)) ||
    		!memcmp(status2, response, AT_CMD_SIZE(status2)) ||
    		!memcmp(status3, response, AT_CMD_SIZE(status3)) ||
    		!memcmp(status4, response, AT_CMD_SIZE(status4))) {
    		k_sem_give(&lte_ready);
    	}
    }
    
    static int activate_lte(bool activate)
    {
    	if (activate) {
    		if (at_cmd_write(AT_ACTIVATE_LTE, NULL, 0, NULL) != 0) {
    			return -1;
    		}
    
    		at_notif_register_handler(NULL, wait_for_lte);
    		if (at_cmd_write("AT+CEREG=2", NULL, 0, NULL) != 0) {
    			return -1;
    		}
    
    		k_sem_take(&lte_ready, K_FOREVER);
    
    		at_notif_deregister_handler(NULL, wait_for_lte);
    		if (at_cmd_write("AT+CEREG=0", NULL, 0, NULL) != 0) {
    			return -1;
    		}
    	} else {
    		if (at_cmd_write(AT_DEACTIVATE_LTE, NULL, 0, NULL) != 0) {
    			return -1;
    		}
    	}
    
    	return 0;
    }
    
    #endif
    
    static int gnss_ctrl(uint32_t ctrl)
    {
    	int retval;
    	nrf_gnss_fix_retry_t    fix_retry    = 0;
    	nrf_gnss_fix_interval_t fix_interval = 1;
    	nrf_gnss_delete_mask_t	delete_mask  = 0;
    	nrf_gnss_nmea_mask_t	nmea_mask    = NRF_GNSS_NMEA_GSV_MASK |
    					       NRF_GNSS_NMEA_GSA_MASK |
    					       NRF_GNSS_NMEA_GLL_MASK |
    					       NRF_GNSS_NMEA_GGA_MASK |
    					       NRF_GNSS_NMEA_RMC_MASK;
    	if (ctrl == GNSS_INIT_AND_START) {
    		gnss_fd = nrf_socket(NRF_AF_LOCAL,
    				     NRF_SOCK_DGRAM,
    				     NRF_PROTO_GNSS);
    		if (gnss_fd >= 0) {
    			printk("GPS Socket created\n");
    		} else {
    			printk("Could not init socket (err: %d)\n", gnss_fd);
    			return -1;
    		}
    		retval = nrf_setsockopt(gnss_fd,
    					NRF_SOL_GNSS,
    					NRF_SO_GNSS_FIX_RETRY,
    					&fix_retry,
    					sizeof(fix_retry));
    		if (retval != 0) {
    			printk("Failed to set fix retry value\n");
    			return -1;
    		}
    		retval = nrf_setsockopt(gnss_fd,
    					NRF_SOL_GNSS,
    					NRF_SO_GNSS_FIX_INTERVAL,
    					&fix_interval,
    					sizeof(fix_interval));
    		if (retval != 0) {
    			printk("Failed to set fix interval value\n");
    			return -1;
    		}
    		retval = nrf_setsockopt(gnss_fd,
    					NRF_SOL_GNSS,
    					NRF_SO_GNSS_NMEA_MASK,
    					&nmea_mask,
    					sizeof(nmea_mask));
    		if (retval != 0) {
    			printk("Failed to set nmea mask\n");
    			return -1;
    		}
    	}
    	if ((ctrl == GNSS_INIT_AND_START) ||
    	    (ctrl == GNSS_RESTART)) {
    		retval = nrf_setsockopt(gnss_fd,
    					NRF_SOL_GNSS,
    					NRF_SO_GNSS_START,
    					&delete_mask,
    					sizeof(delete_mask));
    		if (retval != 0) {
    			printk("Failed to start GPS\n");
    			return -1;
    		}
    	}
    	if (ctrl == GNSS_STOP) {
    		retval = nrf_setsockopt(gnss_fd,
    					NRF_SOL_GNSS,
    					NRF_SO_GNSS_STOP,
    					&delete_mask,
    					sizeof(delete_mask));
    		if (retval != 0) {
    			printk("Failed to stop GPS\n");
    			return -1;
    		}
    	}
    	return 0;
    }
    
    
    
    
    
    
    static int init_app(void)
    {
    	int retval;
    	if (setup_modem() != 0) {
    		printk("Failed to initialize modem\n");
    		return -1;
    	}
    	retval = gnss_ctrl(GNSS_INIT_AND_START);
    	return retval;
    }
    
    static void print_satellite_stats(nrf_gnss_data_frame_t *pvt_data)
    {
    	u8_t  tracked          = 0;
    	u8_t  in_fix           = 0;
    	u8_t  unhealthy        = 0;
    
    	for (int i = 0; i < NRF_GNSS_MAX_SATELLITES; ++i) {
    
    		if ((pvt_data->pvt.sv[i].sv > 0) &&
    		    (pvt_data->pvt.sv[i].sv < 33)) {
    
    			tracked++;
    
    			if (pvt_data->pvt.sv[i].flags &
    					NRF_GNSS_SV_FLAG_USED_IN_FIX) {
    				in_fix++;
    			}
    
    			if (pvt_data->pvt.sv[i].flags &
    					NRF_GNSS_SV_FLAG_UNHEALTHY) {
    				unhealthy++;
    			}
    		}
    	}
    
    	printk("Tracking: %d Using: %d Unhealthy: %d", tracked,
    						       in_fix,
    						       unhealthy);
    
    	printk("\nSeconds since last fix %lld\n",
    			(k_uptime_get() - fix_timestamp) / 1000);
    }
    
    static void print_gnss_stats(nrf_gnss_data_frame_t *pvt_data)
    {
    	if (pvt_data->pvt.flags & NRF_GNSS_PVT_FLAG_DEADLINE_MISSED) {
    		printk("GNSS notification deadline missed\n");
    	}
    	if (pvt_data->pvt.flags & NRF_GNSS_PVT_FLAG_NOT_ENOUGH_WINDOW_TIME) {
    		printk("GNSS operation blocked by insufficient time windows\n");
    	}
    }
    
    static void print_fix_data(nrf_gnss_data_frame_t *pvt_data)
    {
    	printf("Longitude:  %f\n", pvt_data->pvt.longitude);
    	printf("Latitude:   %f\n", pvt_data->pvt.latitude);
    	printf("Altitude:   %f\n", pvt_data->pvt.altitude);
    	printf("Speed:      %f\n", pvt_data->pvt.speed);
    	printf("Heading:    %f\n", pvt_data->pvt.heading);
    	printk("Date:       %02u-%02u-%02u\n", pvt_data->pvt.datetime.day,
    					       pvt_data->pvt.datetime.month,
    					       pvt_data->pvt.datetime.year);
    	printk("Time (UTC): %02u:%02u:%02u\n", pvt_data->pvt.datetime.hour,
    					       pvt_data->pvt.datetime.minute,
    					      pvt_data->pvt.datetime.seconds);
    }
    
    static void print_nmea_data(void)
    {
    	printk("NMEA strings:\n");
    
    	for (int i = 0; i < nmea_string_cnt; ++i) {
    		printk("%s\n", nmea_strings[i]);
    	}
    }
    
    int process_gps_data(nrf_gnss_data_frame_t *gps_data)
    {
    	int retval;
    
    	retval = nrf_recv(gnss_fd,
    			  gps_data,
    			  sizeof(nrf_gnss_data_frame_t),
    			  NRF_MSG_DONTWAIT);
    
    	if (retval > 0) {
    
    		switch (gps_data->data_id) {
    		case NRF_GNSS_PVT_DATA_ID:
    			memcpy(&last_pvt,
    			       gps_data,
    			       sizeof(nrf_gnss_data_frame_t));
    			nmea_string_cnt = 0;
    			got_fix = false;
    			
    			if ((gps_data->pvt.flags &
    				NRF_GNSS_PVT_FLAG_FIX_VALID_BIT)
    				== NRF_GNSS_PVT_FLAG_FIX_VALID_BIT) {
    
    				got_fix = true;
    				fix_timestamp = k_uptime_get();
    
    			}
    			break;
    
    		case NRF_GNSS_NMEA_DATA_ID:
    			if (nmea_string_cnt < 10) {
    				memcpy(nmea_strings[nmea_string_cnt++],
    				       gps_data->nmea,
    				       retval);
    			}
    			break;
    
    		case NRF_GNSS_AGPS_DATA_ID:
    #ifdef CONFIG_SUPL_CLIENT_LIB
    			printk("\033[1;1H");
    			printk("\033[2J");
    			printk("New AGPS data requested, contacting SUPL server, flags %d\n",
    			       gps_data->agps.data_flags);
    			activate_lte(true);
    			printk("Established LTE link\n");
    			if (open_supl_socket() == 0) {
    				printf("Starting SUPL session\n");
    				supl_session(&gps_data->agps);
    				printk("Done\n");
    				close_supl_socket();
    			}
    			activate_lte(false);
    			k_sleep(K_MSEC(2000));
    #endif
    			break;
    
    		default:
    			break;
    		}
    	}
    
    	return retval;
    }
    
    #ifdef CONFIG_SUPL_CLIENT_LIB
    int inject_agps_type(void *agps,
    		     size_t agps_size,
    		     nrf_gnss_agps_data_type_t type,
    		     void *user_data)
    {
    	ARG_UNUSED(user_data);
    	int retval = nrf_sendto(gnss_fd,
    				agps,
    				agps_size,
    				0,
    				&type,
    				sizeof(type));
    
    	if (retval != 0) {
    		printk("Failed to send AGNSS data, type: %d (err: %d)\n",
    		       type,
    		       errno);
    		return -1;
    	}
    
    	printk("Injected AGPS data, flags: %d, size: %d\n", type, agps_size);
    
    	return 0;
    }
    #endif
    
    int main(void)
    {
    	nrf_gnss_data_frame_t gps_data;
    	u8_t		      cnt = 0;
    
    #ifdef CONFIG_SUPL_CLIENT_LIB
    	static struct supl_api supl_api = {
    		.read       = supl_read,
    		.write      = supl_write,
    		.handler    = inject_agps_type,
    		.logger     = supl_logger,
    		.counter_ms = k_uptime_get
    	};
    #endif
    
    	printk("Starting GPS application\n");
    
    	if (init_app() != 0) {
    		return -1;
    	}
    
    #ifdef CONFIG_SUPL_CLIENT_LIB
    	int rc = supl_init(&supl_api);
    
    	if (rc != 0) {
    		return rc;
    	}
    #endif
    
    	printk("Getting GPS data...\n");
    
    	while (1) {
    
    		do {
    			/* Loop until we don't have more
    			 * data to read
    			 */
    		} while (process_gps_data(&gps_data) > 0);
    
    		if (IS_ENABLED(CONFIG_GPS_SAMPLE_NMEA_ONLY)) {
    			print_nmea_data();
    			nmea_string_cnt = 0;
    		} else {
    			printk("\033[1;1H");
    			printk("\033[2J");
    			print_satellite_stats(&last_pvt);
    			print_gnss_stats(&last_pvt);
    			printk("---------------------------------\n");
    
    			if (!got_fix) {
    				printk("Seconds since last fix: %lld\n",
    				       (k_uptime_get() - fix_timestamp) / 1000);
    				cnt++;
    				printk("Searching [%c]\n",
    				       update_indicator[cnt%4]);
    			} else {
    				print_fix_data(&last_pvt);
    			}
    			
    			printk("\nNMEA strings:\n\n");
    			print_nmea_data();
    			printk("---------------------------------");
    
    		}
    
    		k_sleep(K_MSEC(500));
    	}
    
    	return 0;
    }
    

    I also add CONFIG_GPS_SAMPLE_NMEA_ONLY=n to prj.conf

    and here are some log

    2020-06-17T12:48:10.862Z DEBUG modem << ---------------------------------\x1B[1;1H\x1B[2JTracking: 7 Using: 0 Unhealthy: 0\x0D\x0A
    2020-06-17T12:48:10.870Z DEBUG modem << Seconds since last fix 637\x0D\x0A
    2020-06-17T12:48:10.877Z DEBUG modem << ---------------------------------\x0D\x0A
    2020-06-17T12:48:10.882Z DEBUG modem << Seconds since last fix: 637\x0D\x0A
    2020-06-17T12:48:10.889Z DEBUG modem << Searching [|]\x0D\x0A\x0D\x0A
    2020-06-17T12:48:10.897Z DEBUG modem << NMEA strings:\x0D\x0A\x0D\x0A
    2020-06-17T12:48:10.905Z DEBUG modem << NMEA strings:\x0D\x0A
    2020-06-17T12:48:10.912Z DEBUG modem << $GPGGA,001036.00,,,,,0,07,99.99,,M,0,,*34\x0D\x0D\x0A\x0D\x0A
    2020-06-17T12:48:10.916Z DEBUG modem << $GPGLL,,,,,001036.00,V,A*41\x0D\x0D\x0A\x0D\x0A
    2020-06-17T12:48:10.921Z DEBUG modem << $GPGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99,1*2D\x0D\x0D\x0A\x0D\x0A
    2020-06-17T12:48:10.926Z DEBUG modem << $GPGSV,2,1,7,20,,,28,7,,,26,26,,,34,8,,,33,1*50\x0D\x0D\x0A\x0D\x0A
    2020-06-17T12:48:10.934Z DEBUG modem << $GPGSV,2,2,7,16,,,32,27,,,34,10,,,33,1*56\x0D\x0D\x0A\x0D\x0A
    2020-06-17T12:48:10.943Z DEBUG modem << $GPRMC,001036.00,V,,,,,,,060180,,,N,V*0C\x0D\x0D\x0A\x0D\x0A
    2020-06-17T12:48:11.247Z DEBUG modem << ---------------------------------\x1B[1;1H\x1B[2JTracking: 7 Using: 0 Unhealthy: 0\x0D\x0A
    2020-06-17T12:48:11.254Z DEBUG modem << Seconds since last fix 638\x0D\x0A
    2020-06-17T12:48:11.259Z DEBUG modem << ---------------------------------\x0D\x0A
    2020-06-17T12:48:11.265Z DEBUG modem << Seconds since last fix: 638\x0D\x0A
    2020-06-17T12:48:11.270Z DEBUG modem << Searching [/]\x0D\x0A\x0D\x0A
    2020-06-17T12:48:11.276Z DEBUG modem << NMEA strings:\x0D\x0A\x0D\x0A
    2020-06-17T12:48:11.283Z DEBUG modem << NMEA strings:\x0D\x0A
    2020-06-17T12:48:11.288Z DEBUG modem << $GPGGA,001037.00,,,,,0,07,99.99,,M,0,,*35\x0D\x0D\x0A\x0D\x0A
    2020-06-17T12:48:11.293Z DEBUG modem << $GPGLL,,,,,001037.00,V,A*40\x0D\x0D\x0A\x0D\x0A
    2020-06-17T12:48:11.298Z DEBUG modem << $GPGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99,1*2D\x0D\x0D\x0A\x0D\x0A
    2020-06-17T12:48:11.303Z DEBUG modem << $GPGSV,2,1,7,20,,,27,7,,,26,26,,,33,8,,,33,1*58\x0D\x0D\x0A\x0D\x0A
    2020-06-17T12:48:11.308Z DEBUG modem << $GPGSV,2,2,7,16,,,32,27,,,34,10,,,33,1*56\x0D\x0D\x0A\x0D\x0A
    2020-06-17T12:48:11.314Z DEBUG modem << $GPRMC,001037.00,V,,,,,,,060180,,,N,V*0D\x0D\x0D\x0A\x0D\x0A
    2020-06-17T12:48:11.597Z DEBUG modem << ---------------------------------\x1B[1;1H\x1B[2JTracking: 7 Using: 0 Unhealthy: 0\x0D\x0A
    2020-06-17T12:48:11.605Z DEBUG modem << Seconds since last fix 638\x0D\x0A
    2020-06-17T12:48:11.610Z DEBUG modem << ---------------------------------\x0D\x0A

    Any help please 

  • Hi,

    When you build the asset tracker sample for thingy91 it will use the separate "prj_thingy91_nrf9160ns.conf" which sets the different configuration needed for that sample to run on the device.

    One option I just to strip down the asset_tracker sample to only use the GPS controller there since you already confirmed that it works in your favor.

  • Hi

    I did try to strip down the asset_tracker sample to only use the GPS. Here is the code 

    /*
     * Copyright (c) 2018 Nordic Semiconductor ASA
     *
     * SPDX-License-Identifier: LicenseRef-BSD-5-Clause-Nordic
     */
    
    #include <zephyr.h>
    #include <kernel_structs.h>
    #include <stdio.h>
    #include <string.h>
    #include <drivers/gps.h>
    #include <drivers/sensor.h>
    #include <console/console.h>
    #include <power/reboot.h>
    #include <logging/log_ctrl.h>
    #if defined(CONFIG_BSD_LIBRARY)
    #include <net/bsdlib.h>
    #include <bsd.h>
    #include <lte_lc.h>
    #include <modem_info.h>
    #endif /* CONFIG_BSD_LIBRARY */
    #include <net/cloud.h>
    #include <net/socket.h>
    #include <nrf_cloud.h>
    
    #if defined(CONFIG_BOOTLOADER_MCUBOOT)
    #include <dfu/mcuboot.h>
    #endif
    
    #include "cloud_codec.h"
    #include "env_sensors.h"
    #include "motion.h"
    #include "ui.h"
    #include "gps_controller.h"
    #include "service_info.h"
    #include "at_cmd.h"
    #include "watchdog.h"
    
    #include <logging/log.h>
    LOG_MODULE_REGISTER(asset_tracker, CONFIG_ASSET_TRACKER_LOG_LEVEL);
    
    #define CALIBRATION_PRESS_DURATION 	K_SECONDS(5)
    #define CLOUD_CONNACK_WAIT_DURATION	K_SECONDS(CONFIG_CLOUD_WAIT_DURATION)
    
    #ifdef CONFIG_ACCEL_USE_SIM
    #define FLIP_INPUT			CONFIG_FLIP_INPUT
    #define CALIBRATION_INPUT		-1
    #else
    #define FLIP_INPUT			-1
    #ifdef CONFIG_ACCEL_CALIBRATE
    #define CALIBRATION_INPUT		CONFIG_CALIBRATION_INPUT
    #else
    #define CALIBRATION_INPUT		-1
    #endif /* CONFIG_ACCEL_CALIBRATE */
    #endif /* CONFIG_ACCEL_USE_SIM */
    
    #if defined(CONFIG_BSD_LIBRARY) && \
    !defined(CONFIG_LTE_LINK_CONTROL)
    #error "Missing CONFIG_LTE_LINK_CONTROL"
    #endif
    
    #if defined(CONFIG_BSD_LIBRARY) && \
    defined(CONFIG_LTE_AUTO_INIT_AND_CONNECT) && \
    defined(CONFIG_NRF_CLOUD_PROVISION_CERTIFICATES)
    #error "PROVISION_CERTIFICATES \
    	requires CONFIG_LTE_AUTO_INIT_AND_CONNECT to be disabled!"
    #endif
    
    #define CLOUD_LED_ON_STR "{\"led\":\"on\"}"
    #define CLOUD_LED_OFF_STR "{\"led\":\"off\"}"
    #define CLOUD_LED_MSK UI_LED_1
    
    /* Interval in milliseconds after which the device will reboot
     * if the disconnect event has not been handled.
     */
    #define REBOOT_AFTER_DISCONNECT_WAIT_MS	K_SECONDS(15)
    
    /* Interval in milliseconds after which the device will
     * disconnect and reconnect if association was not completed.
     */
    #define CONN_CYCLE_AFTER_ASSOCIATION_REQ_MS	K_MINUTES(5)
    
    struct rsrp_data {
    	u16_t value;
    	u16_t offset;
    };
    
    
    /* Stack definition for application workqueue */
    K_THREAD_STACK_DEFINE(application_stack_area,
    		      CONFIG_APPLICATION_WORKQUEUE_STACK_SIZE);
    static struct k_work_q application_work_q;
    
    /* Sensor data */
    static struct gps_data gps_data;
    static struct cloud_channel_data gps_cloud_data;
    
    
    static atomic_val_t send_data_enable;
    
    /* Structures for work */
    
    static struct k_delayed_work long_press_button_work;
    
    #if defined(CONFIG_AT_CMD)
    #define MODEM_AT_CMD_BUFFER_LEN (CONFIG_AT_CMD_RESPONSE_MAX_LEN + 1)
    #else
    #define MODEM_AT_CMD_NOT_ENABLED_STR "Error: AT Command driver is not enabled"
    #define MODEM_AT_CMD_BUFFER_LEN (sizeof(MODEM_AT_CMD_NOT_ENABLED_STR))
    #endif
    #define MODEM_AT_CMD_RESP_TOO_BIG_STR "Error: AT Command response is too large to be sent"
    #define MODEM_AT_CMD_MAX_RESPONSE_LEN (2000)
    
    static K_SEM_DEFINE(modem_at_cmd_sem, 1, 1);
    
    
    
    enum error_type {
    	ERROR_CLOUD,
    	ERROR_BSD_RECOVERABLE,
    	ERROR_LTE_LC,
    	ERROR_SYSTEM_FAULT
    };
    
    static void set_gps_enable(const bool enable);
    
    /**@brief nRF Cloud error handler. */
    void error_handler(enum error_type err_type, int err_code)
    {
    	if (err_type == ERROR_CLOUD) {
    		if (gps_control_is_enabled()) {
    			LOG_ERR("Reboot");
    			sys_reboot(0);
    		}
    #if defined(CONFIG_LTE_LINK_CONTROL)
    		/* Turn off and shutdown modem */
    		LOG_ERR("LTE link disconnect");
    		int err = lte_lc_power_off();
    		if (err) {
    			LOG_ERR("lte_lc_power_off failed: %d", err);
    		}
    #endif /* CONFIG_LTE_LINK_CONTROL */
    #if defined(CONFIG_BSD_LIBRARY)
    		LOG_ERR("Shutdown modem");
    		bsdlib_shutdown();
    #endif
    	}
    
    #if !defined(CONFIG_DEBUG) && defined(CONFIG_REBOOT)
    	LOG_PANIC();
    	sys_reboot(0);
    #else
    	switch (err_type) {
    	case ERROR_CLOUD:
    		/* Blinking all LEDs ON/OFF in pairs (1 and 4, 2 and 3)
    		 * if there is an application error.
    		 */
    		ui_led_set_pattern(UI_LED_ERROR_CLOUD);
    		LOG_ERR("Error of type ERROR_CLOUD: %d", err_code);
    	break;
    	case ERROR_BSD_RECOVERABLE:
    		/* Blinking all LEDs ON/OFF in pairs (1 and 3, 2 and 4)
    		 * if there is a recoverable error.
    		 */
    		ui_led_set_pattern(UI_LED_ERROR_BSD_REC);
    		LOG_ERR("Error of type ERROR_BSD_RECOVERABLE: %d", err_code);
    	break;
    	default:
    		/* Blinking all LEDs ON/OFF in pairs (1 and 2, 3 and 4)
    		 * undefined error.
    		 */
    		ui_led_set_pattern(UI_LED_ERROR_UNKNOWN);
    		LOG_ERR("Unknown error type: %d, code: %d",
    			err_type, err_code);
    	break;
    	}
    
    	while (true) {
    		k_cpu_idle();
    	}
    #endif /* CONFIG_DEBUG */
    }
    
    void k_sys_fatal_error_handler(unsigned int reason,
    			       const z_arch_esf_t *esf)
    {
    	ARG_UNUSED(esf);
    
    	LOG_PANIC();
    	LOG_ERR("Running main.c error handler");
    	error_handler(ERROR_SYSTEM_FAULT, reason);
    	CODE_UNREACHABLE;
    }
    
    /**@brief Recoverable BSD library error. */
    void bsd_recoverable_error_handler(uint32_t err)
    {
    	error_handler(ERROR_BSD_RECOVERABLE, (int)err);
    }
    
    
    
    /**@brief Callback for GPS trigger events */
    static void gps_trigger_handler(struct device *dev, struct gps_trigger *trigger)
    {
    	static u32_t fix_count;
    
    	ARG_UNUSED(trigger);
    
    	if (!atomic_get(&send_data_enable)) {
    		return;
    	}
    
    	if (++fix_count < CONFIG_GPS_CONTROL_FIX_COUNT) {
    		return;
    	}
    
    	fix_count = 0;
    
    	ui_led_set_pattern(UI_LED_GPS_FIX);   //let the user know that a FIX
    
    	gps_sample_fetch(dev);
    	gps_channel_get(dev, GPS_CHAN_NMEA, &gps_data);
    	gps_cloud_data.data.buf = gps_data.nmea.buf;
    	gps_cloud_data.data.len = gps_data.nmea.len;
    	gps_cloud_data.tag += 1;
    
    	if (gps_cloud_data.tag == 0) {
    		gps_cloud_data.tag = 0x1;
    	}
    
    	gps_control_stop(K_NO_WAIT);
            printk("Yes I got a FIX !!!!!! \n\n");
    	//k_work_submit_to_queue(&application_work_q, &send_gps_data_work);
    	//env_sensors_poll();
    }
    
    
    static void set_gps_enable(const bool enable)
    {
    	if (enable == gps_control_is_enabled()) {
    		return;
    	}
    
    	if (enable) {
    		LOG_INF("Starting GPS");
    		gps_control_enable();
    		gps_control_start(K_SECONDS(1));
    
    	} else {
    		LOG_INF("Stopping GPS");
    		gps_control_disable();
    	}
    }
    
    
    
    /**@brief Configures modem to provide LTE link. Blocks until link is
     * successfully established.
     */
    static void modem_configure(void)
    {
    #if defined(CONFIG_BSD_LIBRARY)
    	if (IS_ENABLED(CONFIG_LTE_AUTO_INIT_AND_CONNECT)) {
    		/* Do nothing, modem is already turned on
    		 * and connected.
    		 */
    	} else {
    		int err;
    
    		LOG_INF("Connecting to LTE network. ");
    		LOG_INF("This may take several minutes.");
    		ui_led_set_pattern(UI_LTE_CONNECTING);
    
    		err = lte_lc_init_and_connect();
    		if (err) {
    			LOG_ERR("LTE link could not be established.");
    			error_handler(ERROR_LTE_LC, err);
    		}
    
    		LOG_INF("Connected to LTE network");
    		ui_led_set_pattern(UI_LTE_CONNECTED);
    	}
    #endif
    }
    
    
    #if defined(CONFIG_USE_UI_MODULE)
    /**@brief User interface event handler. */
    static void ui_evt_handler(struct ui_evt evt)
    {
    	/*if (IS_ENABLED(CONFIG_CLOUD_BUTTON) &&
    	   (evt.button == CONFIG_CLOUD_BUTTON_INPUT)) {
    		button_send(evt.type == UI_EVT_BUTTON_ACTIVE ? 1 : 0);
    	}*/
    
    	if (IS_ENABLED(CONFIG_ACCEL_USE_SIM) && (evt.button == FLIP_INPUT)
    	   && atomic_get(&send_data_enable)) {
    		motion_simulate_trigger();
    	}
    
    	if (IS_ENABLED(CONFIG_GPS_CONTROL_ON_LONG_PRESS) &&
    	   (evt.button == UI_BUTTON_1)) {
    		if (evt.type == UI_EVT_BUTTON_ACTIVE) {
    			k_delayed_work_submit_to_queue(&application_work_q,
    						       &long_press_button_work,
    			K_SECONDS(5));
    		} else {
    			k_delayed_work_cancel(&long_press_button_work);
    		}
    	}
    
    #if defined(CONFIG_LTE_LINK_CONTROL)
    	if ((evt.button == UI_SWITCH_2) &&
    	    IS_ENABLED(CONFIG_POWER_OPTIMIZATION_ENABLE)) {
    		int err;
    		if (evt.type == UI_EVT_BUTTON_ACTIVE) {
    			err = lte_lc_edrx_req(false);
    			if (err) {
    				error_handler(ERROR_LTE_LC, err);
    			}
    			err = lte_lc_psm_req(true);
    			if (err) {
    				error_handler(ERROR_LTE_LC, err);
    			}
    		} else {
    			err = lte_lc_psm_req(false);
    			if (err) {
    				error_handler(ERROR_LTE_LC, err);
    			}
    			err = lte_lc_edrx_req(true);
    			if (err) {
    				error_handler(ERROR_LTE_LC, err);
    			}
    		}
    	}
    #endif /* defined(CONFIG_LTE_LINK_CONTROL) */
    }
    #endif /* defined(CONFIG_USE_UI_MODULE) */
    
    void handle_bsdlib_init_ret(void)
    {
    	#if defined(CONFIG_BSD_LIBRARY)
    	int ret = bsdlib_get_init_ret();
    
    	/* Handle return values relating to modem firmware update */
    	switch (ret) {
    	case MODEM_DFU_RESULT_OK:
    		LOG_INF("MODEM UPDATE OK. Will run new firmware");
    		sys_reboot(SYS_REBOOT_COLD);
    		break;
    	case MODEM_DFU_RESULT_UUID_ERROR:
    	case MODEM_DFU_RESULT_AUTH_ERROR:
    		LOG_ERR("MODEM UPDATE ERROR %d. Will run old firmware", ret);
    		sys_reboot(SYS_REBOOT_COLD);
    		break;
    	case MODEM_DFU_RESULT_HARDWARE_ERROR:
    	case MODEM_DFU_RESULT_INTERNAL_ERROR:
    		LOG_ERR("MODEM UPDATE FATAL ERROR %d. Modem failiure", ret);
    		sys_reboot(SYS_REBOOT_COLD);
    		break;
    	default:
    		break;
    	}
    	#endif /* CONFIG_BSD_LIBRARY */
    }
    
    void main(void)
    {
    	int ret;
    
    	LOG_INF("Asset tracker started");
    	k_work_q_start(&application_work_q, application_stack_area,
    		       K_THREAD_STACK_SIZEOF(application_stack_area),
    		       CONFIG_APPLICATION_WORKQUEUE_PRIORITY);
    	if (IS_ENABLED(CONFIG_WATCHDOG)) {
    		watchdog_init_and_start(&application_work_q);
    	}
    	handle_bsdlib_init_ret();
            
    
    #if defined(CONFIG_USE_UI_MODULE)
    	ui_init(ui_evt_handler);
    #endif
         
    	//work_init();
    	modem_configure();
    
            /* Toggle GPS state */
            gps_control_init(&application_work_q, gps_trigger_handler);
    
    	set_gps_enable(!gps_control_is_enabled());
    
    }
    

    I did not touch the porting (prj_nrf9160_pca20035ns.conf). So I think the port should be correct.  

    #
    # Copyright (c) 2019 Nordic Semiconductor ASA
    #
    # SPDX-License-Identifier: LicenseRef-BSD-5-Clause-Nordic
    #
    # General config
    CONFIG_NEWLIB_LIBC=y
    CONFIG_NEWLIB_LIBC_FLOAT_PRINTF=y
    CONFIG_ASSERT=y
    CONFIG_REBOOT=y
    CONFIG_LOG=y
    CONFIG_LOG_IMMEDIATE=y
    
    # Network
    CONFIG_NETWORKING=y
    CONFIG_NET_NATIVE=n
    CONFIG_NET_SOCKETS=y
    CONFIG_NET_SOCKETS_OFFLOAD=y
    
    # LTE link control
    CONFIG_POWER_OPTIMIZATION_ENABLE=n
    CONFIG_LTE_LINK_CONTROL=y
    CONFIG_LTE_NETWORK_MODE_LTE_M_GPS=y
    CONFIG_LTE_AUTO_INIT_AND_CONNECT=n
    CONFIG_LTE_LINK_CONTROL_LOG_LEVEL_DBG=y
    
    CONFIG_LTE_NETWORK_MODE_NBIOT=n
    CONFIG_LTE_LEGACY_PCO_MODE=n
    CONFIG_LTE_PSM_REQ_RPTAU="00000110"
    CONFIG_LTE_PSM_REQ_RAT="00000000"
    
    CONFIG_LTE_LOCK_BANDS=y
    # Enable band 2, 3, 4, 8, 12, 13 ,20 and 28
    CONFIG_LTE_LOCK_BAND_MASK="1000000010000001100010001110"
    
    # Modem info
    CONFIG_MODEM_INFO=y
    
    # BSD library
    CONFIG_BSD_LIBRARY=y
    CONFIG_BSD_LIBRARY_TRACE_ENABLED=n
    
    # nRF Cloud
    CONFIG_CLOUD_API=y
    CONFIG_NRF_CLOUD=y
    CONFIG_NRF_CLOUD_LOG_LEVEL_DBG=y
    
    # Sensors
    CONFIG_SENSOR=y
    CONFIG_ACCEL_USE_EXTERNAL=y
    CONFIG_ACCEL_DEV_NAME="ADXL362"
    CONFIG_ADXL362=y
    CONFIG_ADXL362_TRIGGER_GLOBAL_THREAD=y
    CONFIG_ADXL362_ABS_REF_MODE=1
    CONFIG_ADXL362_ACTIVITY_THRESHOLD=200
    CONFIG_ADXL362_INACTIVITY_THRESHOLD=200
    CONFIG_ADXL362_INTERRUPT_MODE=1
    CONFIG_TEMP_USE_EXTERNAL=y
    CONFIG_TEMP_DEV_NAME="BME680"
    
    # Deselect CONFIG_BME680 if CONFIG_USE_BME680_BSEC is selected
    CONFIG_BME680=y
    CONFIG_USE_BME680_BSEC=n
    
    # GPS
    CONFIG_NRF9160_GPS_LOG_LEVEL_DBG=y
    CONFIG_NRF9160_GPS=y
    CONFIG_NRF9160_GPS_LOG_LEVEL_DBG=y
    CONFIG_GPS_USE_EXTERNAL=y
    CONFIG_GPS_DEV_NAME="NRF9160_GPS"
    
    CONFIG_GPS_CONTROL_FIRST_FIX_CHECK_DELAY=10
    CONFIG_GPS_CONTROL_FIX_CHECK_INTERVAL=30
    CONFIG_GPS_CONTROL_FIX_TRY_TIME=360
    CONFIG_GPS_CONTROL_PSM_DISABLE_ON_STOP=n
    
    # Library for buttons and LEDs
    CONFIG_DK_LIBRARY=y
    CONFIG_DK_LIBRARY_INVERT_LEDS=n
    
    # Console
    CONFIG_CLOUD_UA_BUTTONS=n
    CONFIG_CLOUD_UA_CONSOLE=n
    CONFIG_CONSOLE_SUBSYS=y
    CONFIG_CONSOLE_HANDLER=y
    CONFIG_CONSOLE_GETCHAR=y
    
    # Heap and stacks
    CONFIG_HEAP_MEM_POOL_SIZE=16384
    CONFIG_MAIN_STACK_SIZE=8192
    CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=2048
    CONFIG_HW_STACK_PROTECTION=y
    
    # Settings
    CONFIG_FLASH=y
    CONFIG_FLASH_PAGE_LAYOUT=y
    CONFIG_FLASH_MAP=y
    CONFIG_FCB=y
    CONFIG_SETTINGS=y
    CONFIG_SETTINGS_FCB=y
    CONFIG_MPU_ALLOW_FLASH_WRITE=y
    
    # MCUBOOT
    CONFIG_BOOTLOADER_MCUBOOT=y
    CONFIG_IMG_MANAGER=y
    CONFIG_MCUBOOT_IMG_MANAGER=y
    CONFIG_IMG_ERASE_PROGRESSIVELY=y
    
    # AWS FOTA
    CONFIG_AWS_FOTA=y
    CONFIG_AWS_FOTA_LOG_LEVEL_DBG=y
    CONFIG_AWS_JOBS_LOG_LEVEL_DBG=y
    CONFIG_DFU_TARGET=y
    
    # Download client (needed by AWS FOTA)
    CONFIG_DOWNLOAD_CLIENT=y
    CONFIG_DOWNLOAD_CLIENT_STACK_SIZE=4096
    
    # Fatal error
    CONFIG_RESET_ON_FATAL_ERROR=n
    
    CONFIG_WATCHDOG=y
    

    However I still have the same issues, it can find several satellites but never get fix Disappointed

     

    Do you still think that the problem is with the port ?  In the asset_tracker sample it use the A-GPS, is it possible to make it work with just the GPS ? 

  • Hi

    I got good news! Since this was working and I didn't find any explanation I started suspecting the hardware a few days ago. So I other a new Thingy:91. 

    And Surprise it works Slight smile In fact, when I program the asset_tracker sample from your website (.hex) it has a A-GPS. And with that the module works, not fast but work. However, went i program the asset_tracker sample (code sample) it doesn't work anymore. Comparing both terminal i saw that one has A-GPS and the other one doesn't. 

    So i program both kit with GPS only, i start the at the same time and got the following screen. 

    I already sent a email to Mouser to know if there is some king of warranty. 

    I got a question. Is it possible to have the asset_tracker sample with the A-GPS ? 

  • Hi,
    Good to hear that you got it up and running.
    If you are using NCS v1.3.0. A-GPS should be enabled by default in the asset_tracker sample: https://github.com/nrfconnect/sdk-nrf/blob/master/applications/asset_tracker/prj_thingy91_nrf9160ns.conf#L47

    Also make sure you are running the latest modem firmware on the devices: https://www.nordicsemi.com/Products/Low-power-cellular-IoT/nRF9160/Download#infotabs

    U
    pdate to NCS v1.3.0 by:

    cd ncs/nrf
    git checkout master
    git pull
    git checkout v1.3.0
    west update

    or use the toolchain manager.

  • Hi @martin Lesund

    Thanks a lot for your support! 

    Just on last question. A-GPS works with a public server or it has to be done for our private server ?  

Reply Children
No Data
Related