mDot sleep behavior with online and offline compilers

Home Forums mDot/xDot mDot sleep behavior with online and offline compilers

Viewing 9 posts - 1 through 9 (of 9 total)
  • Author
    Posts
  • #23820
    Denwis La
    Participant

    Hi,

    I am using mbed’s mbed-cli to compile my program the majority of the time and I noticed that when I put my mDot to sleep for 30 seconds it won’t ever wake up. When I use the mbed online compiler and put it to sleep for 30 seconds, it wakes up with no problems. The sleep function is within a while loop so it should wake up. For sleeping, I am using both the default interrupt DIO7 for waking at interrupt and RTC. The interrupt part works perfectly fine when compiling either online or offline. I am also using the dot_util file for calling sleep. I am using libmDot-mbed5 version 3.0, mbed-os version 5.4.7, GNU Tools ARM Embedded version 4.9 2015q3, and mbed-cli version 1.7.3.
    TLDR; mDot doesn’t wake up from RTC when compiling program offline but works perfectly fine when compiling online.

    Any idea why this behavior is occurring? I think that it is due to the possible difference in assemblers with the online compiler vs the offline one. Maybe.

    Thank you.

    #23821
    Ryan Klaassen
    Blocked

    I cannot reproduce this problem, could you share your code?

    #23822
    Denwis La
    Participant


    #include <mbed.h>
    #include <algorithm>
    #include <sstream>
    #include "dot_util.h"
    #include "RadioEvent.h"
    #include "Device.h"
    #include "SoftI2C.h"
    #include "SPDF.h"

    /////////////////////////////////////////////////////////////////////////////
    // -------------------- DOT LIBRARY REQUIRED ------------------------------//
    // * Because these example programs can be used for both mDot and xDot //
    // devices, the LoRa stack is not included. The libmDot library should //
    // be imported if building for mDot devices. The libxDot library //
    // should be imported if building for xDot devices. //
    // * https://developer.mbed.org/teams/MultiTech/code/libmDot-dev-mbed5/ //
    // * https://developer.mbed.org/teams/MultiTech/code/libmDot-mbed5/ //
    // * https://developer.mbed.org/teams/MultiTech/code/libxDot-dev-mbed5/ //
    // * https://developer.mbed.org/teams/MultiTech/code/libxDot-mbed5/ //
    /////////////////////////////////////////////////////////////////////////////

    /////////////////////////////////////////////////////////////
    // * these options must match the settings on your gateway //
    // * edit their values to match your configuration //
    // * frequency sub band is only relevant for the 915 bands //
    // * either the network name and passphrase can be used or //
    // the network ID (8 bytes) and KEY (16 bytes) //
    /////////////////////////////////////////////////////////////
    static std::string network_name = "networkname";
    static std::string network_passphrase = "networkpass";
    //static uint8_t network_id[] = { 0x6C, 0x4E, 0xEF, 0x66, 0xF4, 0x79, 0x86, 0xA6 };
    //static uint8_t network_key[] = { 0x1F, 0x33, 0xA1, 0x70, 0xA5, 0xF1, 0xFD, 0xA0, 0xAB, 0x69, 0x7A, 0xAE, 0x2B, 0x95, 0x91, 0x6B };
    static uint8_t frequency_sub_band = 7;
    static bool public_network = false;
    static uint8_t ack = 1;
    static bool adr = true;
    uint32_t sleep_interval = 20; /* Sleep interval in seconds */

    // deepsleep consumes slightly less current than sleep
    // in sleep mode, IO state is maintained, RAM is retained, and application will resume after waking up
    // in deepsleep mode, IOs float, RAM is lost, and application will start from beginning after waking up
    // if deep_sleep == true, device will enter deepsleep mode
    static bool deep_sleep = false;

    mDot* dot = NULL;
    lora::ChannelPlan* plan = NULL;

    Serial pc(USBTX, USBRX); /* Terminal communication */
    DigitalOut enable_pin(PB_1); /* d0 Pin */
    DigitalOut v12_24_pin(PB_0); /* d1 pin */
    DigitalOut shdn_pin(PA_11); /* Shutdown pin */
    DigitalIn din3_pin(PA_1); /* No changes */
    DigitalIn wkup_pin(PA_0); /* No changes */

    // Initialize I2C
    SoftI2C i2c(I2C_SDA /*PC_9*/ , I2C_SCL /*PA_8*/);

    /* Create SPI device for the ADC device, ADS1018 */
    SPI spi(SPI1_MOSI, SPI1_MISO, SPI1_SCK);

    /* Create SPI block device for Flash Memory */
    SPIFBlockDevice sfdp(SPI1_MOSI, SPI1_MISO, SPI1_SCK, PC_13);
    SPDF flashMem(&sfdp, &spi, &pc); /* Create flash mem */

    /* Create ADC device */
    DigitalOut adc_cs(PA_4);
    Device adc(&spi,&adc_cs);

    /* Main */
    int main() {

    // Serial datarate
    pc.baud(115200);

    // Custom event handler for automatically displaying RX data
    RadioEvent events;

    /* The SPI/ADC interface operates in SPI mode 1 [POL = 0,PHA = 1]*/
    spi.format(8,1);
    spi.frequency(4000000);

    mts::MTSLog::setLogLevel(mts::MTSLog::TRACE_LEVEL);

    plan = new lora::ChannelPlan_US915();

    assert(plan);

    dot = mDot::getInstance(plan);
    assert(dot);

    // attach the custom events handler
    dot->setEvents(&events);

    if (!dot->getStandbyFlag()) {
    logInfo("mbed-os library version: %d", MBED_LIBRARY_VERSION);

    // start from a well-known state
    logInfo("defaulting Dot configuration");
    dot->resetConfig();
    dot->resetNetworkSession();
    dot->setTxDataRate(dot->DR0);
    dot->setRxDataRate(dot->DR0);

    // make sure library logging is turned on
    dot->setLogLevel(mts::MTSLog::INFO_LEVEL);

    // update configuration if necessary
    // in AUTO_OTA mode the session is automatically saved, so saveNetworkSession and restoreNetworkSession are not needed
    if (dot->getJoinMode() != mDot::AUTO_OTA) {
    logInfo("changing network join mode to AUTO_OTA");
    if (dot->setJoinMode(mDot::AUTO_OTA) != mDot::MDOT_OK) {
    logError("failed to set network join mode to AUTO_OTA");
    }
    }
    // in OTA and AUTO_OTA join modes, the credentials can be passed to the library as a name and passphrase or an ID and KEY
    // only one method or the other should be used!
    // network ID = crc64(network name)
    // network KEY = cmac(network passphrase)
    update_ota_config_name_phrase(network_name, network_passphrase, frequency_sub_band, public_network, ack);
    //update_ota_config_id_key(network_id, network_key, frequency_sub_band, public_network, ack);

    // configure network link checks
    // network link checks are a good alternative to requiring the gateway to ACK every packet and should allow a single gateway to handle more Dots
    // check the link every count packets
    // declare the Dot disconnected after threshold failed link checks
    // for count = 3 and threshold = 5, the Dot will ask for a link check response every 5 packets and will consider the connection lost if it fails to receive 3 responses in a row
    update_network_link_check_config(3, 5);

    // enable or disable Adaptive Data Rate
    dot->setAdr(adr);

    // save changes to configuration
    logInfo("saving configuration");
    if (!dot->saveConfig()) {
    logError("failed to save configuration");
    }

    // display configuration
    display_config();
    }

    while (true) {

    std::vector<uint8_t> tx_data;

    /* Perform I2C communication with device */

    // join network if not joined
    if (!dot->getNetworkJoinStatus()) {
    join_network();
    }
    /* Read from sensors, send to the gateway, and save onto an external flash with SPI*/

    sleep_wake_rtc_or_interrupt(deep_sleep, sleep_interval); /* From dot_util header */
    }

    return 0;
    }

    #23826
    Ryan Klaassen
    Blocked

    sleep_wake_rtc_or_interrupt(deep_sleep, sleep_interval); Is this modified from the original?

    #23827
    Denwis La
    Participant

    sleep_wake_rtc_or_interrupt(deep_sleep, sleep_interval); is modified from the original, yes. Only difference is that variable sleep_interval lets you choose how long the mDot will sleep.


    void sleep_wake_rtc_or_interrupt(bool deepsleep, uint32_t time) {
    // in some frequency bands we need to wait until another channel is available before transmitting again
    // wait at least 10s between transmissions
    //uint32_t delay_s = dot->getNextTxMs() / 1000;
    uint32_t delay_s = time;
    // if (delay_s < SLEEP_TIME ) {
    // delay_s = SLEEP_TIME ;
    // }

    if (deepsleep) {
    // for mDot, XBEE_DIO7 pin is the only pin that can wake the processor from deepsleep
    // it is automatically configured when INTERRUPT or RTC_ALARM_OR_INTERRUPT is the wakeup source and deepsleep is true in the mDot::sleep call
    } else {
    // configure XBEE_DIO7 pin as the pin that will wake the mDot from low power modes
    // other pins can be confgured instead: XBEE_DIO2-6, XBEE_DI8, XBEE_DIN
    dot->setWakePin(XBEE_DIO7);
    }

    logInfo("%ssleeping %lus or until interrupt on %s pin", deepsleep ? "deep" : "", delay_s, deepsleep ? "DIO7" : mDot::pinName2Str(dot->getWakePin()).c_str());

    logInfo("application will %s after waking up", deepsleep ? "execute from beginning" : "resume");

    // lowest current consumption in sleep mode can only be achieved by configuring IOs as analog inputs with no pull resistors
    // the library handles all internal IOs automatically, but the external IOs are the application's responsibility
    // certain IOs may require internal pullup or pulldown resistors because leaving them floating would cause extra current consumption
    // for xDot: UART_*, I2C_*, SPI_*, GPIO*, WAKE
    // for mDot: XBEE_*, USBTX, USBRX, PB_0, PB_1
    // steps are:
    // * save IO configuration
    // * configure IOs to reduce current consumption
    // * sleep
    // * restore IO configuration
    if (! deepsleep) {
    logInfo("Save IO configuration\n\r\n\r");
    wait_ms(200);
    // save the GPIO state.
    sleep_save_io();

    // configure GPIOs for lowest current
    sleep_configure_io();
    }

    // go to sleep/deepsleep and wake using the RTC alarm after delay_s seconds or rising edge of configured wake pin (only the WAKE pin in deepsleep)
    // whichever comes first will wake the xDot

    dot->sleep(delay_s, mDot::RTC_ALARM_OR_INTERRUPT, deepsleep);

    if (! deepsleep) {
    // restore the GPIO state.
    sleep_restore_io();
    logInfo("Restore IO configuration");
    }
    }

    #23828
    Ryan Klaassen
    Blocked

    Did this work without modification to the code?

    #23829
    Denwis La
    Participant

    It also didn’t work without modification. I tried the dot->sleep(time, mDOT::RTC_ALARM_OR_INTERRUPT, false) function by itself and it also didn’t wake up when compiled with the offline compiler.

    #23847
    Ryan Klaassen
    Blocked

    The code works on my end. Can you confirm you are using mbed-os-5.4.7 and GCC 4.9?
    cmd for GCC arm version: mbed config GCC_ARM_PATH
    cmd for mbed-os version: git describe –match mbed-os*

    #23848
    Denwis La
    Participant
    <code>mbed-os (#fc1836545dcc, tags: mbed-os-5.4.7, mbed_lib_rev144)
      * mbed-os-5.1.0
      * mbed-os-5.1.1
      * mbed-os-5.1.2
      * mbed-os-5.1.3
      * mbed-os-5.1.4
      * mbed-os-5.1.5
      * mbed-os-5.2.0
      * mbed-os-5.2.1
      * mbed-os-5.2.2
      * mbed-os-5.2.3
      * mbed-os-5.3.0
      * mbed-os-5.3.1
      * mbed-os-5.3.2
      * mbed-os-5.3.3
      * mbed-os-5.3.4
      * mbed-os-5.3.5
      * mbed-os-5.3.6
      * mbed-os-5.4.0
      * mbed-os-5.4.1
      * mbed-os-5.4.2
      * mbed-os-5.4.3
      * mbed-os-5.4.4
      * mbed-os-5.4.5
      * mbed-os-5.4.6
      * mbed-os-5.4.7  <- current</code>

    Is what it shows when I check which mbed-os I’m on with mbed releases.
    And with git describe –match mbed-os* within mbed-os directory it gives the same version as well: mbed-os-5.4.7.
    <code> [mbed] C:\Program Files (x86)\GNU Tools ARM Embedded\4.9 2015q3\bin </code>
    Is what I get when I use command mbed config GCC_ARM_PATH.

Viewing 9 posts - 1 through 9 (of 9 total)
  • You must be logged in to reply to this topic.