How to receive downlink data on RAK811 pHat

Issue: How to receive downlink data on RAK811 pHat

Setup: RPi4B, RAK811 pHat

Server: TTN

I have a RAK811 pHat.
I have run sudo pip3 install rak811 to install the python library
Using python I am able to send uplink messages from my pHat to TTN.
Now I would like to investigate the downlink.
On my device’s page in TTN Console I have scheduled a downlink to be sent to the device. What command should I use in my python to access the downlink bytes at the pHat? Where are the commands in the rak811 library documented?
Thank you for any help you can offer.

Here is the text of my current code, in case it’s useful. It’s basically an example program I downloaded:

    #!/usr/bin/env python3
    from rak811 import Mode, Rak811

    lora = Rak811()
    lora.mode = Mode.LoRaWan = 'EU868'
    lora.dr = 5
    lora.send('Hello World')

Read the docs & look at the examples for the PIP?

I think it’s based on this:

Which means you need to add:

while lora.nb_downlinks:
            print('Received', lora.get_downlink()['data'].hex())
1 Like

Thank you @nmcc. Prior to posting here I had found that repository and I had found the “RAK811 Lora AT Command User Guide V1.4” in it. But that’s where I got stuck.

I can see the code you’ve quoted in the example file. I note that the key calls seem to be nb_downlinks and get_downlink. But I can see neither nb_downlinks nor get_downlink in the AT Command file.

Genuine (non-sarcastic!) question: how do I make the leap from what’s in the AT Command file to nb_downlinks and get_downlink? Is any of this written down anywhere?

Many thanks again for your help.

The code @nmcc quoted has worked (thank you!) and I am now receiving the downlink message. In fact I’m receiving the downlink message I scheduled at TTN an hour ago every time I run my code, even though I only scheduled it once.

How long does a scheduled downlink message last? Is there any way to mark it as “read” so you don’t receive it multiple times?

The library is Python that provides the functions - they aren’t part of the AT command file - effectively the library is a translation layer that converts AT commands to Python and vice-versa.

Lasts until it’s sent, then it disappears, there is no mark as read in LoRaWAN, there is confirm, but that’s a bag of worms. Most likely we need to find the command that says you’ve got the message at a local level.

That makes sense, thank you. So where are the available library commands (and their mappings to AT commands) written down?

That’s not what I’m seeing. It comes through time after time.

Erm, yeah, that’s the wonder of GitHub, lots of big brains writing code but no documentation. You have to read the source, Luke - particularly in the rak811 folder - although the examples are the best place to start and the command line info at the bottom of the main readme gives some hints on what you can expect to be able to do.

That’s going to be a bit tricky to debug - after each send the library runs for a period to look for responses and puts them in to a list which returns the next one each time you get_downlink.

Can you put a print(lora.nb_downlinks) just above the while line so you can see how many messages it actually thinks have come in - the whole block should be immediately after the lora.send

If they really keep appearing, I’d look at putting a serial-USB lead on and doing a manual send to see what an uplink gets you as a set of downlinks.

That’s helpful, thank you. It’s knowing where to look that’s the big stumbling block! I’ve now been able to extract Port, RSSI, SNR and length as well as the data itself.

I don’t know if it’s relevant but I can see the downlink being sent in the TTN console for the gateway. It would appear as though TTN is sending it every time.

Does anyone know how to stop TTN from sending a downlink message again and again?

It doesn’t in my experience - as I said, ideally you need to wire the RAK811 up to a serial lead and use the RAK serial tool or something else similar to trigger an uplink and see what actually comes back.

Or perhaps cross-post to TTN with a screen shot and lots and lots and lots of detail, with a sprinkling of detail - they are all sharks sniffing for blood over there :wink:

Thank you. Given that I can see in the TTN console that a downlink is being sent from TTN every time, is there anything further to be gained by doing what you suggest?

This screenshot shows three consecutive transactions, all showing a downlink being sent:

I haven’t scheduled a downlink message since early yesterday.

Bit distracted with a PCB layout here, but off the top of my head, it looks like you’ve got it joining every time, thereby reseting everything on the node? As it won’t have confirmed the downlink that was set to be confirmed (very bad think btw), it may well be in Groundhog Day.

Can you duplicate the lora.send('Hello World') line to see if sending something a few times enables the the confirmation to make it’s way up to TTN.

Ok, thanks. Sending a rak811 send "hi" from the command line seems to have cleared it. Crucially, I can see that a confirm/ack has now been sent:
This wasn’t being sent before.

You’re right, my code sends a join every time, because that’s what’s in the example code (in fact it does a hard reset every time too). I think I understand from what you’ve said that the downlink confirm/ack would normally be sent in the next uplink, but if you do a join (and/or a hard reset) before the next uplink is sent then you lose the flag in the node which says “send a confirm/ack”, the confirm/ack is not sent and the downlink comes down again. Is that about right?

I’m only sending a join and doing hard reset every time because that’s what was in the example code I downloaded. Clearly that code was for people only doing uplinks, something I hadn’t appreciated. How often is a join actually necessary?

Thanks again.

(No rush to reply, please finish your PCB layout!)


Once every battery change aka once every, ooh, three/four years?

Like many well meaning GitHub offerings, it’s not really documented as we’ve already observed and the example is mildly unhelpful at best and in this case, slightly obstructive. Really it should have had a loop with a 30 minute delay so you can see how it joins and then sits & sends every so often. There’s an implied assumption about knowing what an OTAA join is in the bigger picture.

Onwards & upwards!

Ah! I think I asked about this somewhere ages ago and was told “once per session”. I wasn’t really sure what a session was, so I just left the code alone!

I’m learning that!

I’ll rewrite my code at some point so that it doesn’t inhibit the downlink function.

Thanks again for your help!

There really isn’t anything for you to do - if you use LoRaWAN as intended, you’ll send uplinks and occasionally the library will tell you there is a downlink just after you’ve sent one of your uplinks.

It was the combination of join, send once, turn off that was causing the issue here. That is definitely not normal for a device.