<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[atom lite lorawan network connectivity issue]]></title><description><![CDATA[<p dir="auto">Hi<br />
i am trying to connect atom lite and lorawan 915 lorawan module (via UART PORT TO UART POT OF ATOM LITE) to lorawan network and not having much luck. here is the code.</p>
<p dir="auto">from machine import UART<br />
import time<br />
import ubinascii</p>
<h1>LoRaWAN credentials</h1>
<p dir="auto">DEV_EUI = "XXXXXXXXXX"<br />
APP_EUI = "9F8E71DD3AFE41XX"<br />
APP_KEY = "b4b5c65a175d5f441ee85686b1253XXX"</p>
<h1>UART configuration (G26, G32; change to G19, G22 if needed)</h1>
<p dir="auto">uart = UART(2, baudrate=115200, tx=26, rx=32, bits=8, parity=None, stop=1, txbuf=256, rxbuf=256)</p>
<h1>State constants</h1>
<p dir="auto">NOT_JOINED = "NOT_JOINED"<br />
JOINING = "JOINING"<br />
JOINED = "JOINED"<br />
SENDING = "SENDING"<br />
SENT = "SENT"<br />
RETRY = "RETRY"</p>
<h1>Simple cooperative scheduler</h1>
<p dir="auto">class Tasks:<br />
def <strong>init</strong>(self):<br />
self.tasks = []</p>
<pre><code>def now(self, func):
    self.tasks.append((func, 0, False))

def after(self, delay_ms, func):
    self.tasks.append((func, time.ticks_add(time.ticks_ms(), delay_ms), False))

def when_then(self, condition_func, then_func):
    self.tasks.append((then_func, 0, condition_func))

def only_one_of(self, task1, task2):
    self.tasks.append(task1)
    self.tasks.append(task2)
    self.tasks[-2] = (task1[0], task1[1], lambda: task1[2]() and not task2[2]())
    self.tasks[-1] = (task2[0], task2[1], lambda: task2[2]() and not task1[2]())

def available(self):
    return len(self.tasks) &gt; 0

def run(self):
    if not self.tasks:
        return
    current_time = time.ticks_ms()
    for i, (func, trigger_time, condition) in enumerate(self.tasks[:]):
        if condition:
            if condition():
                self.tasks.pop(i)
                func()
                break
        elif trigger_time == 0 or time.ticks_diff(current_time, trigger_time) &gt;= 0:
            self.tasks.pop(i)
            func()
            break
    time.sleep_ms(10)
</code></pre>
<h1>Modem state management</h1>
<p dir="auto">class Modem:<br />
def <strong>init</strong>(self, uart):<br />
self.uart = uart<br />
self.state = NOT_JOINED<br />
self.state_changed = False</p>
<pre><code>def send_at_command(self, cmd, timeout=1000):
    print(f"Sending: {cmd}")
    self.uart.write(cmd + "\r\n")
    time.sleep_ms(timeout)
    response = ""
    while self.uart.any():
        response += self.uart.read().decode()
    print(f"Response: {response}")
    return response

def send_join(self):
    self.state = JOINING
    self.state_changed = True
    self.send_at_command("ATZ", 2000)
    self.send_at_command("AT+BAND=5", 1000)  # US915
    self.send_at_command(f"AT+DEVEUI={DEV_EUI}", 1000)
    self.send_at_command(f"AT+APPEUI={APP_EUI}", 1000)
    self.send_at_command(f"AT+APPKEY={APP_KEY}", 1000)
    self.send_at_command("AT+NJM=1", 1000)  # OTAA
    self.send_at_command("AT+CLASS=C", 1000)
    self.send_at_command("AT+MASK=0002", 1000)  # Channels 8-15
    response = self.send_at_command("AT+JOIN=1:0:10:8", 10000)
    if "OK Join Success" in response:
        self.state = JOINED
    else:
        self.state = NOT_JOINED
    return response

def send_message(self, data, confirmed=False):
    self.state = SENDING
    self.state_changed = True
    hex_data = ubinascii.hexlify(data).decode()
    self.send_at_command(f"AT+PORT=2", 1000)
    cmd = f"AT+SEND={hex_data}" if not confirmed else f"AT+CSEND={hex_data}"
    response = self.send_at_command(cmd, 5000)
    if "OK" in response:
        self.state = SENT
    else:
        self.state = RETRY
    return response

def has_state_changed(self):
    changed = self.state_changed
    self.state_changed = False
    return changed

def get_state(self):
    return self.state
</code></pre>
<h1>Initialize modem and tasks</h1>
<p dir="auto">modem = Modem(uart)<br />
tasks = Tasks()<br />
count = 0</p>
<h1>Modem state check</h1>
<p dir="auto">def modem_state_changed():<br />
try:<br />
return modem.has_state_changed()<br />
except Exception as e:<br />
print(f"Modem state error: {e}")<br />
return False</p>
<h1>Join network</h1>
<p dir="auto">def start_join():<br />
print("Joining TTN...")<br />
try:<br />
modem.send_join()<br />
tasks.when_then(modem_state_changed, end_join)<br />
except Exception as e:<br />
print(f"Join error: {e}")<br />
tasks.after(60000, start_join)</p>
<p dir="auto">def end_join():<br />
try:<br />
state = modem.get_state()<br />
if state == JOINING:<br />
tasks.when_then(modem_state_changed, end_join)<br />
elif state == JOINED:<br />
print("Joined TTN!")<br />
tasks.after(10000, start_send)<br />
elif state == NOT_JOINED:<br />
print("Join failed.")<br />
tasks.after(60000, start_join)<br />
else:<br />
raise NotImplementedError(f"Unknown state: {state}")<br />
except Exception as e:<br />
print(f"End join error: {e}")<br />
tasks.after(60000, start_join)</p>
<h1>Send data</h1>
<p dir="auto">def start_send():<br />
global count<br />
count += 1<br />
print(f"Sending data: {count}")<br />
try:<br />
modem.send_message(bytes(str(count), 'ASCII'), count % 29 == 1)<br />
tasks.when_then(modem_state_changed, end_send)<br />
except Exception as e:<br />
print(f"Send error: {e}")<br />
tasks.after(300000, start_send)</p>
<p dir="auto">def end_send():<br />
try:<br />
state = modem.get_state()<br />
if state == SENDING:<br />
tasks.only_one_of(<br />
(end_send, 0, modem_state_changed),<br />
(assume_sent, time.ticks_add(time.ticks_ms(), 60000), lambda: True)<br />
)<br />
elif state == SENT:<br />
print("Data sent!")<br />
tasks.after(300000, start_send)<br />
elif state == RETRY:<br />
print("Send failed.")<br />
tasks.after(300000, start_send)<br />
elif state == NOT_JOINED:<br />
print("Not joined.")<br />
tasks.after(300000, start_join)<br />
else:<br />
raise NotImplementedError(f"Unknown state: {state}")<br />
except Exception as e:<br />
print(f"End send error: {e}")<br />
tasks.after(300000, start_send)</p>
<p dir="auto">def assume_sent():<br />
print("Assumed data sent.")<br />
tasks.after(240000, start_send)</p>
<h1>Start the process</h1>
<p dir="auto">try:<br />
tasks.now(start_join)<br />
while tasks.available():<br />
tasks.run()<br />
except Exception as e:<br />
print(f"Main loop error: {e}")<br />
time.sleep(10)<br />
machine.reset()</p>
]]></description><link>https://community.m5stack.com/topic/7512/atom-lite-lorawan-network-connectivity-issue</link><generator>RSS for Node</generator><lastBuildDate>Wed, 29 Apr 2026 22:36:59 GMT</lastBuildDate><atom:link href="https://community.m5stack.com/topic/7512.rss" rel="self" type="application/rss+xml"/><pubDate>Mon, 21 Apr 2025 21:11:04 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to atom lite lorawan network connectivity issue on Mon, 21 Apr 2025 21:21:23 GMT]]></title><description><![CDATA[<p dir="auto">Version: RUI_4.0.6_RAK3172-E<br />
Current Work Mode: LoRa P2P.</p>
<p dir="auto">Sending: AT+BAND=5<br />
Response: AT_MODE_NO_SUPPORT</p>
<p dir="auto">Sending: AT+DEVEUI=AC1F09FFFE16EE10<br />
Response: AT_MODE_NO_SUPPORT</p>
<p dir="auto">Sending: AT+APPEUI=9F8E71DD3AFE41B2<br />
Response: AT_MODE_NO_SUPPORT</p>
<p dir="auto">Sending: AT+APPKEY=b4b5c65a175d5f441ee85686b12534a8<br />
Response: AT_MODE_NO_SUPPORT</p>
<p dir="auto">Sending: AT+NJM=1<br />
Response: AT_MODE_NO_SUPPORT</p>
<p dir="auto">Sending: AT+CLASS=C<br />
Response: AT_MODE_NO_SUPPORT</p>
<p dir="auto">Sending: AT+MASK=0002<br />
Response: AT_MODE_NO_SUPPORT</p>
<p dir="auto">Sending: AT+JOIN=1:0:10:8<br />
Response: AT_MODE_NO_SUPPORT</p>
<h2>Join failed.<br />
E (100362) i2c: i2c driver install error<br />
E (100364) time: The current date/time in Shanghai is: Mon Apr 21 21:19:27 2025<br />
E (100367) wifi:NAN WiFi stop<br />
E (100368) transport_base: poll_read select error 113, errno = Software caused connection abort, fd = 54<br />
E (100376) mqtt_client: Poll read error: 119, aborting connection<br />
[INFO] Syncing resources...<br />
[INFO] WiFi connected!<br />
Joining TTN...<br />
Sending: ATZ<br />
Response:<br />
RAKwireless RAK3172</h2>
<p dir="auto">Version: RUI_4.0.6_RAK3172-E<br />
Current Work Mode: LoRa P2P.</p>
<p dir="auto">Sending: AT+BAND=5<br />
Response: AT_MODE_NO_SUPPORT</p>
<p dir="auto">Sending: AT+DEVEUI=AC1F09FFFE16EE10<br />
Response: AT_MODE_NO_SUPPORT</p>
<p dir="auto">Sending: AT+APPEUI=9F8E71DD3AFE41B2<br />
Response: AT_MODE_NO_SUPPORT</p>
<p dir="auto">Sending: AT+APPKEY=b4b5c65a175d5f441ee85686b12534a8<br />
Response: AT_MODE_NO_SUPPORT</p>
<p dir="auto">Sending: AT+NJM=1<br />
Response: AT_MODE_NO_SUPPORT</p>
<p dir="auto">Sending: AT+CLASS=C<br />
Response: AT_MODE_NO_SUPPORT</p>
<p dir="auto">Sending: AT+MASK=0002<br />
Response: AT_MODE_NO_SUPPORT</p>
<p dir="auto">Sending: AT+JOIN=1:0:10:8<br />
Response: AT_MODE_NO_SUPPORT</p>
<p dir="auto">Join failed.</p>
]]></description><link>https://community.m5stack.com/post/28938</link><guid isPermaLink="true">https://community.m5stack.com/post/28938</guid><dc:creator><![CDATA[aiconnection]]></dc:creator><pubDate>Mon, 21 Apr 2025 21:21:23 GMT</pubDate></item></channel></rss>