Registering a device using OTAA

I am attempting to connect a node that is based on the Raspberry Pico and a Waveshare SX1262, I think I am nearly there but I’m not seeing the registration through the gateway. What I would like to confirm is the structure of the registration message.

From TTNs documentation I understand it should be:

  • 8 bytes of AppEUI
  • 8 bytes of DevEUI
  • 2 bytes of DevNonce
  • 4 bytes of MIC

So if I my above detail are (yes all complete rubbish values):

  • AppEUI - 01 02 0A 0B 04 06 0C 0D
  • DevEUI - A1 B2 1C 1D 86 72 C5 DA
  • DevNonce - 24 AC
  • MIC - 54 E0 0F 34

Does the message that I need to send simply become

        AppEUI                  DevEUI          Nonce   MIC
<---------------------> <---------------------> <---> <--------->
01 02 0A 0B 04 06 0C 0D A1 B2 1C 1D 86 72 C5 DA 24 AC 54 E0 0F 34

Or do some parts of this need reversing (MSB ↔ FSB)?

I don’t suppose the is a calculator anywhere online where you can provide the AppEUI, DevEUI and Nonce and get the message string with MIC returned?

Tom

There is this online decoder https://lorawan-packet-decoder-0ta6puiniaut.runkit.sh/
You can use this to decode a packet, so you could use it to verify that the packet you’ve compiled in your software makes sense.

Writing your own LoRaWAN device stack seems like a considerable piece of work.

I haven’t taken complete leave of my senses - yet! :wink:

It is micropython I found provided by someone else for using this Waveshare module with LoRaWAN, seems to be the only example - all the rest are peer to peer. The problem is that the author was using it with ChirpStack rather than TTN. I’m assuming it works, but I’ve had to pull out the calibration steps for now as they don’t. I’m now at the stage that it is performing the OTAA, but nothing is appearing.

I have the string that it creates which includes all the above points, but it also has a spare byte at the beginning set to 0 and it reverses some of the data. I’m not sure what TTNs requirement is, have tried it reversed and not with and without the spare byte and getting no results.

I’ll try putting the string into the decoder this evening and see what I get.

Care to share a link, just in case a brief inspection reveals a quick fix!

LoRaWAN has a very detailed specification and is an ITU (ITU-T Y.4480) standard. As the CTO of TTI sits on some of the standards committee, we can be assured that he’s making sure that TTS sticks to the spec!

Certainly, the code I’ve used can be found here…

GereZoltan/LoRaWAN: Possibly complete LoRaWAN implementation in micropython with SX1262 (github.com)

As you can see, it’s well used, no activity in 2 years and I’m the only person that has commented. As I say I have found nothing else regarding using this module to connect to LoRaWAN written in MicroPython. WaveShare do provide a C version, but the rest of the project is written in MicroPython.

The OTAA function can be found in the LoRaWANHandler.

Good to know that the spec is/should be the same, I was going to ask whether everyone has the same OTAA request because as I say there appears to be an extra blank byte on the front of this string. When I pick up again later I’m going to take the string and stick it in the decoder mentioned above.

Not should, is. Both ChirpStack and The Things Stack implement a ratified standard.

And as a result there shouldn’t be any changes to the code required to switch from one to the other. It would be interesting to see if the code still works with ChirpStack, perhaps a change in MicroPython causes issues…

So using the decoder mentioned above, it does seem to need a preceding blank byte, which looks to be called MHDR?

Also, the DevEUI and AppEUI do need to be reversed when building the join string to get a valid decode.

Which leaves me now needing to figure out when OTAA isn’t working

Would it be helpful if you take a look at the LoRaWAN specification?

On page 15 you will find the definition of MHDR, The Join request is specified on page 34.
(Page 70 has a glossary should you encounter fields not mentioned like RFU)

Given the definition of MHDR I very much doubt is should be set to 0 for a join request.

Looks like it should be 1C to join?

Wasn’t aware of this, I’d been looking at this…

End Device Activation | The Things Network

As you already found that page does not list the full LoRaWAN packet. It’s better to always check the formal specification as well (if available, which for LoRaWAN is the case).

Don’t know how you came to that value, but MHDR is
Bit 7…5 4…2 1…0
MType RFU Major

For a join request message type is 000. RFU is always all zeros. And Major is (strangely) 00 for LoRaWAN V1.

So I was wrong in my previous message and 00 seems to be the correct value after all (another reason to always check the specification)

I got the M Type as 000

My take on
image
was that RFU was 0111 and Major was 00

Giving
0000111000

Which I must then have typed into calculator incorrectly, one 0 short on the right, giving 1C, should have been 38.

But you say it should be 00

From the decoder, it looks like 00 is correct

image

And the rest of the values look correct, so I’m left wondering whether:

  1. there is something wrong in the code
  2. something wrong in the transmitter
  3. something wrong with the gateway

As I don’t have anything else to transmit with on 868, I’m struggling at the moment.

Can anyone recommend a super cheap 868 off the shelf node? A temperature sensor or similar that I could use to rule out the gateway? Cheapest I’ve seen is best part of £30 on Amazon, maybe that is as cheap as I’ll get?

Can you check the gateway console at TTN to check the details of the received join request? The console should show the EUIs and the frequency.
(EUIs are public information transmitted unencrypted so don’t bother blacking them out. The AppKey is secret and won’t be part of the request)

Please post the details.

For an off the shelf product, search LDS02. Over here one of the cheapest reliably working sensors.

The gateway console on TTN ticks away every minute, very occasionally a spurious entry will appear in there, no idea from where because it happens even when my node isn’t powered up.

I never see a any form of message detected when I try the node.

Even the LDS02 is £30 when delivered over here!

Seriously thinking of ditching the Pico and this module and using an Arduino or something, any thoughts or guidance, need to be able to connect some sensors to it for a weather station. Did ponder a T-Beam, but they aren’t so cheap, but some have integrated charging which could be useful.

It helps if you show a screen shot so we can check what happens.

Then either the node is not transmitting or not using the right frequencies.

Don’t get an Arduino UNO or alike module with the 8 bit chips. They lack the memory required for a full LoRaWAN stack and sensors.

If you check there might be some old stock lopy (from pycom) available if you want to use python with LoRaWAN.
If you are up for embedded C programming there is a multitude of options. Make sure to choose on based on a controller with sufficient memory.
The easiest solution might be to hook a Grove E5 module to your Pico and use the uart with ascii commands. The other boards from Seeed with the same chipset can be programmed with the
Arduino IDE and STMduino and it’s LoRaWAN stack.

The gateway feed…

I suspect the node either simply doesn’t transmit or what it does transmit simply isn’t valid so the gateway ignores it?

I was using MicroPython because I wrote all the code for the weather sensor components on the Pico in that.

Grove E5 and the Pico is an option, or as you say something in the more powerful Arduino range, I’ve not looked at the options, but I’d guess there must be something with the LoRa onboard.

Not related to the actual question at hand but I really cannot recommend Pycom modules. That ship has sunken too far and is at Titanic level now. And bankrupt. I have 60 LoPy4 in deployment and that is no good experience. -100/10
I mean… there’s communication. I receive uplinks. And that’s about it. Not mentioning a lot of other points about their whole uPy branch.

Gateways only ignore LoRaWAN packets that fail the CRC check. Everythings else is forwarded to the network server.

Those are at this time still the best python powered solution I’ve come across. However there are far better solutions when you can skip python.

Received my Grove E5, will take a look for some examples of using Micropython with Pico to connect to TTN using OTAA and transfer data.

Got the E5 working in short order, then once again work and the likes got in the way.

Back to it tonight and have again sent the test outlined in this page…

Raspberry Pi Pico with LoRaWAN and The Things Network - Makerverse LoRa-E5 Module - Transmit Weather Data into IoT - Tutorial Australia (core-electronics.com.au)

Which should contain 2 payloads (if you search for “Payload 1” you find it). Looking in TTN Gateway Console I can see 3 uplinks, each followed by a downlink - which makes sense. What I can’t see in any of the uplinks is a payload that in anyway matches the 2 payloads I’m meant to be seeing. Sadly the screen shots aren’t clear, but it looks like they are actually looking under the application, but I can’t see them there either.

The following is the Gateway live data…


I’m assuming I should find the payload in the detail panel when clicking on the 3 “receive uplink message” lines, but I don’t - unless it has become encoded into the raw in what looks like Base64

1st

{
  "name": "gs.up.receive",
  "time": "2023-11-10T22:28:25.971716942Z",
  "identifiers": [
    {
      "gateway_ids": {
        "gateway_id": "mintlaw-gateway-01",
        "eui": "B827EBFFFE563AC0"
      }
    }
  ],
  "data": {
    "@type": "type.googleapis.com/ttn.lorawan.v3.GatewayUplinkMessage",
    "message": {
      "raw_payload": "AAYAAAAAAACAXr0wMiDx9yyQu8dpgJU=",
      "payload": {
        "m_hdr": {},
        "mic": "x2mAlQ==",
        "join_request_payload": {
          "join_eui": "8000000000000006",
          "dev_eui": "2CF7F1203230BD5E",
          "dev_nonce": "BB90"
        }
      },
      "settings": {
        "data_rate": {
          "lora": {
            "bandwidth": 125000,
            "spreading_factor": 12,
            "coding_rate": "4/5"
          }
        },
        "frequency": "868500000",
        "timestamp": 3497045146,
        "time": "2023-11-10T22:28:25.960534095Z"
      },
      "rx_metadata": [
        {
          "gateway_ids": {
            "gateway_id": "mintlaw-gateway-01",
            "eui": "B827EBFFFE563AC0"
          },
          "time": "2023-11-10T22:28:25.960534095Z",
          "timestamp": 3497045146,
          "rssi": -78,
          "channel_rssi": -78,
          "snr": 7.75,
          "location": {
            "latitude": 57.52503521045234,
            "longitude": -2.004565000534058,
            "source": "SOURCE_REGISTRY"
          },
          "uplink_token": "CiAKHgoSbWludGxhdy1nYXRld2F5LTAxEgi4J+v//lY6wBCa2cKDDRoMCInduqoGEMW8os8DIJDziMHj/CI=",
          "received_at": "2023-11-10T22:28:25.953815107Z"
        }
      ],
      "received_at": "2023-11-10T22:28:25.971546181Z",
      "correlation_ids": [
        "gs:uplink:01HEXNKJQKE4KHB28SBYF08GH9"
      ]
    },
    "band_id": "EU_863_870"
  },
  "correlation_ids": [
    "gs:uplink:01HEXNKJQKE4KHB28SBYF08GH9"
  ],
  "origin": "ip-10-100-7-161.eu-west-1.compute.internal",
  "context": {
    "tenant-id": "CgN0dG4="
  },
  "visibility": {
    "rights": [
      "RIGHT_GATEWAY_TRAFFIC_READ"
    ]
  },
  "unique_id": "01HEXNKJQKAM2X6CAXW7JDP3DW"
}

2nd

{
  "name": "gs.up.receive",
  "time": "2023-11-10T22:28:36.468274375Z",
  "identifiers": [
    {
      "gateway_ids": {
        "gateway_id": "mintlaw-gateway-01",
        "eui": "B827EBFFFE563AC0"
      }
    }
  ],
  "data": {
    "@type": "type.googleapis.com/ttn.lorawan.v3.GatewayUplinkMessage",
    "message": {
      "raw_payload": "QNEnCyaAAAAI4gNpEF4GaFcC6O1sFz7ALg==",
      "payload": {
        "m_hdr": {
          "m_type": "UNCONFIRMED_UP"
        },
        "mic": "Fz7ALg==",
        "mac_payload": {
          "f_hdr": {
            "dev_addr": "260B27D1",
            "f_ctrl": {
              "adr": true
            }
          },
          "f_port": 8,
          "frm_payload": "4gNpEF4GaFcC6O1s"
        }
      },
      "settings": {
        "data_rate": {
          "lora": {
            "bandwidth": 125000,
            "spreading_factor": 12,
            "coding_rate": "4/5"
          }
        },
        "frequency": "868500000",
        "timestamp": 3507541181,
        "time": "2023-11-10T22:28:36.457109928Z"
      },
      "rx_metadata": [
        {
          "gateway_ids": {
            "gateway_id": "mintlaw-gateway-01",
            "eui": "B827EBFFFE563AC0"
          },
          "time": "2023-11-10T22:28:36.457109928Z",
          "timestamp": 3507541181,
          "rssi": -77,
          "channel_rssi": -77,
          "snr": 9.25,
          "location": {
            "latitude": 57.52503521045234,
            "longitude": -2.004565000534058,
            "source": "SOURCE_REGISTRY"
          },
          "uplink_token": "CiAKHgoSbWludGxhdy1nYXRld2F5LTAxEgi4J+v//lY6wBC9qcOIDRoMCJTduqoGEJ2um98BIMiE/M2K/SI=",
          "received_at": "2023-11-10T22:28:36.422155853Z"
        }
      ],
      "received_at": "2023-11-10T22:28:36.468113181Z",
      "correlation_ids": [
        "gs:uplink:01HEXNKWZMNV3QNVS0R2G8KY5Z"
      ]
    },
    "band_id": "EU_863_870"
  },
  "correlation_ids": [
    "gs:uplink:01HEXNKWZMNV3QNVS0R2G8KY5Z"
  ],
  "origin": "ip-10-100-7-161.eu-west-1.compute.internal",
  "context": {
    "tenant-id": "CgN0dG4="
  },
  "visibility": {
    "rights": [
      "RIGHT_GATEWAY_TRAFFIC_READ"
    ]
  },
  "unique_id": "01HEXNKWZM9HCHYMGS1H5D4S3B"
}

3rd

{
  "name": "gs.up.receive",
  "time": "2023-11-10T22:28:44.594079793Z",
  "identifiers": [
    {
      "gateway_ids": {
        "gateway_id": "mintlaw-gateway-01",
        "eui": "B827EBFFFE563AC0"
      }
    }
  ],
  "data": {
    "@type": "type.googleapis.com/ttn.lorawan.v3.GatewayUplinkMessage",
    "message": {
      "raw_payload": "QNEnCyaFAQADBwb/CgiM1Sr8v1svvT0l0DRatRp4KTNCVQ==",
      "payload": {
        "m_hdr": {
          "m_type": "UNCONFIRMED_UP"
        },
        "mic": "KTNCVQ==",
        "mac_payload": {
          "f_hdr": {
            "dev_addr": "260B27D1",
            "f_ctrl": {
              "adr": true
            },
            "f_cnt": 1,
            "f_opts": "AwcG/wo="
          },
          "f_port": 8,
          "frm_payload": "jNUq/L9bL709JdA0WrUaeA=="
        }
      },
      "settings": {
        "data_rate": {
          "lora": {
            "bandwidth": 125000,
            "spreading_factor": 8,
            "coding_rate": "4/5"
          }
        },
        "frequency": "867300000",
        "timestamp": 3515690416,
        "time": "2023-11-10T22:28:44.582701921Z"
      },
      "rx_metadata": [
        {
          "gateway_ids": {
            "gateway_id": "mintlaw-gateway-01",
            "eui": "B827EBFFFE563AC0"
          },
          "time": "2023-11-10T22:28:44.582701921Z",
          "timestamp": 3515690416,
          "rssi": -77,
          "channel_rssi": -77,
          "snr": 16.5,
          "location": {
            "latitude": 57.52503521045234,
            "longitude": -2.004565000534058,
            "source": "SOURCE_REGISTRY"
          },
          "uplink_token": "CiAKHgoSbWludGxhdy1nYXRld2F5LTAxEgi4J+v//lY6wBCw27SMDRoMCJzduqoGEN6mmpsCIIDv6fuo/SI=",
          "received_at": "2023-11-10T22:28:44.561212519Z"
        }
      ],
      "received_at": "2023-11-10T22:28:44.593924958Z",
      "correlation_ids": [
        "gs:uplink:01HEXNM4XJ0DNEEJYRB3RVP0AT"
      ]
    },
    "band_id": "EU_863_870"
  },
  "correlation_ids": [
    "gs:uplink:01HEXNM4XJ0DNEEJYRB3RVP0AT"
  ],
  "origin": "ip-10-100-7-161.eu-west-1.compute.internal",
  "context": {
    "tenant-id": "CgN0dG4="
  },
  "visibility": {
    "rights": [
      "RIGHT_GATEWAY_TRAFFIC_READ"
    ]
  },
  "unique_id": "01HEXNM4XJCMW6JJB6PJPHQH6R"
}