LoPy4 LoRaWAN Nano Gateway and Node - ABP and OTAA issues

  • Hi there,

    I've been trying to implement a LoRaWAN Nano-gateway and node, both using LoPy4 units. The gateway seems to be working fine for me as it can be seen to be connected on the TTN console, connecting to router.au.thethings.network. However, I can't seem to get the node to connect to the Nano-gateway.

    I've tried connecting using both ABP and OTAA but have encountered problems with both of these. I'm in New Zealand, using the AU915 plan with a gateway frequency of 916.8 MHz. I'm using the LoPy4 units connected to a Pytrack and a Pysense and I'm using the most recent firmware updates for all devices.

    I'm using the following code (only using one of the lora.join() authentication types at a time):

    from network import LoRa
    import socket
    import binascii
    import struct
    import time
    import config
    # initialize LoRa in LORAWAN mode.
    # Please pick the region that matches where you are using the device:
    # Asia = LoRa.AS923
    # Australia = LoRa.AU915
    # Europe = LoRa.EU868
    # United States = LoRa.US915
    lora = LoRa(mode=LoRa.LORAWAN,region=LoRa.AU915)
    # create an OTA authentication params
    dev_eui = binascii.unhexlify('XXXX')
    app_eui = binascii.unhexlify('XXXX')
    app_key = binascii.unhexlify('XXXX')
    # create an ABP authentication params
    dev_addr = struct.unpack(">l", binascii.unhexlify('XXXX'))[0]
    nwk_swkey = binascii.unhexlify('XXXX')
    app_swkey = binascii.unhexlify('XXXX')
    for channel in range(0, 72):
    lora.add_channel(0, frequency=916800000, dr_min=0, dr_max=4)
    # join a network using ABP (Activation By Personalization)
    lora.join(activation=LoRa.ABP, auth=(dev_addr, nwk_swkey, app_swkey))
    # join a network using OTAA
    #lora.join(activation=LoRa.OTAA, auth=(dev_eui, app_eui, app_key), timeout=0)
    # wait until the module has joined the network
    join_wait = 0
    while True:
        if not lora.has_joined():
            print('Not joined yet...')
            join_wait += 1
            if join_wait == 5:
                print("Trying again...")
                lora.join(activation=LoRa.ABP, auth=(dev_addr, nwk_swkey, app_swkey))
                join_wait = 0
    # create a LoRa socket
    s = socket.socket(socket.AF_LORA, socket.SOCK_RAW)
    # set the LoRaWAN data rate
    s.setsockopt(socket.SOL_LORA, socket.SO_DR, 3)
    # make the socket non-blocking
    for i in range (200):
        pkt = b'PKT #' + bytes([i])
        print('Sending:', pkt)
    • Using OTAA, the program seems to become stuck in the lora.join() function as I never see the 'Not joined yet' message.

    • Using ABP, the node says that it has joined a LoRaWAN network (lora.has_joined() returns True) but cannot send anything. I see 'Sending: b'PKT #\x00' and 'Sent' but nothing else in the loop. The gateway shows no indication that it has received anything other than 'Push ack' and 'Pull ack' and nothing is seen on the TTN Gateway Traffic entries or the Application Data.

    I've tried looking at other forum posts that encounter similar problems but the solutions presented in those, such as changing the channels created/removed or the data rate, haven't worked for me. Does anyone know what I may be able to try to fix these problems?

  • @bed Yes, approach it step by step. First check the RF connection witrh the simple examples, which are tricky too. Then try ABP join, since that does not need downlink messages. After that go for OTAA join. There is indeed a problem with DRl 0 in the official 1.17.3.b1 revision, see https://github.com/pycom/pycom-micropython-sigfox/commit/ae3a294c40026433dbdac3e08da788b2b4c4dfdb, but that should not affect here.

  • @rg_elect Glad that the OTAA is progressing.

    As the nano-gateway is listening on Channel 0, I would remove 1 and 2 as well. That will force the sends to be on exactly 915.2. With the GW using SF7BW125, that looks like it's DR 5 not 3. So I would try LORA_NODE_DR = 5.

    I don't know much about the mechanism of the OTAA or the nano gateway so I could be off base here. But it would be neat if the nano-gateway received a message -- does it print out to the console when it does?

    Anyway, I would suggest removing 1 and 2, and using DR 5 instead of 3.

  • @bed Hi.
    I am getting the “not connected yet” in terminal from the lopy4node. I have removed all channels except 0,1,2 and all on 915200000 freq and data rate 3. I am not sure how to check the freq the nanogateway is listening on? I have setup the gateway config.py file for
    LORA_FREQUENCY = 915200000
    LORA_GW_DR = "SF7BW125"
    LORA_NODE_DR = 3

    This should setup the freq it is listening on but I need to query the process on what it is actually on?

  • There are a couple of problems with the 0.17.3b1 release around AU915 -- if there are no channels to transmit on, the code will keep looping looking for a channel. Like forever! If you aren't seeing 'Not joined yet....' then I suspect the sends for the OTAA join are stuck in that loop. In 0.17.3b1, the add_channel() command has a problem (fixed on github) which will make your add_channels silently fail. I don't know if the add_channel() when it fails removes the channel. If so then there would be no channels, so the OTAA join sends would loop forever.

    If you comment out the section of code which removes channels and add channels, then if I'm right, the 'Not joined yet...' messages should start coming out, as the standard channels are setup when in the LoRa() call. I would try that first.

    I haven't used a nano-gateway, but as has been said, it will only listen on a single frequency, so you need to make sure that your LoPy4 is using the same frequency. If it is on a standard frequency, then I would just use lora.remove_channel() to get rid if all other channels (until a new release is created). Then all LoPy4 transmissions should be transmitted on the channel that the nano gateway is listening on.

    Good luck!

  • @dillang Yes that's as far as it gets. I have a feeling it is in the RF connection between the node and the gateway. The gateway doesn't seem to hear it. I have tried all sorts of node codes but it think theres and issue in the gateway RF settings? My gateway shows push and pull ACK from TTN but nothing from the node.

  • @dillang The gateway should print a message when it received a packet from the node, even when the TTN parameters do not match. If not, the may work at different frequencies. The nanogateway listens only at a single frequency. So better sort that out first, and then carry on. You may also use the simple examples (e.g. https://github.com/pycom/pycom-libraries/tree/master/examples/lopy-lopy or https://github.com/pycom/pycom-libraries/tree/master/examples/loraNanoGateway) to verify, that the RF set-up works.
    And yes, if you use revision 1.17.3.b1 of the firmware, you have to use also the most recent copy of the nano-gateway code from the library.

  • @rg_elect Do you ever see the "Not joined yet..." message? I semi-solved this by downgrading the firmware version on the node to 1.13.0.b1, before they implemented the ability to select the LoRa region when the LoRa object is initialised. This solved the issues I had with joining and sending messages.

  • Hi,
    I am also having the same issues with my lopy4 node not joining. Issue is the same as @DillanG was there any resolution to this? my gateway is a lopy and is connected to TTN my node is a lopy4 and have the OTAA copied into the main.py file.

    from network import LoRa
    import socket
    import binascii
    import struct
    import time
    import config

    lora = LoRa(mode=LoRa.LORAWAN, region=LoRa.AU915, adr=False, tx_retries=0, device_class=LoRa.CLASS_A)

    dev_eui = binascii.unhexlify('AABBCCDDEEFF7778')

    app_eui = binascii.unhexlify('****D57ED000C4EF')

    app_key = binascii.unhexlify('*****6CAC02F5742C41EE594460FDF87')

    for i in range(16, 65):
    for i in range(66, 72):

    print("ADD CHANNELS")

    for i in range(8, 15):
    lora.add_channel(i, frequency=915200000 + i * 200000, dr_min=0, dr_max=3)
    lora.add_channel(65, frequency=917500000, dr_min=4, dr_max=4)

    for i in range(0, 7):
    lora.add_channel(i, frequency=923300000 + i * 600000, dr_min=0, dr_max=3)


    lora.join(activation=LoRa.OTAA, auth=(dev_eui, app_eui, app_key), timeout=0)

    while not lora.has_joined():

    print('Not joined yet...')

    s = socket.socket(socket.AF_LORA, socket.SOCK_RAW)

    s.setsockopt(socket.SOL_LORA, socket.SO_DR, config.LORA_NODE_DR)

    for i in range (200):

    pkt = b'PKT #' + bytes([i])
    print('Sending:', pkt)
    rx, port = s.recvfrom(256)
    if rx:
        print('Received: {}, on port: {}'.format(rx, port))

  • Hi @dillang

    I'm also using the AU915 plan and have had a similar problem. Looking at another issue in this forum: fipy_lorawan-otaa-join-freezing-after-subband-selection I think that it's the same issue.

    @jmarcelino has put in a patch which may fix this, though it isn't in a release yet.

    Good luck,

  • @dillang It depends on the combinations of versions. With 1.17.3.b1, you have to use the most recent copy of the nanogateway example from the github repository of the library. The difference: it must use ticks_cpu() instead of ticks_us() for time taking.
    This new version of the nanogateweay example does not work with older versions of the firmware. Uplinks work, but no downlinks, including teh one sent during OTAA join.

  • Solved by downgrading the firmware on the LoPy4 running as the node to version 1.13.0.b1.

    OTAA join requests work and messages can be sent from the node and appear on the TTN console.

  • @robert-hh
    I tested the LoPy4 units with code for Raw LoRa and I was able to transmit and receive messages between the two units so I don't think there is a problem with the antennae I'm using.

    Carrying on using ABP to join, the program definitely gets stuck with the s.send() function. I tried this by setting up the socket with the main program and then typing s.send('Hi') into the REPL. This returned a value of 2 (for the number of bytes I'm guessing??) and then became unresponsive.

    If the settings between gateway and node are different, am I correct in thinking that the node should still be able to send messages? Just the gateway I'm using won't be able to detect them?

    Are there any reasons why the send function might make the LoPy4 unresponsive? Are there some socket parameters that I may have not set?

  • @robert-hh
    Checking the codes for both node and gateway, I have the following parameters set:

    • Gateway frequency and node single channel frequency - both set to 915 MHz
    • Spreading rate - both set to 7
    • Coding rate - both set to CODING_4_5
    • Bandwidth - both set to 125 kHz
    • Data rate - "SF7BW125" in config file for the gateway, 3 for the node socket

    Is there anything I'm missing?

    Also, the documentation says that rx_iq cannot be changed from False when initialising a LoRa object in LoRaWAN mode for the node. Is there another function to change this?

  • @dillang You will always see some messages at a very low rssi level. That's just noise. Besides that, gateway & node have to be set to the same parameters. There is one parameter, which can be different. At the node, it's rx_iq=True, whereas on the gateway it's tx_iq=True. Although with just one node & gateway, it should work with the default settings.
    If I read the spec right, it's DR3. With the call to add_channel, you can set the frequency for that channel.
    Having the antennas a metre apart is a little bit too close, according to the recommendation. But I did that too. Just take care, that the antennas have the same orientation. The should stick both upright.

  • @robert-hh
    The gateway does receive some message packets but I don't think they are from my node as they do not correspond to when I try to send from the node.

    For the gateway RF characteristics, is the only thing I need to change the datarate input to the gateway initialisation?
    Currently it is set up as "SF7BW125". Is the data rate set in setsockopt(socket.SOL_LORA, socket.SO_DR, 3) correct for this? Or should the '3' be something else? I read that SF7BW125 is DR_5 for the EU868 plan but DR_3 for the US915 and AU915 plans. Are there any other settings for the node that I need to change?

    For the node, I checked the spreading factor with lora.sf() and this returned '7' and lora.bandwidth() returned '0' which the documentation says means BW_125KHZ. When I use the lora.frequency() function, it returns '915000000'. Is this incorrect if I want the node to transmit at 916.8 MHz? Or is it okay to just set the channel frequency to be what I want? I tried changing the node channel and gateway frequencies to 915 MHz but still no luck.

    With regards to the antenna setup, the node and gateway are about a metre apart and I'm sure I've attached the antennae to the correct 868/915MHz slot on the LoPy4. The actual antennae have been purchased from Pycom and I'm sure they're the correct antennae.

  • @dillang At least the log of the gateway should show, that it receives a packet, even if the TTN server cannot deal with it.. That is completely independent from the settings of the TTN server. Then, you should check the basics, like having set the same RF characteristics (frequencies, spreading factor, data rate) for both the node and the gateway, and things like proper antenna set-up for both devices.

  • @robert-hh, I've copied the correct entries for the keys and IDs from the TTN page for the device. I double checked the device EUI from the LoPy4 but I still can't get anything to work.

  • @dillang ABP join normally works, but requires some more manual configuration than OTAA. All the keys and IDs listed in your script have to be entered manually. The dev_eui is assigned to your device by Pycom, and has to be entered in the TTN Server registration. The app_eui and app_key are generated by the TTN server and have to be entered into your script. Furtheron, when using ABP, the TTN server creates the dev_addr, nwk_swkey and app_swkey. These have to be copied form the server into your scripts. These three values are exchanged automatically when using OTAA join, encrypted by the app_key.


Pycom on Twitter