ส่งความถี่เดียว LoRaWan

Credit:  arjanvanbArjan

https://www.thethingsnetwork.org/forum/t/can-lmic-1-6-be-set-up-to-use-a-single-channel-and-sf/5207/11


For 1.5, if one does not want to change the library, here is how one can make an ABP or OTAA sketch work with a single channel gateway and Matthijs Kooijman’s LMiC16:
  • Somewhere above onEvent define:
    // Define the single channel and data rate (SF) to use
    int channel = 0;
    int dr = DR_SF7;
    
    // Disables all channels, except for the one defined above, and sets the
    // data rate (SF). This only affects uplinks; for downlinks the default
    // channels or the configuration from the OTAA Join Accept are used.
    //
    // Not LoRaWAN compliant; FOR TESTING ONLY!
    //
    void forceTxSingleChannelDr() {
        for(int i=0; i<9; i++) { // For EU; for US use i<71 span="">
            if(i != channel) {
                LMIC_disableChannel(i);
            }
        }
        // Set data rate (SF) and transmit power for uplink
        LMIC_setDrTxpow(dr, 14);
    }
    
  • For ABP, in init() replace LMIC_setDrTxpow(DR_SF7,14);15 with:
    // Only use one channel and SF
    forceTxSingleChannelDr();
    
  • For OTAA, in init() after LMIC_reset();14 add:
    // Make LMiC initialize the default channels, choose a channel, and
    // schedule the OTAA join
    LMIC_startJoining();
    
    // LMiC will already have decided to send on one of the 3 default
    // channels; ensure it uses the one we want
    LMIC.txChnl = channel;
    
    // ...and make sure we see the EV_JOINING event being logged
    os_runloop_once();
    
  • For OTAA, for EV_JOINED in onEvent use:
    case EV_JOINED:
        // Ignore the channels from the Join Accept
        forceTxSingleChannelDr();
    
        // Disable link check validation (automatically enabled during join)
        LMIC_setLinkCheckMode(0);
    
        break;
    
But note:
  • Only tested with LMiC 1.5, for EU868, channel 0.
  • For OTAA this assumes the first attempt succeeds; if the Join Request or Join Accept are somehow lost, LMiC will still try different channels and data rates due to the logic in nextJoinState.
  • Only tested with an OTAA Join Accept received in RX1 (for EU868 using the same channel as the uplink/join request); when received in RX2 (for EU868 always using 869.525 on SF91), LMiC might also use other values to send? (But maybe the LMIC_setDrTxpow(dr, 14) suffices.)

Background

For Matthijs’ LMiC 1.5, the OTAA flow is:
  • In examples/ttn-otaa/ttn-otaa.ino14, calling LMIC_reset clears the keys after which LMIC_setTxData2 is called to schedule some data to be sent.
  • In src/lmic.c3engineUpdate controls the flow, like if something has been scheduled for transmission. When LMIC.devaddr == 0 this will first trigger LMIC_startJoining:
    • LMIC_startJoining calls initJoinLoop, which for EU868 also calls initDefaultChannels. (For US915, that’s already done in LMIC_reset.)
    • In initJoinLoop, for EU868 one out of 3 channels is selected (LMIC.txChnl = os_getRndU1() % 3) while for US915 it’s set to the first channel (LMIC.txChnl = 0).
    • The actual join is not started yet; LMIC_startJoining basically schedules joining to be the first thing to do when time permits. So when manually calling LMIC_startJoining, one can quickly use LMIC.txChnl = channel to change the channel that LMiC selected.
  • Whenever a join attempt fails, nextJoinState will select another channel and/or data rate (SF), without checking if the channel is activated. One cannot change that behavior from one’s own sketch.

Comments