manuelbl / ttn-esp32

The Things Network device library for ESP32 (ESP-IDF) and SX127x based devices
MIT License
309 stars 64 forks source link

Understanding the need of re-join #30

Closed vrees closed 1 year ago

vrees commented 4 years ago

My application wakes up from deep sleep every hour and sends sensor data to TTN. The code basically follows the hello_world example and works quite well with my self developed ESP32 board in platform.io:

extern "C" void app_main(void) {
      :
    ttn.configurePins(TTN_SPI_HOST, TTN_PIN_NSS, TTN_PIN_RXTX, TTN_PIN_RST, TTN_PIN_DIO0, TTN_PIN_DIO1);
    ttn.provision(devEui, appEui, appKey);
    ttn.onMessage(messageReceived);

    readSensorValues();

    if (ttn.join()) {
        printf("Joined.\n");
        xTaskCreate(sendMessages, "send_messages", 1024 * 4, (void *)0, 3, nullptr);
    }
    else {
        printf("Join failed. Goodbye\n");
    } 
}

After sending the sensor values to TTN the processor is falling into sleep using:

ttn.shutdown();
esp_deep_sleep_start();

So each time the ESP32 wakes up a ttn.join() is performed. As mentioned on Best Practices on the TTN page "devices should perform join operations the less possible in their lifetime".

So I am looking for a solution to do the join operation only once or only when needed. I cannot find something like public bool isJoined() in the API documentation.

Or ist there an another approach for this kind of application?

manuelbl commented 4 years ago

Even though it's in high demand, this library does not yet support deep sleep as the underlying LMIC library does not support it.

In order to avoid rejoining, many parameters (session key, data rate, last used channels etc.) have to be saved and restored and the clock has to be restored as well. The best approach I've seen so far is https://github.com/diplfranzhoepfinger/ttn-esp32. It saves the entire LMIC structure into RTC memory and restores the clock. LMIC is quite a large structure but the ESP32 has sufficient RTC memory.

So you options are:

I hope that the underlying LMIC library will implement deep sleep. Then this library can easily be enhanced.

DaviWT commented 3 years ago

The best approach I've seen so far is https://github.com/diplfranzhoepfinger/ttn-esp32. It saves the entire LMIC structure into RTC memory and restores the clock.

I'm interested in this modified implementation but I couldn't understand how to use it. Does it already saves LMIC structure or do I need to call other methods?

For example, what would I need to change at /examples/shutdown/main.cpp to adapt to this new implementation?

Thanks in advance.

manuelbl commented 3 years ago

@DaviWT I've seen that you have opened an issue in https://github.com/diplfranzhoepfinger/ttn-esp32. That's a better place to ask question about his implementation.

manuelbl commented 3 years ago

Despite the missing support in the underlying LMIC library, I've added support for going into deep sleep and for powering off the ESP32 while retaining the state of the current TTN session.

It should considerably simplify these use cases. It takes care of all the details like when can the device go to sleep (if MAC commands need confirmation), what needs to be saved, handling the clock (very important) etc.

Any feedback is appreciated.