beegee-tokyo / SX126x-Arduino

Arduino library to use Semtech SX126x LoRa chips and modules to communicate
MIT License
226 stars 64 forks source link

LoRa comunication #1

Closed josjimenezja closed 4 years ago

josjimenezja commented 5 years ago

Hi @beegee-tokyo, i have been reading your code and implementing it, good job. I have one question, how i can send the value of a sensor, like a global variable? The LoRa-WAN example is for create a gateway or to connect the node to a gateway?

beegee-tokyo commented 5 years ago

What type is the value of the sensor? Is it a byte (8bit), an integer (16 bit), a long (32 bit) or a float value? If it a byte, integer or long, you set the package size to the size of your sensor value. E.g. 1 byte size for a 8 bit value or 4 bytes for a long value. Then you copy the value from your sensor into the package and send it. Example for a long (32 bit) sensor value. I define a union like this

union {
   int8_t asByte[4];
   long asLong;
} sensValue;

Then I copy the long value of the sensor into the union

sensValue.asLong = valueReadFromSensor;

To send the package over LoRa I do

int8_t package[4];
package[0] = sensValue.asByte[0];
package[1] = sensValue.asByte[1];
package[2] = sensValue.asByte[2];
package[3] = sensValue.asByte[3];

And then send the package.

If your sensor value is a float, it is a little bit more complicated. I have an example for it, but I need to be on my computer to copy the code.

Sorry, I am on my tablet (it's late here). Hope what I wrote does make sense.

josjimenezja commented 5 years ago

Thanks for your answer, i going to try.

beegee-tokyo commented 5 years ago

@josjimenezja
How is it going?

josjimenezja commented 5 years ago

Hi @beegee-tokyo, really good. Now i can send my sensors information in to array of bytes and check that the receptor if received the information. I do not distance test in open field yet, but if in the city and i calculate like 500 mts of distance.

beegee-tokyo commented 5 years ago

Good!

If you will ever test LoRaWan, let me know. I am very curious if the library works on LoRaWan.

Good luck with your project.

josjimenezja commented 4 years ago

Hi again @beegee-tokyo , i have question about loraWan , i am continuous using the same hardware (ESP32 and E22) but i don't understand your lorawan example. This example is for create a gateway lorawan or for use the lorawan protocol to communicate a node to a gateway? I think about buy a gateway but not yet because i cant use lorawan to communicate the node to the gateway. I'm reading about an example of a lora gateway on TTN and they talk about APP KEY and others specific instruccion that the node must have to connect with the gateway and in your example i don't see that, im really confuse with lorawan and the compatibility with the hardware that i'm used.

beegee-tokyo commented 4 years ago

@josjimenezja Welcome back. The examples are for a LoRaWan sensor node, not for a LoRaWan gateway. To run a gateway you need a different LoRa chip, because a LoRaWan gateway needs to listen to at least 8 different frequencies at the same time. The correct chip would be a Semtech SX1301 (I think).

All the required settings for LoRaWan are in the file Commisioning.h. There you can set the frequencies, the regions, the DEVICE EUI, the APPSKEY, .....

josjimenezja commented 4 years ago

Thanks @beegee-tokyo, in the file Commisioning.h i can change all but one of the opction i dont not what is it, is #define LORAWAN_APPLICATION_KEY , in TTN i don't get this key.

beegee-tokyo commented 4 years ago

Not 100% sure but on TheThingsNetwork I found this

Dynamically activated devices (OTAA) use the Application Key (AppKey) to derive the two session keys during the activation procedure. In The Things Network you can have a default AppKey which will be used to activate all devices, or customize the AppKey per device

.

josjimenezja commented 4 years ago

Your code is by OTAA or ABP? In ABP i have not AppKey but yes the others and in OTAA i have App key but not the others.

beegee-tokyo commented 4 years ago

The code should be for both. In Commissioning.h you can set the mode with

/**@brief Define activation procedure here
 * More information https://www.thethingsnetwork.org/forum/t/what-is-the-difference-between-otaa-and-abp-devices/2723
 * When set to 1 the application uses the Over-the-Air activation procedure
 * When set to 0 the application uses the Personalization activation procedure
 */
#define OVER_THE_AIR_ACTIVATION 0
josjimenezja commented 4 years ago

@beegee-tokyo i have this error
lmh_init failed - -1 OVER_THE_AIR_ACTIVATION != 0 Sending frame lmh_send result -1 I thought that was by the app key, but the module is not initializing

beegee-tokyo commented 4 years ago

I guess you have to get the app key from TTN and put it into Commissioning.h. Do you have a working LoRaWan gateway that is connected to TTN? I guess you need it for OOTA procedure.

Sorry if my help is small, but I could never test the code due to the fact that I do not have a gateway.

josjimenezja commented 4 years ago

Yes the gateweay is connect in TTN ,I have a mono canal gateway but is enough for test him, is a dragino Lora gateway. Thank you very much ,i going to try to connect , your code is the only one that i found for this module. If I have more questions, I will write.

beegee-tokyo commented 4 years ago

To connect to a mono channel gateway you might need to set this on the node as well. When doing some basic tests I saw that the node was switching frequency on every package it sends. But to be honest I didn't investigate how to do this.

josjimenezja commented 4 years ago

i have problems with the region, doesn't matters what i select every time returned the same error. (Error -> LORAMAC_STATUS_REGION_NOT_SUPPORTED)

beegee-tokyo commented 4 years ago

Seems some parts of the code don't see the defines made in Commissioning.h.

Try to add #include "mac/Commissiong.h" into the file Region.cpp of the library It should look like

Maintainer: Miguel Luis ( Semtech ), Gregory Cristian ( Semtech ) and Daniel Jaeckle ( STACKFORCE )
*/
#include <stdbool.h>
#include <string.h>
#include <stdint.h>

#include "boards/mcu/timer.h"
#include "mac/LoRaMac.h"
#include "mac/Commissioning.h"

// Regional includes
#include "Region.h"

It might be missing in other files as well, I will try to dig into it.

beegee-tokyo commented 4 years ago

Are you using this gateway?

LG01-S IoT Gateway featuring LoRa® technology

Where did you buy it? And how much did it cost?

Closest shop to my location (Philippines) would be Seeed, but they are out of stock.

beegee-tokyo commented 4 years ago

Just for your info, I found in my locker a SparkFun LoRa Gateway 1-Channel and set it up as a LoRaWan gateway. I found as well a SparkFun SAMD21 Pro RF and set it up as a LoRaWan node. The two work quite good together.

Now the more important part. I used my LoRaWan example (the platformIO version) and setup another ESP32 hooked to an eByte E22-900M22S module.

And it works. The only problem is the frequency hopping. The library jumps to a new frequency on every data package, so the gateway does not receive all packages. Will check on this tomorrow.

beegee-tokyo commented 4 years ago

To work with a single channel and avoid frequency hopping, a quick solution is to change in LoRaMac.cpp line 2221 (or around there)

txConfig.Channel = channel;

to

txConfig.Channel = 0;

Then the LoRaWan node sends always on the base frequency.

josjimenezja commented 4 years ago

Hi @beegee-tokyo excuse me for a late answer. I added the Commissioning.h and works correctly. I'm using this gateway https://www.dragino.com/products/lora/item/117-lg01-p.html. I have a question about the configuration of the gateway, how i can se the if the lora node send the information to the gateway, in the serial print i see that the frame was send, but i don know how i can see the message in the gateway. I did the correction about the frequency jump that you said, but y don't know how see the message in the gateway.

In the serial of arduino print this message

===================================== SX126x LoRaWan test

OVER_THE_AIR_ACTIVATION != 0 Sending frame lmh_send result 0 Sending frame lmh_send result 0

i supposed that is sending the message.

josjimenezja commented 4 years ago

I configured the gatway on TTN.

beegee-tokyo commented 4 years ago

I don't know anything about the Dragino device, so I am sorry, I can't help how to get information from it. lmh_send result 0 indicates that the package was sent successfully.

The software I use on the SparkFun gateway enables a webserver where I can see the packages coming in.

In my setup I can see the messages on TTN. I didn't setup the gateway on TTN,, but I had to register the devices there in order to see the packets.

It's 11pm here, so I am on my tablet, cannot attach screenshots. Will send you some pictures and how-to tomorrow.

beegee-tokyo commented 4 years ago

Found a way to attach Screenshots on my tablet. Below is webpage from my gateway Screenshot_20191008_225259_com android chrome On TTN I created an application Screenshot_20191008_230150_com android chrome This is the device I setup on TTN Screenshot_20191008_225857_com android chrome Here is the data received on TTN Screenshot_20191008_225955_com android chrome

Hope that helps.

beegee-tokyo commented 4 years ago

The SparkFun hookup guide is giving a good example how to setup TTN https://learn.sparkfun.com/tutorials/sparkfun-lora-gateway-1-channel-hookup-guide

josjimenezja commented 4 years ago

Thank you very much for your help, I'm going to read the sparkfun tutorial and try to connect corretly the gateway to TTN. then i write. Have a good night

josjimenezja commented 4 years ago

@beegee-tokyo where i can change the spread factor, coding rate and the other parameters of the communication?

beegee-tokyo commented 4 years ago

As far as I know when you are using LoRaWan these parameters are predefined by the LoRaWan specifications and cannot be freely changed.

The only way to change some parameters is to change the datarate. Using my library at one point you define the _lora_paraminit structure

/**@brief Structure containing LoRaWan parameters, needed for lmh_init()
 */
static lmh_param_t lora_param_init = {LORAWAN_ADR_ON, LORAWAN_DEFAULT_DATARATE, LORAWAN_PUBLIC_NETWORK, JOINREQ_NBTRIALS, LORAWAN_DEFAULT_TX_POWER};

The second parameter, LORAWAN_DEFAULT_DATARATE, specifies the bandwidth and the spreading factor. If you look into Region.h you find 16 predefined data rates and what SF and BW they mean for each region. Example for DR_3, datarate 3:

/*!
 * Region       | SF
 * ------------ | :-----:
 * AS923        | SF9  - BW125
 * AU915        | SF7  - BW125
 * CN470        | SF9  - BW125
 * CN779        | SF9  - BW125
 * EU433        | SF9  - BW125
 * EU868        | SF9  - BW125
 * IN865        | SF9  - BW125
 * KR920        | SF9  - BW125
 * US915        | SF7  - BW125
 * US915_HYBRID | SF7  - BW125
 */
#define DR_3 3

For the coding rate, if you look into LoRaWAN 1.1 Regional Parameters it is fixed for each region. The LoRaWAN™ 1.0.3 Specification is as well worth reading (if you didn't already)

josjimenezja commented 4 years ago

thanks, i will check that, today in the afternoon i'm going to do a test with a friend that have a gateway. I will tell you the results later.

josjimenezja commented 4 years ago

I @beegee-tokyo i have good news, today i tested your code with a gateway and works good, but i have some question about it.

1) How i can select the quantity of channels and the specific frequency for each, for example 8 channels and 903.1 Mhz, 904.5Mhz, .... etc. ? 2) Its possible to change this parametters since thi IDE of arduino? 3) In the test the first messages arrived at TTN arrived empty, the other message had the "hello word" 4) is possible to modificate the adaptive data rate (adr) ?

WhatsApp Image 2019-10-09 at 5 44 47 PM

beegee-tokyo commented 4 years ago

Thanks for the good news.

For the answers, I am guessing you are using the US915 region. If you use another region you need to look in the matching files for your region.

Still just guessing with my answers below, didn't try or test it.

1) Quantity of channels and specified frequencies LoRaWAN 1.1 Regional Parameters says that the start channels and the frequency hops are predefined. For some regions it says as well that there is a minimum number of channels that MUST be supported by an end device. To limit the number of channels you have to change the US915_MAX_NB_CHANNELS value in RegionUS915.h. The steps between channels is predefined in the regional parameters document. In RegionUS915.cpp in the function void RegionUS915InitDefaults(InitType_t type) you can see how the channels and their frequency are initialized. 2) Change these parameters Yes, by changing above mentioned values US915_MAX_NB_CHANNELS you can change the number of used channels. The frequency steps seem to be fixed and should NOT be changed. 3) First messages empty No explanation for this. Could be the gateway, could be the lora node. 4) Adaptive data rate I only know that you can enable or disable the adaptive data rate in the init parameters, but I do not know if you can change its behavior. From my understanding the ADR is used to adapt the data rate to the package size, so it might be better not to change it.

josjimenezja commented 4 years ago

Thanks for answers. I'm trying to change the frequency and the jump, but the jump that the gateway used is the same that are predefined on the code then isn't necessary to change. -New -> i can change the frequency of the channels. Changing the first frequency in RegionUS915InitDefaults. Now i have 72 channels but i just need the 8 firsts.

I have a problem with the function: LoRaMacStatus_t SendFrameOnChannel(uint8_t channel) { TxConfigParams_t txConfig; int8_t txPower = 0; txConfig.Channel = channel; txConfig.Datarate = LoRaMacParams.ChannelsDatarate; txConfig.TxPower = LoRaMacParams.ChannelsTxPower; txConfig.MaxEirp = LoRaMacParams.MaxEirp; txConfig.AntennaGain = LoRaMacParams.AntennaGain; txConfig.PktLen = LoRaMacBufferPktLen; do you know where this function are called in the code? I suppose that this function is the key of the channels selected because the variable 'channel' is a number between 0 and the number of total channels - 1 , in this case since 0 to 71 , if i select the number 0 means the first frequency, the same with 1 means the second frequency, and so on...

beegee-tokyo commented 4 years ago

Hi,

SendFrameOnChannel is called by ScheduleTx.
In ScheduleTx the channel hop is made by calling RegionNextChannel.
ScheduleTx is called from several other functions. I am not that familiar with all the functions in the LoRaWan part, as I just took it from the Semtech example code.

Yesterday I released a new version of the library where I added the option to disable the channel hoping and to define the channel and the datarate to be used in LoRaWan when using a single channel gateway.

In Commisioning.h are now three new defines:

/**@brief Indicate if a single channel gateway is the receiver
 * More information https://www.thethingsnetwork.org/forum/t/what-is-the-difference-between-otaa-and-abp-devices/2723
 * When set to 1 the application does randomly change channels on each transmission
 * When set to 0 the application uses always the base channel
 */
#define DO_CHANNEL_SWITCH 1

/**@brief Channel to be used if we are talking to a single channel gateway
 * Check the file CHANNELS.MD to find out which channel corresponds to which frequency 
 * in a specific region
 * Defaults to channel 0
 */
#define GATEWAY_SINGLE_CHANNEL 0

/**@brief Datarate to be used if we are talking to a single channel gateway
 * Check the file Region.h to find out which datarate corresponds to which SF 
 * and bandwidth in a specific region
 * Defaults to channel DR_3
 */
#define GATEWAY_SINGLE_DATARATE DR_3

In LoRaMac.cpp the channel hoping and data rate are overridden by above defined values if the single channel option is active:

    LoRaMacStatus_t SendFrameOnChannel(uint8_t channel)
    {
        TxConfigParams_t txConfig;
        int8_t txPower = 0;

        txConfig.Channel = channel;
        txConfig.Datarate = LoRaMacParams.ChannelsDatarate;
        txConfig.TxPower = LoRaMacParams.ChannelsTxPower;
        txConfig.MaxEirp = LoRaMacParams.MaxEirp;
        txConfig.AntennaGain = LoRaMacParams.AntennaGain;
        txConfig.PktLen = LoRaMacBufferPktLen;

#if DO_CHANNEL_SWITCH == 0
        txConfig.Channel = GATEWAY_SINGLE_CHANNEL;
        txConfig.Datarate = GATEWAY_SINGLE_DATARATE;
#endif
        RegionTxConfig(LoRaMacRegion, &txConfig, &txPower, &TxTimeOnAir);

        MlmeConfirm.Status = LORAMAC_EVENT_INFO_STATUS_ERROR;
        McpsConfirm.Status = LORAMAC_EVENT_INFO_STATUS_ERROR;
        McpsConfirm.Datarate = LoRaMacParams.ChannelsDatarate;
        McpsConfirm.TxPower = txPower;

        // Store the time on air
        McpsConfirm.TxTimeOnAir = TxTimeOnAir;
        MlmeConfirm.TxTimeOnAir = TxTimeOnAir;

        // Starts the MAC layer status check timer
        TimerSetValue(&MacStateCheckTimer, MAC_STATE_CHECK_TIMEOUT);
        TimerStart(&MacStateCheckTimer);

        if (IsLoRaMacNetworkJoined == false)
        {
            JoinRequestTrials++;
        }

        // Send now
        Radio.Send(LoRaMacBuffer, LoRaMacBufferPktLen);

        LoRaMacState |= LORAMAC_TX_RUNNING;

        return LORAMAC_STATUS_OK;
    }

In CHANNELS.MD you can find the channel numbers corresponding frequency for all regions. and in Regions.h you can find the spreading factor and the bandwidth for each data rate for each region. Be aware that the coding rate is fisxed by LoRaWan specification to 4/5.

The reason for above changes are that my ESP32 single channel gateway is not using the default frequency and data rate in US915 mode. So for my single channel gateway I need to define on the node side which frequency and data rate (== BW and SF) should be used.

beegee-tokyo commented 4 years ago

I tested the library against a Draguino 8 channel LoRaWan gateway and it works without problems.

I will close this issue for now.