Using LoPy devices with Congress

The LoPy devices from Pycom are quite neat: You get a relatively small device with built-in LoRa, BLE and WiFi support, GPIO pins, SPI, I2C and programming them is as simple as writing a few lines of Python.

They’ve made plugins for both Atom and Visual Studio Code but if you have the One True Editor you can upload the files both via FTP and the serial port.

Install the (optional) software

If you are using Atom or Visual Studio Code there’s a plugin named Pymakr that will help you deploy your code.

The configuration file itself is fairly simple. You can either connect to the built-in wifi access point named lopy-wlan-<id> and use FTP to transfer the files or update the device via the USB serial interface. When you’ve got a lot of LoPy devices in the same area the USB serial interface is probably the easiest to use.

The configuration file named pymakr.conf is used to configure your project; open it and set the address field to the name of your serial port (the name of the port might be different - use :

{
    "address": "/dev/cu.usbserial-DO0038M8",
    "username": "micro",
    "password": "python",
    "sync_folder": ".",
    "open_on_start": true
}

You can create a new main.py with some placeholder code first:

import pycom

print("Hello world!")

If you choose Pymakr: Run current file from the command menu the current open file will be uploaded and executed on the device. You should see “Hello world” in the console.

Create an application and a device in Congress

Head on over to the Congress front-end and create a new application (or just use an existing one if you prefer):

New application

Next create a new device in the same application. Choose OTAA as the device type, name it something suitable (“LoPy Test Device” ended up being my choice) and finish the device creation. We’ll get back to the device provisioning later.

New application

Get the LoPy code from Congress

Click on the “Download device configuration” in the Congress front-end, select the LoPy tab on top and copy the contents into your main.py file.

The resulting file should look something like this:

from network import LoRa
import socket
import time
import binascii
import pycom
import  machine

def flash_led(col):
    pycom.rgbled(col)
    time.sleep(0.1)
    pycom.rgbled(0x000000)
    time.sleep(0.1)

# Turn off the heartbeat blink and the LED
pycom.heartbeat(False)
pycom.rgbled(0x000000)

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

# Device provisioning. Use either OTAA or ABP
OTAA_DEVICE =  True

# OTAA parameters
dev_eui = bytes([ 0x00, 0x01, 0x09, 0x00, 0x00, 0x01, 0x4d, 0x52])
app_eui = bytes([ 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x01, 0x65])
app_key = bytes([ 0x4f, 0x94, 0x8c, 0x5d, 0xcd, 0xf1, 0x7d, 0x75, 0xe4, 0xe3, 0x8e, 0x5c, 0x4a, 0xa4, 0x15, 0xba])

# ABP parameters
dev_addr = 0x0
apps_key = bytes([ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ])
nwks_key = bytes([ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ])

if OTAA_DEVICE:
    lora.join(activation=LoRa.OTAA, auth=(dev_eui, app_eui, app_key), timeout=0)
else:
    lora.join(activation=LoRa.ABP, auth=(dev_addr, nwks_key, apps_key), timeout=0)

# wait until the module has joined the network
while not lora.has_joined():
    flash_led(0xff0000)

for i in range(1, 2):
    flash_led(0x0000ff)

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

# set the LoRaWAN data rate
s.setsockopt(socket.SOL_LORA, socket.SO_DR, 5)

# create a raw LoRa socket
s = socket.socket(socket.AF_LORA, socket.SOCK_RAW)

while True:
    flash_led(0xffff00)
    s.setblocking(True)
    s.send(bytes([0x11, 0x22, 0x33, 0x44, 0x55]))
    flash_led(0x00ffff)

    s.setblocking(False)
    data = s.recv(64)
    if len(data) > 0:
        print("Received data:",  data)

    time.sleep(10)

Note that the key and EUIs will be different for your application and device.

Select “Pymakr - Run current file” from the command menu to launch the program and provided that you are in range of a gateway you’ll see the LED flash red for a few seconds, then blue before flashing red every 30 seconds or so. If you check the Congress front-end you will see data from the device:

Receiving data

Making sure you can receive data

The final piece of the puzzle is sending data from Congress to the device. Type a few hex bytes into the “Device messages” box, select a port between 1 and 223 and click Send message to schedule a new message:

Sending a message to the device

The next time the module sends data and flashes green you should see the message Received data: b'\xaa\xbb\xcc\xdd\xee\xff' on the console. The actual payload will of course change depending on what you typed into the message box.

That’s it!