Sometime, disconnect between Esp32 and gateway by use LMIC.h

Hi everyone.
I have problem about sometime disconnect between esp32 and gateway by use LMIC.h. Now, i cannot solve the problem. can we recommend me or explain this problem what cause? and how to solve?
I need to explain solution: Esp32 already join lora OTAA with gateway by used LMIC.h. Sometime, the node didn’t uplink then i cannot send downlink from MQTT to node. but sometime, the node already join with gateway.
Then my problem: Node didn’t join lora with gateway real time.
Firmware:
#include <lmic.h>
#include <hal/hal.h>
#include <SPI.h>
#include <esp_task_wdt.h>
//3 seconds WDT
#define WDT_TIMEOUT 900
// Relay
int value[3] = {};
char tmp[2];
int arr_relaypin = {0, 13, 25, 26, 33};//k1,k3,k2,k4
int arr_size = 4;
// LoRaWan
// f6 f4 f5 6a 29 67 bc 65
static const u1_t PROGMEM APPEUI[8]={ 0x65, 0xbc, 0x67, 0x29, 0x6a, 0xf5, 0xf4, 0xf6 };
void os_getArtEui (u1_t* buf) { memcpy_P(buf, APPEUI, 8);}

// f6 f4 f5 6a 29 67 bc 65
static const u1_t PROGMEM DEVEUI[8]={ 0x65, 0xbc, 0x67, 0x29, 0x6a, 0xf5, 0xf4, 0xf6 };
void os_getDevEui (u1_t* buf) { memcpy_P(buf, DEVEUI, 8);}

// 6c c7 47 66 52 98 e3 92 4e c1 53 27 1e 19 af ca
static const u1_t PROGMEM APPKEY[16] = { 0x6c, 0xc7, 0x47, 0x66, 0x52, 0x98, 0xe3, 0x92, 0x4e, 0xc1, 0x53, 0x27, 0x1e, 0x19, 0xaf, 0xca };
void os_getDevKey (u1_t* buf) { memcpy_P(buf, APPKEY, 16);}

static uint8_t mydata = “00”;
static osjob_t sendjob;

// Schedule TX every this many seconds (might become longer due to duty
// cycle limitations).
const unsigned TX_INTERVAL = 10; // หน่วยเป็นวินาที

// Pin mapping
const lmic_pinmap lmic_pins = {
.nss = 18,
.rxtx = LMIC_UNUSED_PIN,
.rst = 14,
.dio = {2, 4, LMIC_UNUSED_PIN},
};

void printHex2(unsigned v) {
v &= 0xff;
if (v < 16)
Serial.print(‘0’);
Serial.print(v, HEX);
}

void onEvent (ev_t ev) {
Serial.print(os_getTime());
Serial.print(": ");
switch(ev) {
case EV_SCAN_TIMEOUT:
Serial.println(F(“EV_SCAN_TIMEOUT”));
break;
case EV_BEACON_FOUND:
Serial.println(F(“EV_BEACON_FOUND”));
break;
case EV_BEACON_MISSED:
Serial.println(F(“EV_BEACON_MISSED”));
break;
case EV_BEACON_TRACKED:
Serial.println(F(“EV_BEACON_TRACKED”));
break;
case EV_JOINING:
Serial.println(F(“EV_JOINING”));
break;
case EV_JOINED:
Serial.println(F(“EV_JOINED”));
{
u4_t netid = 0;
devaddr_t devaddr = 0;
u1_t nwkKey[16];
u1_t artKey[16];
LMIC_getSessionKeys(&netid, &devaddr, nwkKey, artKey);
Serial.print("netid: ");
Serial.println(netid, DEC);
Serial.print(“devaddr: “);
Serial.println(devaddr, HEX);
Serial.print(“AppSKey: “);
for (size_t i=0; i<sizeof(artKey); ++i) {
if (i != 0)
Serial.print(”-”);
printHex2(artKey[i]);
}
Serial.println(””);
Serial.print(“NwkSKey: “);
for (size_t i=0; i<sizeof(nwkKey); ++i) {
if (i != 0)
Serial.print(”-”);
printHex2(nwkKey[i]);
}
Serial.println();
}
LMIC_setLinkCheckMode(0);
break;

    case EV_JOIN_FAILED:
        Serial.println(F("EV_JOIN_FAILED"));
        break;
    case EV_REJOIN_FAILED:
        Serial.println(F("EV_REJOIN_FAILED"));
        break;
    case EV_TXCOMPLETE:
        Serial.println(F("EV_TXCOMPLETE (includes waiting for RX windows)"));
        if (LMIC.txrxFlags & TXRX_ACK)
          Serial.println(F("Received ack"));
        if (LMIC.dataLen) {
          Serial.print(F("Data Received: "));
          String dpayload = "";    
          char temp[3];
          for(uint8_t i=0;i<LMIC.dataLen;i++)
          {
            // Serial.println(i);
            Serial.print(LMIC.frame[LMIC.dataBeg + i], HEX);
            // sprintf(temp, "%02x", LMIC.frame[LMIC.dataBeg + i]); 
            sprintf(temp ,"%x", LMIC.frame[LMIC.dataBeg + i]);
            dpayload = String(dpayload) + String(temp);
          }  
          Serial.println(dpayload);
          Serial.println();
          if(dpayload != ""){

            pinMode(arr_relaypin[1], OUTPUT);
            pinMode(arr_relaypin[2], OUTPUT);
            pinMode(arr_relaypin[3], OUTPUT);
            pinMode(arr_relaypin[4], OUTPUT);
            dpayload = dpayload.substring(0, 12);

            if (dpayload.length() == 12) {
              String cmd_status = String(dpayload.substring(1, 2)) + String(dpayload.substring(3, 4)); 
              String cmd_pin = dpayload.substring(5, 6) + dpayload.substring(7, 8);  
              String cmd_time = dpayload.substring(9, 10) + dpayload.substring(11, 12);       
              int pin = cmd_pin.toInt();
              long timedelay = cmd_time.toInt() * 1000* 60 ;

              if(cmd_status =="01"){
                for(int i = 1; i <= arr_size; i++){
                  Serial.print(String(i) + ". Pin "+String(arr_relaypin[i])+ " Status: ");
                  Serial.println(digitalRead(arr_relaypin[i])); 
                  sprintf(tmp,"%02d",digitalRead(arr_relaypin[i])); 
                }  
              }else if(cmd_status =="02"){
                if(cmd_pin=="99"){
                  Serial.println("Payload: " + dpayload);  
                  Serial.println("Relay No: BOTH");
                  Serial.println("Turn On...");
                  
                  for(int i = 1; i<= arr_size; i++){
                    digitalWrite(arr_relaypin[i], HIGH);
                  }
                  
                  Serial.print("Delay: ");
                  Serial.print(timedelay);
                  Serial.println(" ms");
                  delay( timedelay );
                  
                  for(int i = 1; i<= arr_size; i++){
                    digitalWrite(arr_relaypin[i], LOW);
                  }
                  
                  Serial.println("Turn Off...");
                }else{

                  Serial.println("Payload: " + dpayload);  
                  Serial.print("Relay No: ");
                  Serial.println(pin);
                  
                  Serial.print("Pin: ");
                  Serial.println(arr_relaypin[pin]);
                  
                  Serial.println("Turn On...");
                  digitalWrite(arr_relaypin[pin], HIGH);
                  
                  Serial.print("Delay: ");
                  Serial.print(timedelay);
                  Serial.println(" ms");
                  delay( timedelay );
                  
                  digitalWrite(arr_relaypin[pin], LOW);
                  Serial.println("Turn Off...");
                }           
              }  
            }else{
              Serial.println("!! Package Lost : Payload Error !!"); 
              Serial.print("Payload: ");
              Serial.println(dpayload);  
            }
             
          }


          Serial.println();
        } 
        esp_task_wdt_reset();
        os_setTimedCallback(&sendjob, os_getTime()+sec2osticks(TX_INTERVAL), do_send);
        break;
    case EV_LOST_TSYNC:
        Serial.println(F("EV_LOST_TSYNC"));
        break;
    case EV_RESET:
        Serial.println(F("EV_RESET"));
        break;
    case EV_RXCOMPLETE:
        // data received in ping slot
        Serial.println(F("EV_RXCOMPLETE"));
        break;
    case EV_LINK_DEAD:
        Serial.println(F("EV_LINK_DEAD"));
        break;
    case EV_LINK_ALIVE:
        Serial.println(F("EV_LINK_ALIVE"));
        break;
    
    case EV_TXSTART:
        Serial.println(F("EV_TXSTART"));
        break;
    case EV_TXCANCELED:
        Serial.println(F("EV_TXCANCELED"));
        break;
    case EV_RXSTART:
        /* do not print anything -- it wrecks timing */
        break;
    case EV_JOIN_TXCOMPLETE:
        Serial.println(F("EV_JOIN_TXCOMPLETE: no JoinAccept"));
        break;

    default:
        Serial.print(F("Unknown event: "));
        Serial.println((unsigned) ev);
        break;
}

}

void do_send(osjob_t* j){
// Check if there is not a current TX/RX job running
if (LMIC.opmode & OP_TXRXPEND) {
Serial.println(F(“OP_TXRXPEND, not sending”));
} else {
// Prepare upstream data transmission at the next possible time.
LMIC_setTxData2(22, mydata, sizeof(mydata)-1, 0);
Serial.println(F(“Packet queued”));
}
}

void setup() {
Serial.begin(115200);
Serial.println(F(“Starting”));

#ifdef VCC_ENABLE
// For Pinoccio Scout boards
pinMode(VCC_ENABLE, OUTPUT);
digitalWrite(VCC_ENABLE, HIGH);
delay(1000);
#endif

Serial.println("Configuring WDT...");
esp_task_wdt_init(WDT_TIMEOUT, true); //enable panic so ESP32 restarts
esp_task_wdt_add(NULL); //add current thread to WDT watch

for(int i = 1; i<= arr_size; i++){
  digitalWrite(arr_relaypin[i], LOW);
} 

// LMIC init
os_init();
// Reset the MAC state. Session and pending data transfers will be discarded.
LMIC_reset();
LMIC_setDrTxpow(DR_SF9,14);
LMIC_setClockError(MAX_CLOCK_ERROR * 10 / 100);
// Start job
do_send(&sendjob);

}

int i = 0;
int last = millis();

void loop() {
os_runloop_once();
}

Welcome to TTN.

? your sending from the node every 10 seconds?

Are you aware of the fair use policy ?

Set the time to something like 600 seconds perhaps, and see if you have the same problem ?

Also remember this is not WiFi - your device does not join a GW it joins, and connects to, a network…here TTS(CE) aka TTN V3. The GW is just a device that passes messages to/from the network - a media convertor if you will - changing RF LoRa(WAN) messages into Internet (IP) messages adding some metadata along the way and vice versa. The GW has no knowledge of the state or credentials of the device and the device doesnt care about the nature of the GW - only caring if messages handled/passed correctly.

That is normal Class A node behaviour (default) - downlinks can only happen after uplinks (in the RX1 or RX2 windows) - no uplink received at LNS = NO downlink set back. Message may not send up if device has exhausted it airtime duty cycle (See Stuart’s comment with respect to abusive TX rate above)

Note also regular Downlinks discouraged on the community network, with again a FUP applied if they are a must have (forum search…)

Thank you for your answer to me.
Now, i under test follow your comment. Concern the result, i will inform you again.

Dear LoRa Tracker
I already change time of TX_INTERVAL=10 to TX_INTERVAL=60 cannot follow your recommend due to user cannot wait. But the result after test TX_INTERVAL=60 result not same with TX_INTERVAL=10.
Now, Esp32 join lora with gateway real time. then i need to confirm the cause can you explain to me?
Thank you

If the user wants to send the payload that often, its outside the scope of TTN support and you need to contact TTI and pay for the connection.