mcci-catena / arduino-lmic

LoraWAN-MAC-in-C library, adapted to run under the Arduino environment
https://forum.mcci.io/c/device-software/arduino-lmic/
MIT License
640 stars 208 forks source link

EV_TXSTART EV_JOIN_TXCOMPETE:no JoinAccept #827

Open liuhengjing-sudo opened 2 years ago

liuhengjing-sudo commented 2 years ago

Consider raising support questions on the forum first

There is a discussion site, forum.mcci.io, which includes a category focused on the Arduino LMIC. Unless you're sure that your problem is a bug in the LMIC, it would be great if you can try for help there first. That will keep issues focused on work that needs to be done by the developers.

Describe your question or issue

Please give a clear and concise description of the problem you're facing and what you'd like help with.

Environment

This information is very important; it's hard to help without a complete set of answers.

Hello

I am using lora shield v1.4 and arduino uno and au915 and using the ttn-otaa example The port monitoring only show EV_TXSTART EV_JOIN_TXCOMPLETE :no join accept And my applicant data in TTN is no data appear My gateway is self-build single channel using rasp pi and lora shield v1.4 and there are no data appear on gateway in TTN

my pin mapping is const lmic_pinmap lmic_pins = { .nss = 10, .rxtx = LMIC_UNUSED_PIN, .rst = 5, .dio = {2, 3, LMIC_UNUSED_PIN}, };

Any help will be grateful Thanks !

terrillmoore commented 2 years ago

Hi,

Sorry you're having problems.

If you have two devices, please use the raw sketch to confirm radio tx/rx performance.

After that, try setting the clock error to a large tolerance, e.g. LMIC_setClockError(MAX_CLOCK_ERROR * 20 / 1000). Also, at the same time, in your project configuration file, add #define LMIC_ENABLE_arbitrary_clock_error 1. This often helps.

If not, please share your project config file and test sketch.

Best regards, --Terry

liuhengjing-sudo commented 2 years ago

Thanks for your detailed and quick reply I am sorry I am very new in the Lora. After I put LMIC_setClockError(MAX_CLOCK_ERROR * 20 / 1000) before dosend() in ttn-otaa, and put #define LMIC_ENABLE_arbitrary_clock_error 1 in Arduino\libraries\arduino-lmic-master\project_config. I get this in my rasp pi terminal image However I still get EV_TXSTART EV_JOIN_TXCOMPLETE :no join accept in arduino port monitoring. image

my sketch code is

include

include <hal/hal.h>

include

// // For normal use, we require that you edit the sketch to replace FILLMEIN // with values assigned by the TTN console. However, for regression tests, // we want to be able to compile these scripts. The regression tests define // COMPILE_REGRESSION_TEST, and in that case we define FILLMEIN to a non- // working but innocuous value. //

ifdef COMPILE_REGRESSION_TEST

define FILLMEIN 0

else

warning "You must replace the values marked FILLMEIN with real values from the TTN control panel!"

define FILLMEIN (#dont edit this, edit the lines that use FILLMEIN)

endif

// This EUI must be in little-endian format, so least-significant-byte // first. When copying an EUI from ttnctl output, this means to reverse // the bytes. For TTN issued EUIs the last bytes should be 0xD5, 0xB3, // 0x70. static const u1_t PROGMEM APPEUI[8]={0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; void os_getArtEui (u1_t* buf) { memcpy_P(buf, APPEUI, 8);}

// This should also be in little endian format, see above. static const u1_t PROGMEM DEVEUI[8]= {0x70, 0xB3, 0xD5, 0x7E, 0xD0, 0x04, 0x9C, 0x26}; void os_getDevEui (u1_t* buf) { memcpy_P(buf, DEVEUI, 8);}

// This key should be in big endian format (or, since it is not really a // number but a block of memory, endianness does not really apply). In // practice, a key taken from ttnctl can be copied as-is. static const u1_t PROGMEM APPKEY[16] = {0xC2, 0x19, 0xBF, 0x2F, 0x4F, 0xC0, 0x87, 0x89, 0x6A, 0xDA, 0x59, 0xCA, 0x18, 0x8E, 0xFA, 0x07}; void os_getDevKey (u1_t* buf) { memcpy_P(buf, APPKEY, 16);}

static uint8_t mydata[] = "Hello, world!"; static osjob_t sendjob;

// Schedule TX every this many seconds (might become longer due to duty // cycle limitations). const unsigned TX_INTERVAL = 60;

// Pin mapping const lmic_pinmap lmic_pins = { .nss = 10, .rxtx = LMIC_UNUSED_PIN, .rst = 5, .dio = {2, 3, 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(); } // Disable link check validation (automatically enabled // during join, but because slow data rates change max TX // size, we don't use it in this example. LMIC_setLinkCheckMode(0); break; /* This event is defined but not used in the code. No point in wasting codespace on it.
case EV_RFU1:
Serial.println(F("EV_RFU1"));
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("Received "));
          Serial.print(LMIC.dataLen);
          Serial.println(F(" bytes of payload"));
        }
        // Schedule next transmission
        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;
    /*
    || This event is defined but not used in the code. No
    || point in wasting codespace on it.
    ||
    || case EV_SCAN_FOUND:
    ||    Serial.println(F("EV_SCAN_FOUND"));
    ||    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(1, mydata, sizeof(mydata)-1, 0); Serial.println(F("Packet queued")); } // Next TX is scheduled after TX_COMPLETE event. }

void setup() { Serial.begin(9600); Serial.println(F("Starting"));

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

// LMIC init
os_init();
// Reset the MAC state. Session and pending data transfers will be discarded.
LMIC_reset();

// Use with Arduino Pro Mini ATmega328P 3.3V 8 MHz
// Let LMIC compensate for +/- 1% clock error
LMIC_setClockError(MAX_CLOCK_ERROR * 20 / 1000);

// Start job (sending automatically starts OTAA too)
do_send(&sendjob);

}

void loop() { os_runloop_once(); }

and my project config file is in libraries image image image

the rasp pi code is come from this link , which is compiled by sudo ./single-chanel-ptk-fwd very appreciate!

terrillmoore commented 2 years ago

A Join message is always sent at SF10. The "single channel gateway" is listening at SF7. This means that it won't hear the JoinRequest message (for non-gateway LoRa chips, the TX and RX SF must match (as must the frequency).

The LMIC can't easily be changed to use SF7 for JoinRequest, but perhaps the SingleChannel gateway software can be changed to always listen on SF10 rather than SF7.

Single channel gateways are very troublesome and are the very hardest way to get started with LoRa. I strongly suggest spending a little money (US $80) for a Things Network Indoor Gateway. Whoever introduced single-channel gateways did learners a great disservice, because it looks like an inexpensive way to start. But it also leads to frustration and gives a distorted view of the technology. (I'm not sure TTN really supports single-channel gateways, in fact.)

liuhengjing-sudo commented 2 years ago

Thanks for your reply After I put the gateway outdoor just the yard, the node is connected and send the uplink message slowly. However after I want retry this, there is loop in Applicant live data: Forward join accept message Accept join request

The port monitoring in arduino is still no join accept I try SF10 it does not work And I try the ttn ABP, with the DEVADRR NESKEY APPSKEY from this end device in Applicant which gives me failure message in port monitoring. I am still adjust the distance between gateway and the node, sometimes the applicant shoews that the joint sever failed, I am not sure what is the problem right now

But Thanks again!

jpmeijers commented 2 years ago

After that, try setting the clock error to a large tolerance, e.g. LMIC_setClockError(MAX_CLOCK_ERROR * 20 / 1000). Also, at the same time, in your project configuration file, add #define LMIC_ENABLE_arbitrary_clock_error 1. This often helps.

Thanks for this @terrillmoore. My devices didn't want to join on SF7, even though I had a gateway very close. Adding the clock error compensation allowed them to join at the first try.

Without the clock error set:

1912 - Compiled: Jun 22 2022, 11:40:38, 7.3.0
1916 - Clock cycles per us: 8
1919 - App EUI: <redacted>
1921 - Dev EUI: <redacted>
1923 - App Key: <redacted>
2372 - BME280 forced read
2475 - Temperature:20.20°C
2478 - Humidity:63.20%
2480 - Pressure:1006.13hPa
2530 - Packet queued
2532 - 101176 (1618 ms): EV_JOINING
10480 - 597805 (9564 ms): EV_TXSTART: ch=2 rps=0x01 (SF7 BW125 CR 4/5 Crc IH=0), datarate=5, opmode=88C, txend=597692, avail=0
15545 - 914423 (14630 ms): EV_RXSTART: freq=868.5 rps=0x81 (SF7 BW125 CR 4/5 NoCrc IH=0), datarate=5, opmode=88C, txend=602084, avail=0, rxtime=914459, rxsyms=8
16544 - 976593 (15625 ms): EV_RXSTART: freq=869.5 rps=0x86 (SF12 BW125 CR 4/5 NoCrc IH=0), datarate=5, opmode=88C, txend=602084, avail=0, rxtime=976959, rxsyms=7
16785 - 992052 (15872 ms): EV_JOIN_TXCOMPLETE, saveIrqFlags 0x80, nLateRx=1 ticks=100
75633 - 4669944 (74719 ms): EV_TXSTART: ch=1 rps=0x01 (SF7 BW125 CR 4/5 Crc IH=0), datarate=5, opmode=88C, txend=4669933, avail=0
80699 - 4986575 (79785 ms): EV_RXSTART: freq=868.3 rps=0x81 (SF7 BW125 CR 4/5 NoCrc IH=0), datarate=5, opmode=88C, txend=4674244, avail=0, rxtime=4986619, rxsyms=8
81698 - 5048772 (80780 ms): EV_RXSTART: freq=869.5 rps=0x86 (SF12 BW125 CR 4/5 NoCrc IH=0), datarate=5, opmode=88C, txend=4674244, avail=0, rxtime=5049119, rxsyms=7
81942 - 5064232 (81027 ms): EV_JOIN_TXCOMPLETE, saveIrqFlags 0x80, nLateRx=2 ticks=193
140729 - 8738447 (139815 ms): EV_TXSTART: ch=0 rps=0x01 (SF7 BW125 CR 4/5 Crc IH=0), datarate=5, opmode=88C, txend=8737983, avail=0
145795 - 9055099 (144881 ms): EV_RXSTART: freq=868.1 rps=0x81 (SF7 BW125 CR 4/5 NoCrc IH=0), datarate=5, opmode=88C, txend=8742756, avail=0, rxtime=9055131, rxsyms=8
146793 - 9117306 (145876 ms): EV_RXSTART: freq=869.5 rps=0x86 (SF12 BW125 CR 4/5 NoCrc IH=0), datarate=5, opmode=88C, txend=8742756, avail=0, rxtime=9117631, rxsyms=7
147036 - 9132754 (146124 ms): EV_JOIN_TXCOMPLETE, saveIrqFlags 0x80, nLateRx=3 ticks=299
206228 - 12832195 (205315 ms): EV_TXSTART: ch=2 rps=0x02 (SF8 BW125 CR 4/5 Crc IH=0), datarate=4, opmode=88C, txend=12832164, avail=0
211345 - 13152007 (210432 ms): EV_RXSTART: freq=868.5 rps=0x82 (SF8 BW125 CR 4/5 NoCrc IH=0), datarate=4, opmode=88C, txend=12839668, avail=0, rxtime=13152043, rxsyms=7
211536 - 13162885 (210606 ms): EV_JOINED: ch=2
211540 - netid: 19
211541 - devaddr: 260B1FFC
211543 - artKey: A0-0C-F4-6A-FF-A8-2E-F3-E9-AB-33-E8-E3-29-A1-F0
211548 - nwkKey: 11-A5-0B-92-35-28-73-69-85-9D-BB-94-8C-D3-F6-8B
211553 - 13163935 (210622 ms): EV_TXSTART: ch=1 rps=0x02 (SF8 BW125 CR 4/5 Crc IH=0), datarate=4, opmode=888, txend=13162515, avail=0
216690 - 13486038 (215776 ms): EV_RXSTART: freq=868.3 rps=0x82 (SF8 BW125 CR 4/5 NoCrc IH=0), datarate=4, opmode=888, txend=13173706, avail=0, rxtime=13486081, rxsyms=7
217688 - 13548264 (216772 ms): EV_RXSTART: freq=869.5 rps=0x83 (SF9 BW125 CR 4/5 NoCrc IH=0), datarate=4, opmode=888, txend=13173706, avail=0, rxtime=13548581, rxsyms=7
217728 - 13551116 (216817 ms): EV_TXCOMPLETE: ch=1 rps=0x83 (SF9 BW125 CR 4/5 NoCrc IH=0), txrxFlags=0x20, FcntUp=0001, FcntDn=0000, txend=13173706, avail=13582361, nLateRx=5 ticks=494
217749 - TX done
m-andreev commented 1 year ago

OK guys, I had the same problem, so let me tell you how I fixed it : I went to lmic.project.config , and there I disabled all the region settings and just left #define LMIC_ENABLE_arbitrary_clock_error 1 and #define CFG_sx1276_radio 1 , then you go to your basic settings .ini file -> in my case is platformio.ini and there you must add your region like this :

build_flags = -D CFG_eu868=1

This worked for me, let's hope it will help somebody too. :)