cjhdev / lora_device_lib Goto Github PK
View Code? Open in Web Editor NEWA LoRaWAN Device Library
Home Page: https://ldl.readthedocs.io/en/latest/
License: MIT License
A LoRaWAN Device Library
Home Page: https://ldl.readthedocs.io/en/latest/
License: MIT License
hi ! this is a great package ! but it lack of add driver for different Lora module ! could anyone help to add or adding instruction how to add extra drivers for different modules ? thank you !
I want to remove the diagnostic events because this information isn't useful to applications and yet takes code space and increases the line count. Previously these events could be enabled/disabled at compile time but I removed the option as it made the configuration documentation more complicated.
Since the information is sometimes useful to eyeball during development, I propose that the information should be printed via LDL_DEBUG. This is typically what these events get used for anyway, at least in the ports I've written.
Diagnostic events include:
Hi, I am glad to see there is new alternative to LMIC or LoRaMac-Node for no-arduino developers.
I am using ESP32, in my code https://github.com/dzurikmiroslav/esp32-ldl-example I have issue with OTAA joining request. In log I see many attempts to join, but in TTN console I see only first attempt. After restart is the situation same, in TTN console will be added one join request.
Application log:
1229: LDL_MAC_addChannel: debug: adding chIndex=0 freq=868100000 minRate=0 maxRate=5
1229: LDL_MAC_addChannel: debug: adding chIndex=1 freq=868300000 minRate=0 maxRate=5
1229: LDL_MAC_addChannel: debug: adding chIndex=2 freq=868500000 minRate=0 maxRate=5
I (318) main: LDL_MAC_RESET
I (318) main: LDL_MAC_STARTUP
216: LDL_MAC_otaa: debug: sending join in 16359821 ticks
I (76518) main: LDL_MAC_TX_BEGIN
I (76618) main: LDL_MAC_TX_COMPLETE
I (81618) main: LDL_MAC_RX1_SLOT
I (82518) main: LDL_MAC_RX2_SLOT
I (83318) main: LDL_MAC_JOIN_TIMEOUT
950: LDL_MAC_process: debug: dither retry by 18069775 ticks
I (107518) main: LDL_MAC_TX_BEGIN
I (107718) main: LDL_MAC_TX_COMPLETE
I (112618) main: LDL_MAC_RX1_SLOT
I (113618) main: LDL_MAC_RX2_SLOT
I (114618) main: LDL_MAC_JOIN_TIMEOUT
950: LDL_MAC_process: debug: dither retry by 4623390 ticks
I (130018) main: LDL_MAC_TX_BEGIN
I (130318) main: LDL_MAC_TX_COMPLETE
I (135218) main: LDL_MAC_RX1_SLOT
I (136218) main: LDL_MAC_RX2_SLOT
I (137218) main: LDL_MAC_JOIN_TIMEOUT
950: LDL_MAC_process: debug: dither retry by 18470742 ticks
I (174118) main: LDL_MAC_TX_BEGIN
I (174618) main: LDL_MAC_TX_COMPLETE
I (179518) main: LDL_MAC_RX1_SLOT
I (180518) main: LDL_MAC_RX2_SLOT
I (181518) main: LDL_MAC_JOIN_TIMEOUT
950: LDL_MAC_process: debug: dither retry by 17685113 ticks
I (236118) main: LDL_MAC_TX_BEGIN
I (237118) main: LDL_MAC_TX_COMPLETE
I (242018) main: LDL_MAC_RX1_SLOT
I (243018) main: LDL_MAC_RX2_SLOT
I (244718) main: LDL_MAC_JOIN_TIMEOUT
Hi,
How do you use the DeviceTimeSync options with the current implementation?
I've added a new app callback function to the end of the processTX function, where I only record the current msec/tick counter, and calculate the time diff at the LDL_MAC_DEVICE_TIME callback, but I'm not sure this is the best way.
When the node receives the command TXParamSetupReq
the network defines if the node has to limit the uplink and downlink time to 400ms (a.k.a. dwell time)
What you actually do in the current version of this library, is limit the datarate to 2 (0 and 1 do not comply with the dwell time limitation). But the function LDL_Region_convertRate
does not take the dwell time into account when it should. The maximum payload allowable is dependent on the dwell time too.
Affects 0.3.0 and earlier but only for 1.1 servers.
The problem occurs in LoRaWAN 1.1 where the channel index as a parameter for generating MIC. LoRaWAN 1.0 doesn't do this.
LDL currently works by sending the exact same frame as before for re-transmission, but usually on a different channel to the original. This also affects "dedicated mac command responses" because the MIC is generated before the channel is selected.
This will be fixed in the next release.
Hi,
I came across your library after asking about open source LoRaWan stack implementartions here.
We want to develop sensor nodes in a factory environment, we're planning to use STM32Lx devices, communicating over LoRaWan with a gateway. We're using Atollic TrueStudio (configuration code generated with STM32CubeMX) and I would like to include your library to the project, I tried to do so with lorawan-mac I i wasn't able to do so.
After searching LoRaWan stacks I think yours is the most sane one, but i would like to know what is your roadmap, maybe if you accept contributions, plans to implement Class B and C, etc.
Hi,
I am build my own single channel gateway using ESP-1ch-Gateway and connect it to TTN. In TTN console I see received join query and joint accept response. My device always give me LDL_MAC_JOIN_TIMEOUT.
This problem may be caused by wrong LDL_System_advance value? In what way I should calculate it?
Hi,
I'd ported this nice little library to my custom cortex m0+ microcontroller, but with the LDL_LITTLE_ENDIAN define the OTAA authentication fails, with "joinAccept MIC failed" error.
After removing the define it successfully join and packets are ok, so this option is possibly deprecated or buggy.
This bug is in 0.4.0 but it's possibly been around longer.
Normally, a radio waiting to receive a packet will raise one of two interrupt lines to signal:
LDL uses a guard timer to reset the chip if no interrupt is raised within an extended period of time. If this timer expires, LDL produces a chip error event and performs a chip reset.
I've been reproducing this bug by waiting for OTAA to increase the spreading factor to 11 (or 12) before starting the network server to answer the join request at that spreading factor. If there is no message sent, the timeout interrupt is raised. If there is a message sent, then no interrupt is raised.
I'm going to start the investigation by adding trace level messages to the radio driver to compare register access between modes that work and modes that don't.
Hello,
I can't receive the join accepts. The ldl doesn't even get to the RX mode and instantly goes for a RESET.
I'm getting radio faults and interrupt faults. Maybe it has to do with the ticks configuration ?
The debug messages look like this :
chIndex=0 freq=868100000 minRate=0 maxRate=5
chIndex=1 freq=868300000 minRate=0 maxRate=5
chIndex=2 freq=868500000 minRate=0 maxRate=5
set radio reset: ticks=39
clear radio reset: ticks=46
chIndex=0 freq=868100000 minRate=0 maxRate=5
chIndex=1 freq=868300000 minRate=0 maxRate=5
chIndex=2 freq=868500000 minRate=0 maxRate=5
OTAA is pending
add dither to otaa: ticks=111 delay=0
tx begin
ticks=162 freq=868500000 power=0 bw=125000 sf=7 size=23
offtime=100
interrupt fault
ticks=281
waiting to retry OTAA
radio fault detected, initiating radio reset
clear radio reset: ticks=318
channel is ready
add dither to otaa: ticks=6133 delay=0
tx begin
ticks=6187 freq=868300000 power=0 bw=125000 sf=8 size=23
offtime=100
interrupt fault
ticks=6397
waiting to retry OTAA
radio fault detected, initiating radio reset
clear radio reset: ticks=6434
channel is ready
add dither to otaa: ticks=16938 delay=0
tx begin
ticks=16990 freq=868100000 power=0 bw=125000 sf=9 size=23
offtime=100
interrupt fault
ticks=17367
waiting to retry OTAA
radio fault detected, initiating radio reset
clear radio reset: ticks=17405
Also I'm using the main loop given as an example
I'm using a STM32L412 on a custom PCB board with a SX1261
any help would be very appreciated.
thank you
You mentioned in another issue you'd like some kind of coordination before others submitted PRs. I have some SX1262 modules arriving soon, and I'd like to add support to this library (I can see where, and how). Just wanted to hear your thoughts on contributing this upstream before I start.
I share your frustration with the (over)complexity of the other implementations, after looking at either using semtech's reference which has SX1262 support already, or adapting arduino-lmic.
IMHO the handling of confirmed uplink messages can be improved. The number of retransmissions can be controlled by nbTrans, but control of further timing and data rate changes are not possible. The default ADR algorithm will eventually lower the rate on bad conditions, but that takes a lot of time. My first idea was, that LDL could get additional parameters for further repetitions and data rate changes. But that is not an ideal solution, when we encounter long delays for retransmissions the possibility is high, that updated measurements exists, that should be sent instead.
So I came to a solution, where I refactored some library code, so that two new callable functions exist:
With both functions the application can control the data rate very easily and retry a transmission on demand. It works well together with ADR, the network increases the data rate on demand and the application can decrease the data rate and repeat the transmission on packet loss.
I'm not sure, if that is the right solution and the code is of sufficient quality, so I did not create a pull request yet, but implemented that on a private branch only. The commit is https://github.com/frbehrens/lora_device_lib/commit/16fdba6dd2281611ecb0b13db2f2317cbc51be2f
What do you think?
Kind regards,
Frank
Hello. First of all I would like to thank you for the amazing library you wrote. I'm using it instead of loramac-node because your library is so much smaller. Also is not Arduino dependant like lmic (mcci port).
Anyway, I ported your code to a STM32 with a RFM95. The frequency plan I'm using is AU915 and for the development I use TTN. I was able to make the library transmit perfectly, but for some reason I'm not receiving correctly the OTAA response. This is the debug output from your library (plus some added by me).
tx begin
ticks=8630550 freq=917600000 power=0 bw=125000 sf=10 size=23
DIO0 Interrupt 8667667
offtime=100
tx complete
ticks=8668127
rx1 slot
ticks=9167831 timeout=8 lag=0 freq=925700000 bw=500000 sf=10
DIO1 Interrupt 9169402
rx2 slot
ticks=9266908 timeout=8 lag=1 freq=923300000 bw=500000 sf=12
DIO1 Interrupt 9273411
LDL_MAC_DEV_NONCE_UPDATED: 4
waiting to retry OTAA
I can see on the TTN console that the gateway is sending the downlink with the network join accept. But nevertheless, LDL is not receiving it. Not sure what to try. Could you give me a hint on what to test to find the problem?
Hello,
I updated successfully to the latest version 0.4.5 (597630c).
I see a different behaviour, compared to previous versions. The function LDL_MAC_ticksUntilNextEvent() returns always values less than 60 seconds, due to a armed LDL_TIMER_BAND timer. I use the value to calculate possible power down times for my application and that value is rather short.
Is it really necessary to have a timer for band events? The processing function is in any case called from LDL_MAC_process and at first glance I see no problems if more ticks elapse before the next call. I would like to get UINT32_MAX from LDL_MAC_ticksUntilNextEvent() when the last receive window is closed and no (MAC) messages are queued.
Kind regards,
Frank
These macros currently look like this:
LDL_DEBUG(APP, ...)
The APP argument is a hangover from some time ago when I thought it was useful to be able to link a message back to some instance. In practice a suitable pointer isn't always available, and even if one is, there is usually only on instance producing messages and so its redundant.
The ...
usually expands to something like:
LDL_DEBUG(NULL, "a format string with some number %d", 42)
This is a problem for anyone using AVR since you have no option of putting the format string into progmem.
I propose changing the pattern to:
LDL_DEBUG(FMT, ...)
This could then be redefined on your port as:
LDL_DEBUG(FMT, ...) printf(FMT, __VA_ARGS__);
Or if you are on AVR and want the string in flash:
LDL_DEBUG(FMT, ...) printf(PSTR(FMT), __VA_ARGS__);
etc.
I observed sometimes problems with joins, where a reduced rate is required due to a longer distance. I debugged this further and could see, that the TTN ignores repeated join frames with the same devNonce. That happens, when a join-accept downlink is lost, but not when the join-request uplink is lost.
The LoRaWAN standard (1.0.4) seems to require a different devNonce as well: "For each transmission of a Join-Request, the end-device SHALL increment the DevNonce value."
So I propose to increment the devNonce in LDL for every join request frame.
I created a PoC (https://github.com/frbehrens/lora_device_lib/commit/8e7c8acd76036a16cd3c07b6faa060e44930b24a), that solved the problem and allows a stable device join procedure.
What do you think about the issue?
I am having trouble importing this library to arduino?
Hello ,
i m having some troubles connecting my node to TTN as the node is stuck in the join procedure.
i thought it was a timer issue ,i was using stm32 1ms systick timer as a counter then i switched to lptim which is ticking at a rate of 16384 tick per second but the problem still persist i m still not recieving the joinaccept packets.
I've set a breakpoint in LDL_MAC_process() where LDL_Radio_collect() is called but its not reaching that point.
I'm using STM32L073RZ microcontroller with the semtech sx1272 transceiver , laird RX186 gateway and the TTN server stack
my node is about five meters away from the gateway
the joinrequest messages are received by TTN and its sending the join accept messages back.
also i tried to enlarge RX1/RX2 windows but wont work either
https://github.com/cjhdev/lora_device_lib/blob/94c64ba1cae06d81ee4d3b80d4895b543284ec27/src/ldl_mac.c#L570
https://github.com/cjhdev/lora_device_lib/blob/94c64ba1cae06d81ee4d3b80d4895b543284ec27/src/ldl_mac.c#L616
here is the link to my test repo
https://github.com/abdouTCH13/LDL_STM32L073RZ_test
any help would be very appreciated.
thank you
I believe - because we use for all operands and the result the same integer type - we can simplify the function in ldl_mac.c
static uint32_t timerDelta(uint32_t timeout, uint32_t time)
{
return (timeout <= time) ? (time - timeout) : (UINT32_MAX - timeout + time);
}
to
static uint32_t timerDelta(uint32_t timeout, uint32_t time)
{
return (time - timeout);
}
Hi,
I am wondering if we should call LDL_MAC_process
at least X times per second?
Regards
Hello, I'm using using an STM32L4 and thus I'm using LPTimer. The timer has a 16 bit resolution but the system ticks used in LDL assume the timer has a 32 bit resolution.
I read in another issue that you also use LPTIM so how do you solve this problem ?
regards
Hello,
I've been trying to use the library with my STM32L4 in Stop2 mode.
I'm using a software 32bit timer with my LPTimer to make it work all together as you told me to in my last issue.
The problem is happening at 2 different points in my program :
I'm using a SX1261 with the STM32L412KB, the timer used is LPTIM1 clocked at 1000KHz. The interrupt on pin DIO1 is getting handled and I'm calling LDL_Radio_handleInterrupt inside the callback.
I actually had no issue when not going into stop mode and simply looping with the LDL_mac_process.
I've tried forcing the loop through LDL_mac_process using LDL_MAC_priority but then it means the mcu is looping during a whole TX-RX sequence.
Thank you for your help
There is no explizit check for maximum message size. If the size is too big, it leads to the (wrong) error message LDL_STATUS_MACPRIORITY / "mac data has been prioritised".
I propose an explicit check like mentioned in the patch. I know, that the style does not match the library, therefore I did not create a pull request.
--- "a/src/ldl_mac.c"
+++ "b/src/ldl_mac.c"
@@ -1656,40 +1665,45 @@ static enum ldl_mac_status externalDataCommand(struct ldl_mac *self, bool confir
if(self->ctx.joined){
if(self->op == LDL_OP_NONE){
if((port > 0U) && (port <= 223U)){
if(self->band[LDL_BAND_GLOBAL] == 0U){
/* set desired power and rate */
self->tx.power = self->ctx.power;
#ifdef LDL_DISABLE_TX_PARAM_SETUP
self->tx.rate = self->ctx.rate;
#else
self->tx.rate = LDL_Region_applyUplinkDwell(self->ctx.region, uplinkDwell(self->ctx.tx_param_setup), self->ctx.rate);
#endif
if(selectChannel(self, self->ctx.rate, 0U, &self->tx)){
LDL_Region_convertRate(self->ctx.region, self->ctx.rate, &sf, &bw, &maxPayload);
+ if (len + LDL_Frame_dataOverhead() > maxPayload) {
+ LDL_INFO("message is too large");
+ return LDL_STATUS_SIZE;
+ }
+
(void)memset(&self->opts, 0, sizeof(self->opts));
if(opts != NULL){
(void)memcpy(&self->opts, opts, sizeof(self->opts));
}
self->opts.nbTrans = self->opts.nbTrans & 0xfU;
{
self->trials = 0U;
(void)memset(&f, 0, sizeof(f));
self->op = confirmed ? LDL_OP_DATA_CONFIRMED : LDL_OP_DATA_UNCONFIRMED;
f.type = confirmed ? FRAME_TYPE_DATA_CONFIRMED_UP : FRAME_TYPE_DATA_UNCONFIRMED_UP;
f.devAddr = self->ctx.devAddr;
f.counter = U16(self->ctx.up);
f.adr = self->ctx.adr;
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.