Andreas Motzek
Published © CC BY

Using The Things Network with ATOM Lite and LoRaWAN Unit

Learn how to send messages to The Things Network with MicroPython. You will need a The Things Network Gateway near you.

IntermediateFull instructions provided2 hours7,594
Using The Things Network with ATOM Lite and LoRaWAN Unit

Things used in this project

Hardware components

ATOM Lite ESP32 Development Kit
M5Stack ATOM Lite ESP32 Development Kit
×1
M5Stack LoRaWAN Unit 868MHz
×1

Software apps and online services

MicroPython Firmware for ESP32 v1.19.1
Download esp32-20220618-v1.19.1.bin from the download page.
The Things Stack
The Things Industries The Things Stack
Go to https://www.thethingsnetwork.org and sign up for an account if you don't have one.

Story

Read more

Code

main.py

Python
Fill in your DevEUI, AppEUI and AppKey in line 7.
from cooperative_multitasking import Tasks
from machine import UART
from lora_states import NOT_JOINED, JOINING, JOINED, SENDING, SENT, RETRY
from asr6501 import ASR6501

tasks = Tasks()
uart2 = UART(2, tx=26, rx=32)
uart2.init(baudrate=115200, bits=8, parity=None, stop=1, txbuf=256, rxbuf=256)
modem = ASR6501(uart2, '...', '...', '...')  # DevEUI, AppEUI, AppKey as hex codes
count = 0

def modem_state_changed():
    return modem.has_state_changed()

def start_join():
    yellow()
    modem.send_join()
    tasks.when_then(modem_state_changed, end_join)
    
def end_join():
    state = modem.get_state()
    if state == JOINING:
        tasks.when_then(modem_state_changed, end_join)
    elif state == JOINED:
        green()
        tasks.after(10000, start_send)
    elif state == NOT_JOINED:
        tasks.after(60000, start_join)
    else:
        raise NotImplementedError()
    
def start_send():
    global count
    count += 1
    blue()
    modem.send_message(bytes(str(count), 'ASCII'), count % 29 == 1)  # message, confirmed
    tasks.when_then(modem_state_changed, end_send)

def end_send():
    state = modem.get_state()
    if state == SENDING:
        tasks.only_one_of(tasks.when_then(modem_state_changed, end_send), tasks.after(60000, assume_sent))  # workaround for AT+DTRX response lines
    elif state == SENT:
        magenta()
        tasks.after(300000, start_send)
    elif state == RETRY:
        red()
        tasks.after(300000, start_send)
    elif state == NOT_JOINED:
        red()
        tasks.after(300000, start_join)
    else:
        raise NotImplementedError()

def assume_sent():
    magenta()
    tasks.after(240000, start_send)


from machine import Pin
from neopixel import NeoPixel

gpio27 = Pin(27, Pin.OUT)
neopixels = NeoPixel(gpio27, 1)

def yellow():
    neopixels[0] = (20, 20, 0)
    neopixels.write()

def green():
    neopixels[0] = (0, 25, 0)
    neopixels.write()

def blue():
    neopixels[0] = (0, 0, 25)
    neopixels.write()

def magenta():
    neopixels[0] = (20, 0, 20)
    neopixels.write()

def red():
    neopixels[0] = (25, 0, 0)
    neopixels.write()


tasks.now(start_join)

while tasks.available():
    tasks.run()
    

Credits

Andreas Motzek

Andreas Motzek

16 projects • 9 followers
I like algorithms, code, statistics and decisions based on them, solving difficult problems and, if possible, avoiding them elegantly.

Comments