Credit:
https://www.thethingsnetwork.org/forum/t/can-lmic-1-6-be-set-up-to-use-a-single-channel-and-sf/5207/11
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); } 71>
- For ABP, in
init()
replaceLMIC_setDrTxpow(DR_SF7,14);
15 with:
// Only use one channel and SF forceTxSingleChannelDr();
- For OTAA, in
init()
afterLMIC_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
inonEvent
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.ino
14, callingLMIC_reset
clears the keys after whichLMIC_setTxData2
is called to schedule some data to be sent. - In
src/lmic.c
3,engineUpdate
controls the flow, like if something has been scheduled for transmission. WhenLMIC.devaddr == 0
this will first triggerLMIC_startJoining
:
LMIC_startJoining
callsinitJoinLoop
, which for EU868 also callsinitDefaultChannels
. (For US915, that’s already done inLMIC_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 callingLMIC_startJoining
, one can quickly useLMIC.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