How to persist LMIC OTAA parameters with an ESP32?

@JackGruber It seems like that it was only luck that your code did something. I wondered that my node only used one channel (with your code modified in the post above this one ) and started investigating

First of all I noticed that the array with the bands is missing which stores the duty cycles and the usages of the channel etc.

When I was typing the corresponding memcpy command I noticed that you switched the destination and the source parameter in your code . Also MAX_CHANNELS as the size parameter is wrong because the command wants a size in bytes and not the count of array entries. So we need to multiply MAX_CHANNELS with the size of the array entries:

memcpy(RTC_LORAWAN_channelDrMap, LMIC.channelDrMap, MAX_CHANNELS*sizeof(u2_t));

It would be nice if you change this in your code block so that other readers of this thread don’t copy a switched memcpy :slight_smile:

Currently this code block is working ( I did something with the duty cycle because after deep sleep the ESP resets the system clock):

RTC_DATA_ATTR u4_t RTC_LORAWAN_netid = 0;
RTC_DATA_ATTR devaddr_t RTC_LORAWAN_devaddr = 0;
RTC_DATA_ATTR u1_t RTC_LORAWAN_nwkKey[16];
RTC_DATA_ATTR u1_t RTC_LORAWAN_artKey[16];
RTC_DATA_ATTR u4_t RTC_LORAWAN_seqnoUp = 0;
RTC_DATA_ATTR u4_t RTC_LORAWAN_seqnoDn;
RTC_DATA_ATTR u1_t RTC_LORAWAN_dn2Dr;
RTC_DATA_ATTR u1_t RTC_LORAWAN_dnConf;
RTC_DATA_ATTR s1_t RTC_LORAWAN_adrTxPow;
RTC_DATA_ATTR u1_t RTC_LORAWAN_txChnl;
RTC_DATA_ATTR s1_t RTC_LORAWAN_datarate;
RTC_DATA_ATTR u4_t RTC_LORAWAN_channelFreq[MAX_CHANNELS];
RTC_DATA_ATTR u2_t RTC_LORAWAN_channelDrMap[MAX_CHANNELS];
RTC_DATA_ATTR u4_t RTC_LORAWAN_channelDlFreq[MAX_CHANNELS];
RTC_DATA_ATTR band_t RTC_LORAWAN_bands[MAX_BANDS];
RTC_DATA_ATTR u2_t RTC_LORAWAN_channelMap;
RTC_DATA_ATTR s2_t RTC_LORAWAN_adrAckReq;
RTC_DATA_ATTR u1_t RTC_LORAWAN_rx1DrOffset;
RTC_DATA_ATTR u1_t RTC_LORAWAN_rxDelay;



void Sleep(int sleepSeconds)
{
    Serial.println(F("Save LMIC to RTC ..."));
    RTC_LORAWAN_netid = LMIC.netid;
    RTC_LORAWAN_devaddr = LMIC.devaddr;
    memcpy(RTC_LORAWAN_nwkKey, LMIC.nwkKey, 16);
    memcpy(RTC_LORAWAN_artKey, LMIC.artKey, 16);
    RTC_LORAWAN_dn2Dr = LMIC.dn2Dr;
    RTC_LORAWAN_dnConf = LMIC.dnConf;
    RTC_LORAWAN_seqnoDn = LMIC.seqnoDn;
    RTC_LORAWAN_seqnoUp = LMIC.seqnoUp;
    RTC_LORAWAN_adrTxPow = LMIC.adrTxPow;
    RTC_LORAWAN_txChnl = LMIC.txChnl;
    RTC_LORAWAN_datarate = LMIC.datarate;
    RTC_LORAWAN_adrAckReq = LMIC.adrAckReq;
    RTC_LORAWAN_rx1DrOffset = LMIC.rx1DrOffset;
    RTC_LORAWAN_rxDelay = LMIC.rxDelay;
    memcpy(RTC_LORAWAN_channelFreq, LMIC.channelFreq, MAX_CHANNELS*sizeof(u4_t));
    memcpy(RTC_LORAWAN_channelDrMap, LMIC.channelDrMap, MAX_CHANNELS*sizeof(u2_t));
    memcpy(RTC_LORAWAN_channelDlFreq, LMIC.channelDlFreq, MAX_CHANNELS*sizeof(u4_t));
    memcpy(RTC_LORAWAN_bands, LMIC.bands, MAX_BANDS*sizeof(band_t));
    RTC_LORAWAN_channelMap = LMIC.channelMap;
    
    //System time is resetted after sleep. So we need to calculate the dutycycle with a resetted system time
    delay(random(1000));
    unsigned long now = millis();
    Serial.println(now);
    for(int i = 0; i < MAX_BANDS; i++) {
        ostime_t correctedAvail = RTC_LORAWAN_bands[i].avail - ((now/1000.0 + sleepSeconds ) * OSTICKS_PER_SEC);
        if(correctedAvail < 0) {
            correctedAvail = 0;
        }
        RTC_LORAWAN_bands[i].avail = correctedAvail;
    }
    esp_sleep_enable_timer_wakeup(1000000 * sleepSeconds);
    esp_deep_sleep_start();
}

void Wakeup()
{
    Serial.println(F("Load LMIC from RTC ..."));
    
    LMIC_setSession(RTC_LORAWAN_netid, RTC_LORAWAN_devaddr, RTC_LORAWAN_nwkKey, RTC_LORAWAN_artKey);
    LMIC_setSeqnoUp(RTC_LORAWAN_seqnoUp);
    LMIC_setDrTxpow(RTC_LORAWAN_datarate, RTC_LORAWAN_adrTxPow);
    memcpy(LMIC.bands, RTC_LORAWAN_bands, MAX_BANDS*sizeof(band_t));
    memcpy(LMIC.channelFreq, RTC_LORAWAN_channelFreq, MAX_CHANNELS*sizeof(u4_t));
    memcpy(LMIC.channelDlFreq, RTC_LORAWAN_channelDlFreq, MAX_CHANNELS*sizeof(u4_t));
    memcpy(LMIC.channelDrMap, RTC_LORAWAN_channelDrMap, MAX_CHANNELS*sizeof(u2_t));
    LMIC.seqnoDn = RTC_LORAWAN_seqnoDn;
    LMIC.dnConf = RTC_LORAWAN_dnConf;
    LMIC.adrAckReq = RTC_LORAWAN_adrAckReq;
    LMIC.dn2Dr = RTC_LORAWAN_dn2Dr;
    LMIC.rx1DrOffset = RTC_LORAWAN_rx1DrOffset;
    LMIC.rxDelay = RTC_LORAWAN_rxDelay;
    LMIC.txChnl = RTC_LORAWAN_txChnl;
    LMIC.channelMap = RTC_LORAWAN_channelMap;
}

Im sure that there are some attributes missing. I will add them in this post when I know about them :slight_smile:

Anyway: Thank you @JackGruber for giving me the right hint to persist the attributes in the RTC :slight_smile: This was really helpful!

1 Like