summaryrefslogtreecommitdiff
path: root/nrfdemo
diff options
context:
space:
mode:
authorMichal Hanus <mikehanus@protonmail.com>2025-05-21 20:55:30 +0200
committerMichal Hanus <mikehanus@protonmail.com>2025-05-21 20:55:30 +0200
commitca84ca1273fb3676ffbb402ec9c1019c698c0553 (patch)
treef683a0efec688dea6accaa9f5bc84a449312dbbc /nrfdemo
parent85f4aadd7382eec843a02f513f6933abba6e5d02 (diff)
GNSS+LTEHEADmaster
Diffstat (limited to 'nrfdemo')
-rw-r--r--nrfdemo/src/main.c330
1 files changed, 202 insertions, 128 deletions
diff --git a/nrfdemo/src/main.c b/nrfdemo/src/main.c
index 770b178..4c8503e 100644
--- a/nrfdemo/src/main.c
+++ b/nrfdemo/src/main.c
@@ -19,47 +19,68 @@
#include <nrf_modem_gnss.h>
#include "mqtt_connection.h"
-#include "bme680/bme680.h"
-
/* The mqtt client struct */
static struct mqtt_client client;
/* File descriptor */
static struct pollfd fds;
-/* Define the PVT data frame variable */
-static struct nrf_modem_gnss_pvt_data_frame pvt_data;
/* Declare helper variables to find the TTFF */
static int64_t gnss_start_time;
-static bool first_fix = false;
+//static bool first_fix = false;
static void gnss_event_handler(int event);
static void print_fix_data(struct nrf_modem_gnss_pvt_data_frame *pvt_data);
-static K_SEM_DEFINE(lte_connected, 0, 1);
-
-LOG_MODULE_REGISTER(mqtt_app, LOG_LEVEL_INF);
+K_SEM_DEFINE(lte_connected, 0, 1);
+K_SEM_DEFINE(gnss_fix_sem, 0, 1);
+LOG_MODULE_REGISTER(Cellfund_Project, LOG_LEVEL_INF);
+static struct nrf_modem_gnss_pvt_data_frame current_pvt;
+static struct nrf_modem_gnss_pvt_data_frame last_pvt;
+static enum tracker_status {status_nolte = DK_LED1, status_searching = DK_LED2, status_fixed = DK_LED3} device_status;
static void lte_handler(const struct lte_lc_evt *const evt)
{
- switch (evt->type) {
- case LTE_LC_EVT_NW_REG_STATUS:
- if ((evt->nw_reg_status != LTE_LC_NW_REG_REGISTERED_HOME) &&
- (evt->nw_reg_status != LTE_LC_NW_REG_REGISTERED_ROAMING)) {
- break;
- }
- LOG_INF("Network registration status: %s",
+ switch (evt->type) {
+ case LTE_LC_EVT_NW_REG_STATUS:
+ if ((evt->nw_reg_status != LTE_LC_NW_REG_REGISTERED_HOME) &&
+ (evt->nw_reg_status != LTE_LC_NW_REG_REGISTERED_ROAMING)) {
+ break;
+ }
+
+ LOG_INF("Network registration status: %s\n",
evt->nw_reg_status == LTE_LC_NW_REG_REGISTERED_HOME ?
- "Connected - home network" : "Connected - roaming");
- k_sem_give(&lte_connected);
- break;
- case LTE_LC_EVT_RRC_UPDATE:
- LOG_INF("RRC mode: %s", evt->rrc_mode == LTE_LC_RRC_MODE_CONNECTED ?
- "Connected" : "Idle");
- break;
- default:
+ "Connected - home network" : "Connected - roaming\n");
+ k_sem_give(&lte_connected);
+ break;
+ case LTE_LC_EVT_PSM_UPDATE:
+ LOG_INF("PSM parameter update: TAU: %d, Active time: %d\n",
+ evt->psm_cfg.tau, evt->psm_cfg.active_time);
+ break;
+ case LTE_LC_EVT_EDRX_UPDATE: {
+ char log_buf[60];
+ ssize_t len;
+
+ len = snprintf(log_buf, sizeof(log_buf),
+ "eDRX parameter update: eDRX: %f, PTW: %f\n",
+ (double)evt->edrx_cfg.edrx, (double)evt->edrx_cfg.ptw);
+ if (len > 0) {
+ LOG_INF("%s\n", log_buf);
+ }
+ }
+ break;
+ case LTE_LC_EVT_RRC_UPDATE:
+ LOG_INF("RRC mode: %s\n",
+ evt->rrc_mode == LTE_LC_RRC_MODE_CONNECTED ?
+ "Connected" : "Idle\n");
+ break;
+ case LTE_LC_EVT_CELL_UPDATE:
+ LOG_INF("LTE cell changed: Cell ID: %d, Tracking area: %d\n",
+ evt->cell.id, evt->cell.tac);
break;
- }
+ default:
+ break;
+ }
}
static int modem_configure(void)
@@ -80,14 +101,13 @@ static int modem_configure(void)
return err;
}
- k_sem_take(&lte_connected, K_FOREVER);
- LOG_INF("Connected to LTE network");
-
- // Blink LED to indicate we connected to MQTT broker
- dk_set_led_on(DK_LED1);
- k_msleep(2000);
- dk_set_led_off(DK_LED1);
+ /* Decativate LTE and enable GNSS. */
+ err = lte_lc_func_mode_set(LTE_LC_FUNC_MODE_DEACTIVATE_LTE);
+ if (err) {
+ LOG_ERR("Failed to decativate LTE and enable GNSS functional mode");
+ return err;
+ }
return 0;
}
@@ -109,7 +129,6 @@ static void button_handler(uint32_t button_state, uint32_t has_changed)
}
}
-#if 1
/* Define a function to log fix data in a readable format */
static void print_fix_data(struct nrf_modem_gnss_pvt_data_frame *pvt_data)
{
@@ -127,122 +146,102 @@ static void print_fix_data(struct nrf_modem_gnss_pvt_data_frame *pvt_data)
static void gnss_event_handler(int event)
{
int err;
-
switch (event) {
- /* On a PVT event, confirm if PVT data is a valid fix */
case NRF_MODEM_GNSS_EVT_PVT:
- LOG_INF("Searching...");
- /* Print satellite information */
- int num_satellites = 0;
- for (int i = 0; i < 12 ; i++) {
- if (pvt_data.sv[i].signal != 0) {
- LOG_INF("sv: %d, cn0: %d", pvt_data.sv[i].sv, pvt_data.sv[i].cn0);
- num_satellites++;
- }
- }
- LOG_INF("Number of current satellites: %d", num_satellites);
- err = nrf_modem_gnss_read(&pvt_data, sizeof(pvt_data), NRF_MODEM_GNSS_DATA_PVT);
- if (err) {
- LOG_ERR("nrf_modem_gnss_read failed, err %d", err);
- return;
- }
- if (pvt_data.flags & NRF_MODEM_GNSS_PVT_FLAG_FIX_VALID) {
- dk_set_led_on(DK_LED1);
- print_fix_data(&pvt_data);
- /* Print the time to first fix */
- if (!first_fix) {
- LOG_INF("Time to first fix: %2.1lld s", (k_uptime_get() - gnss_start_time)/1000);
- first_fix = true;
- }
- return;
- }
+ LOG_INF("Searching for GNSS Satellites....\n\r");
+ device_status = status_searching;
+ break;
+ case NRF_MODEM_GNSS_EVT_FIX:
+ LOG_INF("GNSS fix event\n\r");
break;
- /* Log when the GNSS sleeps and wakes up */
case NRF_MODEM_GNSS_EVT_PERIODIC_WAKEUP:
- LOG_INF("GNSS has woken up");
+ LOG_INF("GNSS woke up in periodic mode\n\r");
+ break;
+ case NRF_MODEM_GNSS_EVT_BLOCKED:
+ LOG_INF("GNSS is blocked by LTE event\n\r");
break;
case NRF_MODEM_GNSS_EVT_SLEEP_AFTER_FIX:
- LOG_INF("GNSS enter sleep after fix");
+ LOG_INF("GNSS enters sleep because fix was achieved in periodic mode\n\r");
+ device_status = status_fixed;
+ err = nrf_modem_gnss_read(&last_pvt, sizeof(last_pvt), NRF_MODEM_GNSS_DATA_PVT);
+ if (err == 0){
+ current_pvt = last_pvt;
+ print_fix_data(&current_pvt);
+ k_sem_give(&gnss_fix_sem);
+ }
break;
+ case NRF_MODEM_GNSS_EVT_SLEEP_AFTER_TIMEOUT:
+ LOG_INF("GNSS enters sleep because fix retry timeout was reached\n\r");
+ break;
+
default:
+
break;
}
}
-#endif
-int main(void)
+static int gnss_init_and_start(void)
{
- int err;
- uint32_t connect_attempt = 0;
-
- LOG_INF("Starting MQTT sample on %s\n", CONFIG_BOARD);
-
- if (dk_leds_init() != 0) {
- LOG_ERR("Failed to initialize the LED library");
- }
-
- err = modem_configure();
- if (err) {
- LOG_ERR("Failed to configure the modem");
- return 0;
- }
-
- if (dk_buttons_init(button_handler) != 0) {
- LOG_ERR("Failed to initialize the buttons library");
+#if defined(CONFIG_GNSS_HIGH_ACCURACY_TIMING_SOURCE)
+ if (nrf_modem_gnss_timing_source_set(NRF_MODEM_GNSS_TIMING_SOURCE_TCXO)){
+ LOG_ERR("Failed to set TCXO timing source");
+ return -1;
}
-
-
- /* Activate only the GNSS stack */
- if (lte_lc_func_mode_set(LTE_LC_FUNC_MODE_ACTIVATE_GNSS) != 0) {
- LOG_ERR("Failed to activate GNSS functional mode");
- return 0;
+#endif
+#if defined(CONFIG_GNSS_LOW_ACCURACY) || defined (CONFIG_BOARD_THINGY91_NRF9160_NS)
+ uint8_t use_case;
+ use_case = NRF_MODEM_GNSS_USE_CASE_MULTIPLE_HOT_START | NRF_MODEM_GNSS_USE_CASE_LOW_ACCURACY;
+ if (nrf_modem_gnss_use_case_set(use_case) != 0) {
+ LOG_ERR("Failed to set low accuracy use case");
+ return -1;
}
-
- /* Register the GNSS event handler */
+#endif
+ /* Configure GNSS event handler . */
if (nrf_modem_gnss_event_handler_set(gnss_event_handler) != 0) {
LOG_ERR("Failed to set GNSS event handler");
- return 0;
+ return -1;
}
- /* Set the GNSS fix interval and GNSS fix retry period */
if (nrf_modem_gnss_fix_interval_set(1) != 0) {
LOG_ERR("Failed to set GNSS fix interval");
- return 0;
+ return -1;
}
- if (nrf_modem_gnss_fix_retry_set(60) != 0) {
+ if (nrf_modem_gnss_fix_retry_set(600) != 0) {
LOG_ERR("Failed to set GNSS fix retry");
- return 0;
+ return -1;
}
- /* Start the GNSS receiver */
- LOG_INF("Starting GNSS");
if (nrf_modem_gnss_start() != 0) {
LOG_ERR("Failed to start GNSS");
- return 0;
+ return -1;
}
-
- err = client_init(&client);
- if (err) {
- LOG_ERR("Failed to initialize MQTT client: %d", err);
- return 0;
+ if (nrf_modem_gnss_prio_mode_enable() != 0){
+ LOG_ERR("Error setting GNSS priority mode");
+ return -1;
}
+ return 0;
+}
- /* Log the current system uptime */
- gnss_start_time = k_uptime_get();
-do_connect:
- if (connect_attempt++ > 0) {
+int try_mqtt_connect(void)
+{
+ int err = 0;
+ for (int connect_attempt = 0; connect_attempt < 5; connect_attempt++)
+ {
+ LOG_INF("Connection to broker using mqtt_connect");
+ err = mqtt_connect(&client);
+ if (!err) {
+ break;
+ }
+ LOG_ERR("Error in mqtt_connect: %d", err);
LOG_INF("Reconnecting in %d seconds...",
CONFIG_MQTT_RECONNECT_DELAY_S);
k_sleep(K_SECONDS(CONFIG_MQTT_RECONNECT_DELAY_S));
}
- LOG_INF("Connection to broker using mqtt_connect");
- err = mqtt_connect(&client);
if (err) {
- LOG_ERR("Error in mqtt_connect: %d", err);
- goto do_connect;
+ return err;
}
err = fds_init(&client,&fds);
@@ -251,34 +250,110 @@ do_connect:
return 0;
}
+ return err;
+}
+
+int main(void)
+{
+ int err;
+
+ err = dk_leds_init();
+ if (err){
+ LOG_ERR("Failed to initlize the LEDs Library");
+ }
+
+ device_status = status_nolte;
+
+ err = modem_configure();
+ if (err) {
+ LOG_ERR("Failed to configure the modem");
+ return 0;
+ }
+
+ err = dk_buttons_init(button_handler);
+ if (err) {
+ LOG_ERR("Failed to initlize button handler: %d\n", err);
+ return 0;
+ }
+
+ if (dk_leds_init() != 0) {
+ LOG_ERR("Failed to initialize the LED library");
+ }
+
+ LOG_INF("Starting GNSS....");
+ gnss_init_and_start();
+
+
+ LOG_INF("Starting MQTT sample on %s\n", CONFIG_BOARD);
+
+ err = client_init(&client);
+ if (err) {
+ LOG_ERR("Failed to initialize MQTT client: %d", err);
+ return 0;
+ }
+
+ /* Log the current system uptime */
+ gnss_start_time = k_uptime_get();
+
+ try_mqtt_connect();
+
while (1) {
- err = poll(&fds, 1, mqtt_keepalive_time_left(&client));
- if (err < 0) {
- LOG_ERR("Error in poll(): %d", errno);
+ k_sem_take(&gnss_fix_sem, K_FOREVER);
+ err = lte_lc_func_mode_set(LTE_LC_FUNC_MODE_NORMAL);
+ if (err != 0){
+ LOG_ERR("Failed to activate LTE");
break;
}
+ k_sem_take(&lte_connected, K_FOREVER);
- err = mqtt_live(&client);
- if ((err != 0) && (err != -EAGAIN)) {
- LOG_ERR("Error in mqtt_live: %d", err);
- break;
- }
+ try_mqtt_connect();
- if ((fds.revents & POLLIN) == POLLIN) {
- err = mqtt_input(&client);
- if (err != 0) {
- LOG_ERR("Error in mqtt_input: %d", err);
+ for (int i = 0; i < 10; i++)
+ {
+ err = poll(&fds, 1, mqtt_keepalive_time_left(&client));
+ if (err < 0) {
+ LOG_ERR("Error in poll(): %d", errno);
break;
}
+
+ err = mqtt_live(&client);
+ if ((err != 0) && (err != -EAGAIN)) {
+ LOG_ERR("Error in mqtt_live: %d", err);
+ break;
+ }
+
+ if ((fds.revents & POLLIN) == POLLIN) {
+ err = mqtt_input(&client);
+ if (err != 0) {
+ LOG_ERR("Error in mqtt_input: %d", err);
+ break;
+ }
+ }
+
+ if ((fds.revents & POLLERR) == POLLERR) {
+ LOG_ERR("POLLERR");
+ break;
+ }
+
+ if ((fds.revents & POLLNVAL) == POLLNVAL) {
+ LOG_ERR("POLLNVAL");
+ break;
+ }
+
+ err = data_publish(&client, MQTT_QOS_1_AT_LEAST_ONCE,
+ CONFIG_BUTTON_EVENT_PUBLISH_MSG, sizeof(CONFIG_BUTTON_EVENT_PUBLISH_MSG)-1);
+
+ k_msleep(1000);
}
- if ((fds.revents & POLLERR) == POLLERR) {
- LOG_ERR("POLLERR");
- break;
+ err = mqtt_disconnect(&client);
+ if (err) {
+ LOG_ERR("Could not disconnect MQTT client: %d", err);
}
- if ((fds.revents & POLLNVAL) == POLLNVAL) {
- LOG_ERR("POLLNVAL");
+ err = lte_lc_func_mode_set(LTE_LC_FUNC_MODE_DEACTIVATE_LTE);
+ if (err != 0){
+ LOG_ERR("Failed to decativate LTE and enable GNSS functional mode");
break;
}
}
@@ -289,7 +364,6 @@ do_connect:
if (err) {
LOG_ERR("Could not disconnect MQTT client: %d", err);
}
- goto do_connect;
/* This is never reached */
return 0;