RadioLib icon indicating copy to clipboard operation
RadioLib copied to clipboard

LoRaWAN support

Open jgromes opened this issue 4 years ago • 21 comments

RadioLib could be extended to support LoRaWAN networks (and it's been on the TODO/WIP list for quite a while now).

jgromes avatar Nov 08 '19 17:11 jgromes

Hello, I would like to help implement the LoRaWAN stuff. First I need to understand how the library works and how to set and get information about frequency, SF, invert signal and others of the lora modules (SX127x, RFM9x and SX126x).

struct LoRa_config
{
  long Frequency;
  int SpreadingFactor;
  long SignalBandwidth;
  int CodingRate4;
  bool enableCrc;
  bool invertIQ;
  int SyncWord;
  int PreambleLength;
};

static LoRa_config txLoRa = {903900000, 9, 125000, 5, true, false, 0x34, 8};

With this configuration is possible to create a simple LoRaWAN protocol. Starting with:

  • Uplink
  • Downlink
  • OTAA
  • Frequency plan

See yaa!

ricaun avatar Mar 07 '20 14:03 ricaun

Thank you for taking your time to contribute!

I already did some work on this, starting with band plans. I did run into quite a few issues, since LoRaWAN Regional Parameters specification has several different ways of specifying channels. Ideally this LoRaWAN implementation will support all regions. At the same time though, it must be light enough to fit onto low-end MCUs, such as Arduino Uno.

PS: Please make sure to use PhysicalLayer to keep our LoRaWAN implementation module-agnostic. I think it should be possible to make it run on non-LoRa radios - that'd be fun ;)

jgromes avatar Mar 07 '20 17:03 jgromes

I think is needed to create a virtual function on the PhysicalLayer like setLoRa(float freq, float bw, uint8_t sf, uint8_t cr, bool enableCrc, bool invertIQ, uint8_t syncWord, uint16_t preambleLength) What do you think it's a good strategy to change all the lora configuration on each module?

ricaun avatar Mar 07 '20 18:03 ricaun

It might be better to implement each method separately (setFrequency(), setBandwidth() etc.), because things like setFrequencyDeviation() are already implemented as a single method.

jgromes avatar Mar 07 '20 19:03 jgromes

I was testing and (setFrequency(), setBandwidth() etc.), should work, but some lora module have a different setFrequency() with an extra calibrate parameter and It's breaking the code =( I'm gonna remove the calibration = true and make some testes.

ricaun avatar Mar 07 '20 20:03 ricaun

You can create a setFrequency overload that only takes the frequency parameter, that should solve the issue.

jgromes avatar Mar 08 '20 06:03 jgromes

Hello, I manage to make work but I need to change some functions, I only change on the SX126X module.

https://github.com/ricaun/RadioLib/tree/lorawan

We need to normalize the funcions.

PhysicalLayer
* Add setFrequency
* Add setSpreadingFactor
* Add setBandwidth
* Add setCodingRate
* Add setCRC
* Add setInvertIQ
* Add setSyncWord
* Add setPreambleLength

I know the sx127X don't have the setInvertIQ function, this function is needed to receive downlink.


I design this library that's make the encode and decode of the LoRaWan, I really don't know is a good idea to add all the LoRaMacCrypto stuff on your code.

https://github.com/ricaun/LoRaWanPacket

See yaa.

ricaun avatar Mar 16 '20 19:03 ricaun

I don't think it's a good idea to separate LoRaWAN implementation from the library - mainly because Arduino has no way to manage dependencies.

IQ inversion is not implemented on SX127x, but I believe that setting is somewhere in the registers, so it can be added.

I'm still playing around with the idea of having radio-agnostic LoRaWAN implementation, to get the possibility of "LoRaWAN-like" network with non-LoRa modules. The main issue is the LoRa parameters: spreading factor, bandwidth and coding rate. I'm thinking that on FSK modules, bandwidth could be represented by frequency deviation (receiver filter bandwdith) and spreading factor by the bitrate, but that still leaves coding rate unaccounted for - perhaps the GFSK shaping parameter could be used here?

On a side note, it's not a good idea to implicitly return ERR_NONE from virtual PhysicalLayer methods. If that method gets called from a module that doesn't have it fully implemented (e.g. calling setSpreadingFactor on non-LoRa module like CC1101), it will return ERR_NONE leading the user to believe it was executed correctly. Either ERR_UNKNOWN or a new ERR_NOT_IMPLEMENTED should be used here.

jgromes avatar Mar 17 '20 18:03 jgromes

I don't think it's a good idea to separate LoRaWAN implementation from the library - mainly because Arduino has no way to manage dependencies.

I know the Arduino has the depends= on the library.properties file that manage dependence of the librarys.

IQ inversion is not implemented on SX127x, but I believe that setting is somewhere in the registers, so it can be added.

https://github.com/sandeepmistry/arduino-LoRa/blob/8eb6a51b99f650c2244d193c7d8497a0877fd42e/src/LoRa.cpp#L585-L595

I'm still playing around with the idea of having radio-agnostic LoRaWAN implementation, to get the possibility of "LoRaWAN-like" network with non-LoRa modules. The main issue is the LoRa parameters: spreading factor, bandwidth and coding rate. I'm thinking that on FSK modules, bandwidth could be represented by frequency deviation (receiver filter bandwdith) and spreading factor by the bitrate, but that still leaves coding rate unaccounted for - perhaps the GFSK shaping parameter could be used here?

In some frequency plan, the LoRaWAN has a single FSK channel, it's needed to investigate on the LoRaWAN.

On a side note, it's not a good idea to implicitly return ERR_NONE from virtual PhysicalLayer methods. If that method gets called from a module that doesn't have it fully implemented (e.g. calling setSpreadingFactor on non-LoRa module like CC1101), it will return ERR_NONE leading the user to believe it was executed correctly. Either ERR_UNKNOWN or a new ERR_NOT_IMPLEMENTED should be used here.

Good ERR_NOT_IMPLEMENTED is better. 😄

ricaun avatar Mar 17 '20 20:03 ricaun

depends is only available from Arduino 1.8.10. Furthermore, it can only handle dependencies when installing the library via library manager, and AFAIK, it offers no way of revision control (i.e. it will always install the latest available release). What are the advantages over having the code in the same library?

In some frequency plan, the LoRaWAN has a single FSK channel

I'm aware of that, though I'm unable to find the FSK parameters (frequency deviation and signal shaping) anywhere in the specification or regional parameters. Is that channel even used?

jgromes avatar Mar 18 '20 06:03 jgromes

sx1276 RegInvertIQ 0x33 6bit (status 0 - normal, 1 - inverted I Q)

billiri avatar Apr 03 '20 19:04 billiri

Totally random user/bystander here, but I honestly have mixed feelings about integration of more advanced layers into a single library. The "plugability" you've developed with the Module and PhysicalLayer abstraction are great, but I think that's a reason to build a set of interconnectable libraries, rather than one giant one. I at least don't want to have to disentangle LoraWAN functionality from the core drivers.

Timvrakas avatar Apr 24 '20 06:04 Timvrakas

@Timvrakas that's a very good point - the original purpose of PhysicalLayer was to provide support for reletively simple stuff, like RTTY or Morse code. And I do agree that the library size is getting out of hand (there's like 60+ examples right now - Travis builds for some platforms take longer than hour). On the other hand, I have a lot of flexibility right now, and if I want to change something in one of the layers, it's easy to track down and update all affected dependencies, because there are none outside RadioLib.

I'm still clinging on to the hope that I'll get to try out LoRaWAN on non-LoRa modules. The parameters obviously won't map onto each other exactly (e.g.: FSK modules don't have spreading factor), but I'm thinking that some could be replaced with parameters that have similar impact (FSK bit rate could be considered a counterpart of spreading factor in this example).

jgromes avatar Apr 24 '20 07:04 jgromes

@jgromes

I'm aware of that, though I'm unable to find the FSK parameters (frequency deviation and signal shaping) anywhere in the specification or regional parameters.

That is ussual. Try looking at LoRaMac-node or BasicMAC radio drivers, I've seen it somewhere in there.

Is that channel even used?

Doesn't have to, but can be. I've successfully tested it once, its use seems to be quite rare tho.

Thing is that your end device does not necessarily need to support that channel to be LoRaWAN compatible. What it MUST support to be LoRaWAN compatible (apart from other features) is subset of predefined channels in most channel plans. For EU868 that is 3 channels with LoRa modulation using SF12 to SF7.

I'm still clinging on to the hope that I'll get to try out LoRaWAN on non-LoRa modules.

This would be long chapter on its own. If you would omit LoRa modulation, then you would most likely have to make your own gateway (HW and SW) and server software to make this kind of WAN network.

There may be one way to let non-LoRa devices comunicate with LoRaWAN network (don't confuse it with LoRaWAN compatible - it is not) which is using that dedicated FSK channel, but beware of that you're opening pandoras box ;)

That is simillar when people try to make single-channel LoRa gateway - it may be able to comunicate with LoRaWAN network, but it creates whole lot of confusion as it can never be LoRaWAN compatible anyways.

mmrein avatar May 21 '20 09:05 mmrein

Just in case this is of use - a different TTN LoRaWAN implementation, https://github.com/adafruit/TinyLoRa/ and https://github.com/brentru/TinyLoRa apologies if this is already known or not helpful.

KevWal avatar May 16 '21 15:05 KevWal

What is the current status for implementing the lorawan protocol for the SX127x?

MystikReasons avatar Sep 10 '21 07:09 MystikReasons

@MystikReasons unfortunately there was no progress on this from my side due to lack of time.

jgromes avatar Sep 10 '21 16:09 jgromes

Hello. Great work. Do you have any expectations of advancement on LORAWAN for SX1262?

ivanboesing avatar Sep 25 '21 13:09 ivanboesing

@ivanboesing Well the good news is that once the LoRaWAN driver is ready, it won't care one bit which module is it using. The bad news is that I still don't have the time to work on it.

jgromes avatar Sep 25 '21 17:09 jgromes

I created a LoRa device by using your library. I want to integrate my module to the Gateway, How to generate Dev EUI, Join EUI, APP EUI on the device ?

UdayChaduvula avatar Jul 01 '22 04:07 UdayChaduvula

@UdayChaduvula unfortunately, LoRaWAN is not supported yet.

jgromes avatar Jul 01 '22 05:07 jgromes

@jgromes May you publish LoRaWAN branch?

IhorNehrutsa avatar Nov 23 '22 12:11 IhorNehrutsa

@IhorNehrutsa all the work that was done is already on the development branch (https://github.com/jgromes/RadioLib/tree/development), but that's all there is so far.

jgromes avatar Nov 23 '22 15:11 jgromes

Basic LoRaWAN support was added, see https://github.com/jgromes/RadioLib/blob/master/examples/LoRaWAN/LoRaWAN_End_Device/LoRaWAN_End_Device.ino

It's been tested against a Waveshare SX1302 gateway connected to TTN. Caveats:

  1. ~~Only supports LoRaWAN 1.0~~ 1.1 implemented as well
  2. ~~Only uplinking data is supported at the moment (without confirmation)~~ Uplink and downlink supported
  3. Adaptive data rate not supported yet
  4. ~~Only EU868 and US915 bands supported~~ implemented all bands
  5. MAC commands not supported yet
  6. Class A only
  7. Only end device support (no RadioLib gateways yet)

This doesn't yet complete this issue, however, it's something that can be built upon. I will keep this issue open until points 1 - 4 are resolved. Points 5 and 6 would be good to have and point 7 I would see as optional. In theory, having also the gateway side implemented in RadioLib would allow to "extend" LoRaWAN over non-LoRa devices.

EDIT 2023-08-12: resolved point 1, partially resolved points 2 and 5 EDIT 2023-08-23: mostly point 5 (not all MAC commands supported yet)

jgromes avatar Jul 06 '23 14:07 jgromes

In the examples for LoRaWAN OTAA, you use a char array of size 16(17) for the appKey. On TTN, the hex array has 32 symbols (which does match w.r.t. length) - but how should I convert this? A straight conversion from hex to ASCII results in VERY weird characters which I am not really able to put into the appKey array.

I would love to be able to copy the array straight over from TTN to the code, just as is the case for the joinEUI and devEUI.

By the way: the default name for the third parameter on TTN is appKey, but the code says that the nwkKey should be used and appKey set to NULL for <1.1.0. I think that this is quite confusing, or am I missing something maybe?

Moreover, the OTAA example shows the following lines:

// SX1278 has the following connections:
// NSS pin:   10
// DIO0 pin:  2
// RESET pin: 9
// DIO1 pin:  3
SX1278 radio = new Module(10, 2, 9, 3);

But, at least for my board (one of the Heltec ESP32 boards with a SX1262), the order should be NSS, DIO1, RESET, BUSY. Is that a naming issue, or a documentation issue?

StevenCellist avatar Aug 24 '23 11:08 StevenCellist

@StevenCellist LoRaWAN mandates AES-128, which has 16-byte keys. I chose to represent them as ASCII strings. A 16-character string will be 32 symbols when represented as hexadecimals numbers. I have assumed that it is common knowledge in C programming that string is a an array of charaters and that it does not matter whether you treat them as char* or uint8_t*. But seeing as there is already a PR addressing the same thing (#811), perhaps I have assumed wrong. I will update the example so that the keys are not a C-string.

I would love to be able to copy the array straight over from TTN to the code

You will not be able to, it still needs to be formatted as hex array (e.g. uint8_t nwkKey[] = { 0x74, 0x6F, 0x70, .....

By the way: the default name for the third parameter on TTN is appKey, but the code says that the nwkKey should be used and appKey set to NULL for <1.1.0. I think that this is quite confusing, or am I missing something maybe?

I was confused by this too, and now I'm convinced this is incorrect in TTN web interface. There is no appKey in LoRaWAN 1.0.x, as can be seen in the diagram below - directly from LoRaWAN 1.1 specification.

Screenshot_67

But, at least for my board (one of the Heltec ESP32 boards with a SX1262),

SX126x has different pins than SX127x, see the SX126x examples.

jgromes avatar Aug 24 '23 15:08 jgromes

@jgromes thanks for the feedback, and implementing the change towards hex arrays!!

SX126x has different pins than SX127x, see the SX126x examples.

If this codebase is going to end up popular, I expect a lot of people (like me) trying out the examples without looking into the difference in pins for the different series of SX. My suggestion is to add a (commented) version for the different series to the examples, such that it is more clear that we should look for a different naming scheme :)

StevenCellist avatar Aug 24 '23 16:08 StevenCellist

@StevenCellist All RadioLib protocols run on any of its supported transceivers (there are some exceptions caused by hardware, but that's beside the point). The number of possible combinations is huge, so I don't think that's a step in the right direction.

If this codebase is going to end up popular, I expect a lot of people (like me) trying out the examples without looking into the difference in pins for the different series of SX.

Sorry, but my answer to that is going to be "read the docs". RadioLib is not for beginners, and it assumes you know how to use the hardware you have. It's intended for people who are building systems that have to run on wide range of platforms/with various transceivers and still provide the same interface.

jgromes avatar Aug 24 '23 17:08 jgromes

I would love to be able to copy the array straight over from TTN to the code You will not be able to, it still needs to be formatted as hex array (e.g. uint8_t nwkKey[] = { 0x74, 0x6F, 0x70, .....

It does. Click on the <> and you get:

0x70, 0xB3, 0xD5, 0x7E, 0xD0, 0x01, 0xC4, 0xEF

And then you can click the clipboard icon. However the default clipboard does yield:

70B3D57ED001C4EF

So you're both right!

By the way: the default name for the third parameter on TTN is appKey, but the code says that the nwkKey should be used and appKey set to NULL for <1.1.0. I think that this is quite confusing, or am I missing something maybe? I was confused by this too, and now I'm convinced this is incorrect in TTN web interface. There is no appKey in LoRaWAN 1.0.x, as can be seen in the diagram below - directly from LoRaWAN 1.1 specification.

Very few devices are on 1.0.4 yet, let alone 1.1, so the console shows end-user-engineer reality. It's most definitely not wrong, unless the Tech Director who's on the LA committees writing the specs who wants to make TTS a completely LW compliant LNS has lost the plot. If you select v1.1.0, you'll find the advanced settings provide entry fields for AppKey and NwkKey - the tooltips on the ? explain the various combinations. Frankly I think it's a muddle but if you are the TTS target audience of a volume user, your provisioning workflow will look after you.

Consequently one of the LMn 'bugs' or is it an issue, definitely a gotcha, is that some combos of config won't join unless you set the AppKey and the NwkKey to be the same, started seeing this when we moved to TTS v3 with the new STM32WL a couple of years back.

As I may have mentioned, mostly devices are still moving to v1.0.4, but for the DIY community, most LNS's support v1.1 so using that is entirely feasible, even if we all get confused by the changes in the specs with far less developers around to answer the questions.

HeadBoffin avatar Sep 17 '23 11:09 HeadBoffin

If this codebase is going to end up popular, I expect a lot of people (like me) trying out the examples without looking into the difference in pins for the different series of SX. Sorry, but my answer to that is going to be "read the docs". RadioLib is not for beginners, and it assumes you know how to use the hardware you have.

LoL or is that Sob? TTN forum experience clearly indicates that RTFM isn't a thing now - I get feedback for even suggesting it. Perhaps the best thing is to build up a list of product names with the pin mapping as well as something to explain connections for those soldering their own radios. LMIC-node should provide a useful source of info to get that started.

HeadBoffin avatar Sep 17 '23 11:09 HeadBoffin