diff options
| author | Michal Hanus <mikehanus@protonmail.com> | 2025-05-21 20:55:30 +0200 |
|---|---|---|
| committer | Michal Hanus <mikehanus@protonmail.com> | 2025-05-21 20:55:30 +0200 |
| commit | ca84ca1273fb3676ffbb402ec9c1019c698c0553 (patch) | |
| tree | f683a0efec688dea6accaa9f5bc84a449312dbbc | |
| parent | 85f4aadd7382eec843a02f513f6933abba6e5d02 (diff) | |
| -rw-r--r-- | nrfdemo/src/main.c | 330 |
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(<e_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(<e_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(<e_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(¤t_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(<e_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; |
