jgromes / RadioLib

Universal wireless communication library for embedded devices
https://jgromes.github.io/RadioLib/
MIT License
1.55k stars 387 forks source link

LoRaWAN support #58

Closed jgromes closed 1 year ago

jgromes commented 4 years ago

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

ricaun commented 4 years ago

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:

See yaa!

jgromes commented 4 years ago

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 ;)

ricaun commented 4 years ago

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?

jgromes commented 4 years ago

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

ricaun commented 4 years ago

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.

jgromes commented 4 years ago

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

ricaun commented 4 years ago

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.

jgromes commented 4 years ago

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.

ricaun commented 4 years ago

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. 😄

jgromes commented 4 years ago

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?

billiri commented 4 years ago

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

Timvrakas commented 4 years ago

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.

jgromes commented 4 years ago

@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).

mmrein commented 4 years ago

@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.

KevWal commented 3 years ago

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.

MystikReasons commented 3 years ago

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

jgromes commented 3 years ago

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

ivanboesing commented 3 years ago

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

jgromes commented 3 years ago

@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.

UdayChaduvula commented 2 years ago

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 ?

jgromes commented 2 years ago

@UdayChaduvula unfortunately, LoRaWAN is not supported yet.

IhorNehrutsa commented 1 year ago

@jgromes May you publish LoRaWAN branch?

jgromes commented 1 year ago

@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 commented 1 year ago

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)

StevenCellist commented 1 year ago

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?

jgromes commented 1 year ago

@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.

StevenCellist commented 1 year ago

@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 :)

jgromes commented 1 year ago

@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.

HeadBoffin commented 1 year ago

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 commented 1 year ago

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.

jgromes commented 1 year ago

@HeadBoffin overall, I appreciate the feedback, but next time please open a new issue or discussion. I will close this one shortly, it's been open for way too long and since the 6.2.0 update, it can be considered resolved in my opinion. Further work is of course needed, but I'll keep tracking that in separate issues as feedback from users arrives.

It does. Click on the <> and you get: 0x70, 0xB3, 0xD5, 0x7E, 0xD0, 0x01, 0xC4, 0xEF

Didn't know that, thanks - the examples have been using hexadecimal arrays for a while now.

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

Somehow I doubt the Tech Director is the one implementing the web interface. I've actually seen quite a few bugs in it my testing (not able to change parameters of node after changing its frequency band or version, the web interface crashing after re-opening more than one tab etc.). I'm not talking about the backend at all (which obviously works fine), just the interface.

LoL or is that Sob? TTN forum experience clearly indicates that RTFM isn't a thing now

I don't understand what you're trying to say, sorry.

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

I'll think about it, though I'm not really keen to be maintaining such a list. Products have variants, they appear and disappear off the market, and it would be up to RadioLib/me to ensure the list is up to date.

PS: In general, please try using less abbreviations. It's a bit hard to wrap one's head around what you're trying to say.

jgromes commented 1 year ago

Closing since basic LoRaWAN suport has been released in update 6.2.0, with future work to be done based on user feedback.

HeadBoffin commented 1 year ago

LoL or is that Sob? TTN forum experience clearly indicates that RTFM isn't a thing now

I don't understand what you're trying to say, sorry.

Reading The Flipping Manual is now considered an act of desperation - people will post issues first to get someone else to do the research / thinking for them. They won't even search issues, just open a new one.