Big STM32 boards topic


That did it. I have TTN_OTAA.ino working now. :+1:
(Not neccesary to disable ADR).

Actually this code is only relevant for ABP.

Yes I know, I only showed it as an example.


I am confused now.

What did address your issue:

(a) LoRaWAN.setDutyCycle(false)

(b) LoRaWAN.setDataRate(5)

I would be rather confused if it’s a datarate problem … Unless your gateway is seriously misconfigured.


LoRaWAN.setDataRate(5) did address my issue (“Not neccesary to disable ADR”).


I don’t like magic numbers. Are there any enums or macros defined for these? Where can I find them?


Ah, that is a very good point … one that I have no good answer to.

Here is the problem. The LoRaWAN protocol works with datarates, 0 to 15 (not all are used). 0 is the lowest, 15 the highest.

What a specific datarate means is region specific. So for EU868 DR_0 means SF12BW125. For US915 DR_0 means SF10BW125 … All of that is nicely documented by the LoRaWAN Regional Parameters document you can download upon request from the LoRaWAN alliance … after you register …

Not user friendly at all. TxPower has the same issue, except that I do the “dbm” to “tx-power-index” translation (which is really power-dbm = EIRP/ERP - 2 * power-index

So there I am stuck. Whether you use “0” or “DR_0” does not matter much. It’s bad. If I start using enums along SF[sf]BW[bw] it becomes more intuitive, except that the question comes up “why does SF12BW125” not work for me" … are you on “US915” … “yes” … “that’s not supported”. So you end up needed to reference the LoRaWAN Regional Parameters document again.

I could of course have a dual set enum scheme:

DR_0 = 0,

SF12BW125 = 16,


Yes but I assume that would have to be region dependent.
A dual scheme probably causes confusion and inconsistencies in applications.
A one-fits-all solution is probably not feasible due to region dependent implementation differences.

I did additional testing. These are the results:

Data Rate       Join Request   Join Accept   After Join Accept
---------       ------------   -----------   -----------------
setDataRate(0)  SF12BW125      SF12BW125     Nothing, then retry after 2:30
setDataRate(1)  SF11BW125      SF12BW125     Nothing, then retry after 1:20
setDataRate(2)  SF10BW125      SF10BW125     Recognized, starts uploading messages
setDataRate(3)  SF9BW125       SF9BW125      Recognized, starts uploading messages
setDataRate(4)  SF8BW125       SF8BW125      Recognized, starts uploading messages
setDataRate(5)  SF7BW125       SF7BW125      Recognized, starts uploading messages
setDataRate(6)  Exactly like setDataRate(0)

So when doing Join Requests on SF11BW125 or SF12BW123 the gateway sends Join Accepts but they are not recognized / not properly handled by the node.

Notice the different behavior when doing Join Requests at SF11BW125, the Join Accept uses SF12BW125 while the request was done on SF11BW125.

Can you explain the different (accept on SF12) behavior when doing Join Request on SF11BW125?
Why are the Join Accepts when doing requests on SF11BW125 and SF12BW125 not recognized / not properly handled?


Do you have some more info about the frequencies that gateway sees the incoming JOIN_REQUEST, and on which frequency it sends it’s JOIN_ACCEPT.

The RX2 window for TTN is non-standard:

869.525 - SF9BW125 (RX2 downlink only)

And yes, you found that for EU868 you can set the datarate before the join, and it will use that one … I’ll see with my gateway what it answer with. The join accept should be with the same datarate, unless it’s answering on the RX2 slot. This is why I think your gateway answers for SF12BW125 and SW11BW125 on the RX2 slot, but on 869.525MHz with SF12BW125 (which is EU868 standard).

The LoRaWAN_TTN_OTAA.ino contains this line:

LoRaWAN.setRX2Channel(869525000, 3);

Mind removing it and retry the series ? This one would remove the TTN specific RX2 window.


Three sequences for DR 5: (reset before each sequence)


There are image issues with the forum software the last months, so you will have to right-click the image and then select ‘Open image in new tab’ (for Chrome) or whatever option your browser has.

Note: setRX2Channel(…) still in place (not yet removed).


Three sequences for DR 4:



Two sequences for DR 2:



Well, that does not show the join behaviour … The setRX2Channel(…) channel line would be the real interesting one …


Two sequences (reset after the first two tries) for DR 1:



Ok, confirmed. Your gateway is non-TTN compliant.

869.525 is the RX2 slot, and it’s sending out SF12BW125. Should have used SF9BW125. At least this is how I read the spec, and how The offical TTN Arduino code ™ sets it up.


Ok, I was wrong …

Looks like this overrides the spec … So a JOIN_ACCEPT is still SF12BW125. That means for the TTN_OTAA example, the setRX2Channel() needs to be removed.

Thanx for helping me figuring that one out.


One sequence for DR 0:



One squence for DR 1 with LoRaWAN.setRX2Channel(869525000, 3); removed:


Notice that the Join Accept is missing.


One squence for DR 5 with LoRaWAN.setRX2Channel(869525000, 3); removed:



I don’t think so. See DR 1 with setRX2Channel(…) removed.


Not sure. With DR_1 perhaps the GUI is missing it. Because the log shows that the node saw the join accept (otherwise it would not have send data). IMHO this is the correct way. Wish TTN would have documented that properly … perhaps it’s just my command of the english language.


You are probably correct that the GUI missed it.

I did another try for DR 1 and also DR 0 (with LoRaWAN.setRX2Channel(..) removed):

DR 1:


DR 0:


Why is all of below in the main source file?

#if defined(REGION_EU868)
    LoRaWAN.addChannel(1, 868300000, 0, 6);
    LoRaWAN.setRX2Channel(869525000, 3);

Why not only place this in the example:

#define LORA_REGION EU868


and place the code below elsewhere (abstracted away from the main source file):

LoRaWAN.addChannel(1, 868300000, 0, 6);
LoRaWAN.setRX2Channel(869525000, 3);

And LoRaWAN.setRX2Channel(869525000, 3) should be automatically applied for ABP only.

(Jac Kersing) #123

For join TTN uses the specification value of DR0 for RX2, not DR3. DR3 is being used only after join.