Maker Bounty: Pycom LoPy4 + OTAA on The Things Network (AU915 settings)

I’m all ears if someone has setup Pycom LoPy4 on The Things Network with OTAA activation (using AU915 settings). Please share your method here with a demonstration of both the LoPy4 Nano-Gateway, and a LoPy4 Node.

Fyi there is a support topic with Pycom, although given it seems to be localised around AU915, we’re not getting a lot of traction there.

The first solution we can replicate for both the Nano-Gateway and Node (both using Pycom LoPy4, on The Things Network with AU915 settings on Sub Band 2) will get a $300 store credit!

Hey, sorry for the delay. All code files as per Pycom Libraries on Github

Nano Gateway

config.py

import machine
import ubinascii

WIFI_MAC = ubinascii.hexlify(machine.unique_id()).upper()
# Set  the Gateway ID to be the first 3 bytes of MAC address + 'FFFE' + last 3 bytes of MAC address
GATEWAY_ID = WIFI_MAC[:6] + "FFFE" + WIFI_MAC[6:12]

SERVER = 'router.au.thethings.network'
PORT = 1700

NTP = "au.pool.ntp.org"
NTP_PERIOD_S = 3600

WIFI_SSID = 'XXX'
WIFI_PASS = 'YYY'

# for AU915
LORA_FREQUENCY = 916800000
LORA_GW_DR = "SF7BW125" # DR_5
LORA_NODE_DR = 5

ABP Node

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 ABP authentication params
dev_addr = struct.unpack(">l", binascii.unhexlify('2604126C'))[0]
nwk_swkey = binascii.unhexlify('ADFAAE719468D488F6125362B4197282')
app_swkey = binascii.unhexlify('23AA3ED54B9F8451A7CFCF416140775A')

# remove all the non-default channels
for i in range(0, 72):
    lora.remove_channel(i)

# set the 3 default channels to the same frequency
lora.add_channel(0, frequency=config.LORA_FREQUENCY, dr_min=0, dr_max=5)
lora.add_channel(1, frequency=config.LORA_FREQUENCY, dr_min=0, dr_max=5)
lora.add_channel(2, frequency=config.LORA_FREQUENCY, dr_min=0, dr_max=5)

# join a network using ABP (Activation By Personalization)
lora.join(activation=LoRa.ABP, auth=(dev_addr, nwk_swkey, app_swkey))

# 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, config.LORA_NODE_DR)

# make the socket blocking
s.setblocking(False)

for i in range (200):
    pkt = b'PKT #' + bytes([i])
    print('Sending:', pkt)
    s.send(pkt)
    time.sleep(4)
    rx, port = s.recvfrom(256)
    if rx:
        print('Received: {}, on port: {}'.format(rx, port))
    time.sleep(6)

OTAA Node

""" OTAA Node example compatible with the LoPy Nano Gateway """

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

# Initialize LoRa in LORAWAN mode.
lora = LoRa(mode=LoRa.LORAWAN)

# create an OTA authentication params
dev_eui = binascii.unhexlify('70B3D5499B5361C5') # these settings can be found from TTN
app_eui = binascii.unhexlify('70B3D57ED000FF1C') # these settings can be found from TTN
app_key = binascii.unhexlify('A72D4289A54613C3EB4738CB25B6BF5C') # these settings can be found from TTN

# set the 3 default channels to the same frequency (must be before sending the OTAA join request)
lora.add_channel(0, frequency=916800000, dr_min=0, dr_max=5)
lora.add_channel(1, frequency=916800000, dr_min=0, dr_max=5)
lora.add_channel(2, frequency=916800000, dr_min=0, dr_max=5)

# 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
while not lora.has_joined():
    time.sleep(2.5)
    print('Not joined yet...')

# remove all the non-default channels
# for i in range(3, 16):
#     lora.remove_channel(i)

# 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, 5)

# make the socket non-blocking
s.setblocking(False)

time.sleep(5.0)

""" Your own code can be written below! """

for i in range (200):
    s.send(b'PKT #' + bytes([i]))
    time.sleep(4)
    rx = s.recv(256)
    if rx:
        print(rx)
    time.sleep(6)

EDIT: OTAA code replaced with runnable code that fails to authenticate.

1 Like