Mbed event queue: How to deep sleep for x amount of hours?

I am using a stm32l0 chip, MTB_MURATA_ABZ to be specific. I am trying to use the event queue for my lorawan applications. These applications will require me to go deep sleep, we are talking hours. Unfortunately I have not been able to get it working. It sleeps for a maximum time of 40s then something causes it to wake up and send data again.

I ran into several threads on here that suggest using event_queue background function. However that example is using RTOS which I am ignoring. I’v e been able to achieve deep sleep without using the event queue by doing the following:
-Setting all peripherals low, PA11, PA12(radio), PA2,PA3,PA5 etc…
-on the mbed_apps.json set MBED TICKLESS to true, LSE available true, lowpowerticker value to 0(need to use RTC to achieve longer sleep)
-I create a lowpowerticker object and use it to attach whatever time i want to sleep

By doing all the above steps, I was able to go to deep sleep for x amount of hours based on whatever value i sent down from my server. In addition, it would manage to wakeup successfully. What is the difference with the event queue? Is there some unknown interrupts that are firing from the event queue that I am not aware of? Should I not be using the lp ticker? here is my code. Only posting it some of it since its not formatting correctly for whatever reason. I apologize since this is my first post.

this is from mbed_app.json

"target_overrides": {
    "*": {
        "target.lse_available": true,
        "target.device_has_add": [
            "LPTICKER"
        ],
        "platform.cpu-stats-enabled": true,
        "events.use-lowpower-timer-ticker": true,
        "target.device_has_remove": [],
        "target.clock_source": "USE_PLL_HSI",
        "target.lpticker_lptim":  0,
        "platform.stdio-convert-newlines": true,
        "platform.stdio-baud-rate": 115200,
        "platform.default-serial-baud-rate": 115200,
        "lora.over-the-air-activation": true,
        "lora.duty-cycle-on": false,
        "lora.phy": "US915",
        "lora.device-eui": "{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}",
        "lora.application-eui": "{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}",
        "lora.application-key": "{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}",
        "lora.fsb-mask": "{0x00FF, 0x0000, 0x0000, 0x0000, 0x0001}",
        "lora.max-sys-rx-error": 50,
        "mbed-trace.enable": true
    },

static void goToSleep()
{

radio.saveRadioStatus();

pb_2 = 0;
pb_5 = 0;
pb_6 = 0;
pb_7 = 0;
pb_8 = 0;
pb_9 = 0;


do_env9v_d.write(0); // enable 9v regulator
wait_ms(5);
do_nenlp_d.write(0); // disable low power mode
wait_ms(1);
TXCO_pwr_d.write(0); // enable TXCO power
wait_ms(5);
sleep_manager_unlock_deep_sleep();
sleep_manager_sleep_auto();

if (flags.sense) {
    flags.sense = 0;
    wakeUp();

    printf("WAKEUP");
}

}

static void lora_event_handler(lorawan_event_t event)
{
switch (event) {
case CONNECTED:
printf(“\r\n Connection - Successful \r\n”);
attach_ticker(600.0f);
id = ev_queue.call_every(TX_TIMER, send_message);
#ifdef CLASS_C_ENABLE
lorawan.set_device_class(CLASS_C);
#endif
break;
case DISCONNECTED:
ev_queue.break_dispatch();
printf(“\r\n Disconnected Successfully \r\n”);
break;
case TX_DONE:
{

            printf("\r\n Message Sent to Network Server \r\n");
            lorawan_tx_metadata data;
            lorawan_status_t retcode_tx_data = lorawan.get_tx_metadata(data);
            if(retcode_tx_data == LORAWAN_STATUS_OK) {
                attach_ticker(600.0f);
                aimmiSleep = true;
                printf(" tx_toa %lu, channel %lu, tx_power %u, data_rate %u, nb_retries %u, stale %u\r\n",
                     data.tx_toa, data.channel, data.tx_power, data.data_rate, data.nb_retries, data.stale);
            } else {
                ticker_lp.detach();
                aimmiSleep = true;
	   
                printf("Error getting TX metadata %d\r\n", retcode_tx_data);

            }

            if(aimmi.uplinkBuffer.hasData()) {
                aimmiSleep = false;
                printf("MORE TO SEND\n");
                send_message();
            }
        }


        break;
    case TX_TIMEOUT:
    case TX_ERROR:
    case TX_CRYPTO_ERROR:
    case TX_SCHEDULING_ERROR:
        aimmiSleep = true;
        printf("\r\n Transmission Error - EventCode = %d (%s)\r\n", event, lorawan_codes_strings[event]);
        if(aimmiSleep)
        {
	firstSend = true;
            aimmiSleep = false;
            goToSleep();

        }


        //aimmi.handleError(event);
        break;
    case RX_DONE:
        printf("\r\n Received message from Network Server \r\n");
        receive_message();
       
        aimmiSleep = true;
        if(aimmiSleep)
        {
            printf("SLEEP!!\n");
            aimmiSleep = false;
            
            goToSleep();

        }



        break;
    case RX_TIMEOUT:
    case RX_ERROR:
        printf("\r\n Error in reception - EventCode = %d (%s)\r\n", event, lorawan_codes_strings[event]);
        //aimmi.handleError(event);
        break;
    case JOIN_FAILURE:
        printf("\r\n OTAA Failed - Check Keys \r\n");
        break;
    case UPLINK_REQUIRED:
        printf("\r\n Uplink required by NS \r\n");
        if (MBED_CONF_LORA_DUTY_CYCLE_ON) {
            send_message();
        }
        break;
    default:
        MBED_ASSERT("Unknown Event");
}

}

Hi Jessica

I’m not absolutely sure, I tend to use bare metal build (no RTOS) and use long period deep sleep functions and shut off everything to achieve lowest power.

However,

From what I understand in RTOS you need to periodically wake up and check for interrupts, see here:

https://os.mbed.com/questions/85125/Whats-causing-this-power-spike/

Looks to me that’s what is happening with your project.

"events.use-lowpower-timer-ticker": true," 

in your .json file appears to be the very timer.
If you turn it it may not wake up when the lora radio receives data.

Depending on how low you want to go, you could turn off your tickers (not RTC) and use a hardware interrupt connection from the lora radio (if it has one) as a wake up to override the RTC.
That’s pretty much what I do with Xbee radios, I haven’t used lora yet.

I do mine communications ‘backwards’ to achieve the best power performance in the respect my remote device totally shuts down, no radio but will wake every, say 5 minutes, fire off a beacon code where the server will ‘latch on’ and respond if necessary. That drives the power right down, only draw back is you can’t communicate with it during the sleep period. But I do get 3-4 months running from a 1000mAh li-ion battery.

Good detailed post information :slight_smile:

Paul