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,  

  • Hi @martin leasund 

    Thanks for the answer.

    I'm still stuck. What should i change with the port to make it work ? I try to copy ma code the asset_tracker project but it still don't work. The asset tracker example has the correct port ? 

  • 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.

Related