I am only want to send and MQTT message every day. Because of this I think it is better to turnoff the modem and reconnect when needed. I tried to alter the LTE Link example a bit but it does not work as expected. I think it has something to do with the timing of the work thread. I schedule the connect when the device is turned on. When this function is successful a new work item is scheduled to disconnect the modem.
The fist connect does not respond.
#include <zephyr/kernel.h>
#include <modem/lte_lc.h>
/* Semaphore used to block the main thread until the link controller has
* established an LTE connection.
*/
K_SEM_DEFINE(lte_connected, 0, 1);
static struct k_work_delayable connectLTE_work;
static struct k_work_delayable disconnectLTE_work;
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;
}
printk("Connected to: %s network\n",
evt->nw_reg_status == LTE_LC_NW_REG_REGISTERED_HOME ? "home" : "roaming");
k_sem_give(<e_connected);
break;
case LTE_LC_EVT_PSM_UPDATE:
case LTE_LC_EVT_EDRX_UPDATE:
case LTE_LC_EVT_RRC_UPDATE:
case LTE_LC_EVT_CELL_UPDATE:
case LTE_LC_EVT_LTE_MODE_UPDATE:
case LTE_LC_EVT_TAU_PRE_WARNING:
case LTE_LC_EVT_NEIGHBOR_CELL_MEAS:
case LTE_LC_EVT_MODEM_SLEEP_EXIT_PRE_WARNING:
case LTE_LC_EVT_MODEM_SLEEP_EXIT:
case LTE_LC_EVT_MODEM_SLEEP_ENTER:
/* Callback events carrying LTE link data */
break;
default:
break;
}
}
static void connectLTE(struct k_work *work)
{
int err;
printk("Connecting to LTE network. This may take a few minutes...\n");
err = lte_lc_init_and_connect_async(lte_handler);
if (err) {
printk("lte_lc_init_and_connect_async, error: %d\n", err);
return;
}
k_sem_take(<e_connected, K_FOREVER);
printk("Connected!\n");
//Disconnect after 30 seconds
k_work_schedule(&disconnectLTE_work, K_SECONDS(30));
}
static void disconnectLTE(struct k_work *work)
{
int err;
printk("Disconnecting...\n");
err = lte_lc_offline();
if (err) {
printk("Failed to discconet\n");
return;
}
printk("Disconnected!\n");
//Connect after 30 seconds
k_work_schedule(&connectLTE_work, K_SECONDS(30));
}
static void init_work(void)
{
k_work_init_delayable(&connectLTE_work, connectLTE);
k_work_init_delayable(&disconnectLTE_work, disconnectLTE);
}
void main(void)
{
init_work();
//Schedule connect now
k_work_schedule(&connectLTE_work, K_NO_WAIT);
}
Output
14:32:07.540 -> *** Booting Zephyr OS build v3.1.99-ncs1-1 *** 14:32:07.540 -> Connecting to LTE network. This may take a few minutes...
What would be the correct way to archive something like this?