Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

examples/lorawan: add autonomous lorawan class A device example #8789

Merged
merged 1 commit into from
Jun 21, 2018

Conversation

aabadie
Copy link
Contributor

@aabadie aabadie commented Mar 16, 2018

Contribution description

This PR adds a simple example of use of RIOT with LoRaWAN. The example shows several concepts:

  • OTAA join procedure and sending of messages with a LoRaWAN class A device
  • low-power mode: the device go to STOP mode between each send
  • RTC: the device wakes up every 20s for a new send using RTC.

I had to slightly change the loramac pkg code to better handle caller thread pid: in this application each send is done by a sender thread which is different from the main thread, used for the join procedure.

Issues/PRs references

Now based on #8798

@aabadie aabadie added Area: pm Area: (Low) power management Area: LoRa Area: LoRa radio support labels Mar 16, 2018
@aabadie aabadie force-pushed the pr/examples/lorawan branch from 6d93a79 to 9f95963 Compare March 16, 2018 09:49
@aabadie aabadie added the CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR label Mar 16, 2018
@aabadie
Copy link
Contributor Author

aabadie commented Mar 16, 2018

Side comment: I'm unsure if the pm management is used like it should, same for the RTC. Comments are very welcome on those specific parts.

@aabadie aabadie force-pushed the pr/examples/lorawan branch 7 times, most recently from 366977d to 8367a4a Compare March 16, 2018 10:44
@aabadie
Copy link
Contributor Author

aabadie commented Mar 16, 2018

Finally fixed the CI. Maybe this PR could also interest @jia200x and @dylad.

@jia200x
Copy link
Member

jia200x commented Mar 16, 2018

Thanks @aabadie!
I guess also @paula75 and @fjmolinas will be interested.

I will give it a closer look

Copy link
Member

@dylad dylad left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks interesting ! But I don't see any call to pm_set(). You should put the device to sleep after the init I guess.

time.tm_sec -= 60;
}
while (time.tm_min > 60) {
time.tm_hour++;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should also add a guard to ensure tm_hour doesn't reach 25 hours.

{
#ifdef MODULE_PM_LAYERED
/* Ensure the low-power mode is blocked during initialization phase */
pm_block(PM_MODE);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no call to pm_unblock after initialization.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it is not needed because it's done at the end of the send function.

@aabadie aabadie force-pushed the pr/examples/lorawan branch from 8367a4a to dfe5caf Compare March 16, 2018 11:17
@aabadie
Copy link
Contributor Author

aabadie commented Mar 16, 2018

But I don't see any call to pm_set().

This is the part I'm unsure. I thought that when all threads are blocked, the system falls in the idle thread that itself calls pm_set_lowest(). Normally, the pm_set_lowest used is in sys/pm_layered/pm.c and this function should call pm_set. @kaspar030 am I right ?

@vincent-d
Copy link
Member

Actually, you should not call any pm_* function from app code. @kaspar030 will correct me if I'm wrong, but the goal of pm_layered is that only periph drivers blocks pm mode. But there are still a lot of parts missing in RIOT to have all this in place (xtimer and shell for instance are almost incompatible with this approach if they stay as-is).

@aabadie aabadie force-pushed the pr/examples/lorawan branch 3 times, most recently from 46eaae8 to 13373c9 Compare March 19, 2018 08:00
@aabadie aabadie added the State: waiting for other PR State: The PR requires another PR to be merged first label Mar 19, 2018
@aabadie aabadie force-pushed the pr/examples/lorawan branch 4 times, most recently from 3bba77c to 0038928 Compare March 19, 2018 19:34
semtech_loramac_channel_params_t params;
params.frequency = freq;
params.datarate = p.Datarate;
semtech_loramac_set_rx2_params(mac, params);
Copy link
Member

@dylad dylad Mar 24, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just wondering, isn't it a problem to call this function which will re-call mutex_lock(&mac->lock) before we unlock it ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes it is. Good finding. I admit I didn't test this function. If you try semtech_loramac_set_rx2_freq or semtech_loramac_set_rx2_dr from the shell application, I think the command will just hang.

@aabadie aabadie force-pushed the pr/examples/lorawan branch from 0038928 to 03d0847 Compare March 24, 2018 21:25
@@ -60,7 +60,7 @@ void TimerSetValue(TimerEvent_t *obj, uint32_t value)
xtimer_remove(&(obj->dev));
}

obj->timeout = (value - 50) * 1000;
obj->timeout = (value - 20) * 1000;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BTW what sorcery is this number?

Copy link
Contributor Author

@aabadie aabadie Mar 24, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comes from the specs: the RX windows start RX_DELAY seconds after the TX with +/-20ms error, so anticipating the RX window with 20ms should ensure that a message from the gateway is not missed.
The initial port was not very accurate : the RX windows were starting is little too late - probably because of thread switching overheads - and then were missing the gateway message preamble, that's why I anticipated them a little more (hence the arbitrary 50ms value). But with this PR, it behaves as expected, and it works with 20ms.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you add a little comment above this line to explain it please ? I don't think it is a good idea to have hardcoded number in the wild without any tips.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you add a little comment above this line to explain it please ?

that's a good idea (and practice), I'll change that.

@aabadie aabadie force-pushed the pr/examples/lorawan branch 2 times, most recently from aa422c8 to 6a85c3d Compare March 30, 2018 09:27
@dylad
Copy link
Member

dylad commented Apr 19, 2018

I took a look at RIOT's PM and I think @vincent-d is right. You must not call any pm_* function here. The idle must select the best PM mode by itself.
Otherwise this PR looks good and should be good to go :)

@aabadie
Copy link
Contributor Author

aabadie commented Apr 19, 2018

You must not call any pm_* function here. The idle must select the best PM mode by itself.

I know but the problem is that in this case it doesn't stop the MCU as I would expect. I'm testing with the b-l072z-lrwan1 board which is STM32L0 based.
Calling pm_set() seems to work, the MCU mode is set correctly, although power consumption seems higher than expected: I see almost no difference with the normal mode in stop mode (around 5mA).

@aabadie aabadie force-pushed the pr/examples/lorawan branch from 6a85c3d to c8b702e Compare April 19, 2018 14:14
@aabadie aabadie removed the State: waiting for other PR State: The PR requires another PR to be merged first label Apr 19, 2018
@aabadie aabadie force-pushed the pr/examples/lorawan branch from c8b702e to 563518b Compare April 19, 2018 14:15
@dylad
Copy link
Member

dylad commented Apr 19, 2018

Calling pm_set() seems to work, the MCU mode is set correctly

I understand what you means but this is something that must be handle at driver and board level not at application level. There is still a lot of work that need to be done in order to have a working and wonderful PM management ;)

@aabadie
Copy link
Contributor Author

aabadie commented Apr 19, 2018

I removed the use of pm_set from the example.

#include "semtech_loramac.h"

/* Use the STOP mode to ensure memory retention between each send */
#define PM_MODE (1)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not needed anymore

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed, fixed !

@fjmolinas
Copy link
Contributor

I see almost no difference with the normal mode in stop mode (around 5mA).

Although this doesn't have to do with the general discussion here, @aabadie in my experience working with pm modes for L0 and L1, there's a lot of stuff you have to do with peripherals and gpio's to reach the datasheet power modes consumption. Whats is implemented right now for L0 isn't enough, the biggest part is switching unused GPIO's to AIN and the driver part @dylad mentioned (I had a PR on this a long time ago, you can see #8403 to have an idea of what I mean).

@dylad
Copy link
Member

dylad commented Apr 19, 2018

there's a lot of stuff you have to do with peripherals and gpio's to reach the datasheet power modes consumption

+1 , I had to hack so much part of RIOT to get a sleep consumption around 20 uA with my SAML21 family.

@aabadie
Copy link
Contributor Author

aabadie commented Apr 19, 2018

Thanks @dylad and @fjmolinas for the information. I'll look at #8403 more closely to see how the low power consumption can be reached with the L0 board I have.

@aabadie aabadie force-pushed the pr/examples/lorawan branch from b933367 to c9f6013 Compare April 19, 2018 19:35
@tcschmidt
Copy link
Member

@dylad are still changes requested?

@dylad
Copy link
Member

dylad commented Jun 21, 2018

@tcschmidt I don't think so, the current state looks good to me and it works.
I guess I can ACK :)

@tcschmidt
Copy link
Member

@dylad great. Then hit merge?

@dylad dylad merged commit 2ae0e1c into RIOT-OS:master Jun 21, 2018
@miri64
Copy link
Member

miri64 commented Jun 21, 2018

@miri64
Copy link
Member

miri64 commented Jun 21, 2018

This is why we don't merge with builds that are ages old..

@miri64
Copy link
Member

miri64 commented Jun 21, 2018

See #9393 for fix. Guess someone owes the community a box of beer ;-)

@tcschmidt
Copy link
Member

@miri64 you'll get free beer on Saturday!

@dylad
Copy link
Member

dylad commented Jun 21, 2018

Sorry @miri64, I was not aware we need to re-triggers Murdock for this :(

@miri64
Copy link
Member

miri64 commented Jun 21, 2018

No problem. It was an easy fix after all ;-)

@tcschmidt
Copy link
Member

@dylad we all live and learn - you'll get free beer at the RIOT summit.

@aabadie aabadie deleted the pr/examples/lorawan branch June 26, 2018 18:57
@cladmi cladmi added this to the Release 2018.07 milestone Jul 10, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area: LoRa Area: LoRa radio support Area: pm Area: (Low) power management CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants