LoRaWAN-Kommunikation mit dem LR1262 Dev.-Board (RP2040) und einem Multi-Channel Gateway über OTAA
Ich hatte ja ein paar Probleme bei meinen letzten Experimenten mit LoRaWAN und einem günstigen Single-Channel-LoRaWAN-Gateway und der Übertragung zum The Things Networt, wie ihr hier in diesem Artikel nachlesen könnt.Dort hatte ich eine LoRaWAN-Nachricht von meinem Elecrow LoRaWAN LR1262 Dev.-Board mit Raspi-Pico 2040 (siehe Vorstellungsartikel dazu hier) über mein Elecrow ESP32 Basic Single-Channel LoRaWAN-Gateway (siehe Vorstellungsartikel dazu hier) abgesetzt.
Da traf ich auf ein Problem und eine Fehlannahme:
Die Fehlannahme

Ich hatte mein neues Elecrow ESP32 Basic Single-Channel LoRaWAN-Gateway natürlich gleich mit meinem LilyGo TTGO T3 PAX-Counter ausprobiert.
Das Teil meldet sich beim nächsten LoRaWAN-Gateway an und überträgt dann die Anzahl der Personen in der Nähe, die es anhand von Bluetooth und WLAN-Geräten ausmacht. Die LoRaWAN-Kommunikation erledigt es mit einer "Join"-Verbindung (korrekt eigentlich OTAA – Over-The-Air Activation, zur Begriffserklärung siehe auch mein Artikel LoRaWAN-Kommunikation mit dem LR1262 Dev.-Board (RP2040) und einem Single-Channel Gateway).
Da mein PAX-Counter keine Join-Verbindung mit meinem Single-Channel-LoRaWAN-Gateway aufbauen wollte, ging ich davon aus, dass das Single-Gateway kein OTAA unterstützt. Also habe ich mich damit erst gar nicht weiter beschäfigt, da ich annahm, dass man für OTAA ein Multi-Channel-Gateway benötigt. Was nicht ganz richtig ist, wie ich jetzt herausgefunden habe - dazu später mehr. Das war meine Fehlannahme.
Aufgrund dieser Annahme habe ich mich mit der Ad-hoc-Verbindung (ABP – Activation By Personalization Modus) beschäftigt und bekam damit auch eine Verbindung - allerdings...
Das Problem mit dem LR1262 LoRa SoC

Allerdings scheint es so, dass irgendetwas mit meinem LR1262 SoC auf meinem Elecrow Lora Development Board nicht stimmt. Es unterstützt aus irgendeinem Grund den Befehl AT+SAVE nicht richtig und speichert nicht, wenn man ihn ausführt. Es wird zwar OK zurückgegeben, doch hat das keine Auswirkungen. Neu gesetzte IDs sind nach einem Reset weg und selbst während der Laufzeit funktioniert AT+SAVE nicht bei Frame-Counter.
Denn es ist nötig, dass ein Zähler namens "FCnt" (kurz für Frame-Counter) herauf gezählt wird, um die einzelnen LoRa-Nachrichten zu unterscheiden. Jede neue LoRa-Nachricht braucht eine Nummer, die größer ist als die letzte, sonst wird die Nachricht einfach vom TTN verworfen. AT+SAVE sollte die Nachrichtennummer speichern und erhöhen, tut es aber nicht. So ist FCnt immer Null (FCnt=0).
So kommt es, dass nur die erste Nachricht eines Tages vom TTN entgegengenommen wird und der Rest im Müll landet - ohne weitere Meldung - happy Debugging!
Es gibt zwar ein Einstellung, dass FCnt im ABP-Modus auf TTN ignoriert werden soll, aber auch das funktioniert nicht zuverlässig, wahrscheinlich, weil FCnt immer gleich Null ist und sich überhaupt nicht verändert. Auch kann man FCnt nicht einfach selbst hochzählen und dann dem LR1262 vai AT-Command mitteilen. FCnt ist nämlich Teil der Nachricht und wird mit dem ganzen Rest verschlüsselt zu der LoRa-Message, die dann gefunkt wird. Das Verschlüsseln macht der LoRa-Chip und das geht automatisch. FCnt sollte vom LoRa-Chip verwaltet und automatisch erhöht werden. Tut er aber nicht. Man hat als Entwickler kein Zugriff darauf. Dumm gelaufen.
Mein Single-Channel-LoRaWAN-Gateway habe ich dann nicht mehr so richtig angeschaut. Irgendwann war es dann auch irgendwann im TTN verschwunden, obwohl ich es Tag und Nacht habe durchlaufen lassen. Auch ein Reset brachte das Gateway nicht mehr in TTN zurück. Es wurde immer "offline" angezeigt. Ich habe es dann ganz vom Strom genommen. Irgendwann wollte ich doch noch einmal was nachschauen und habe es nach Tagen wieder ans Stromnetz gehängt und komischerweise war es dann wieder im TTN online. Das TTN war mir schon immer ein wenig suspekt und dieser seltsame Effekt ließ mein Vertrauen ins TTN doch noch ein wenig mehr schwinden. Ein Reset oder ein kurzes vom Netz nehmen sollte doch den selben Effekt habe als ein tagelanges vom Netz nehmen, oder?
Irgendwann habe ich dann bemerkt, dass MultiChannel-Gateways nicht mehr so super teuer sind und nunmehr für rund 100 Euro zu haben sind. Also eines besorgt. Mit einem Multi-Channel-Gateway sollte es ja dann keine Probleme mehr geben, oder?
Stolzer Besitzer eines MultiChannel-Gateways

Ein MultiChannel-Gateway ist eigentlich ein LoRaWAN-Gateway, wie es angedacht ist. Ein Single-Channel-Gateway ist eher ein Trick, bei dem keine richtige (aber dafür günstige) Gateway-Hardware benutzt wird, sondern die von der Client-Seite, also die, die man in Sensoren verbaut.
Nachdem ich mir mein neues 8-Channel-LoRaWAN-Gateway M2 von Seeed Studio näher angeschaut (hier mein Hardware-Review zum M2) und es installiert und mit dem Starter-Kit-Sensor in der Seeed-LoRa-Cloud einem ersten Test unterzogen hatte, wollte ich natürlich auch meinen PAX-Counter ausprobieren - damit hatte ja alles angefangen.
Dazu musste ich das Seeed 8-Channel-LoRaWAN-Gateway M2 auf TTN umkonfigurieren, denn der PAX-Counter war ja von LilyGo/TTGO und nicht von Seeed ist deswegen nicht mit der Seeed Cloud kompatibel.
Aber dann funktionierte gleich der erste Test mit dem PAX-Counter. Der Join war innerhalb von Sekunden erledigt (hier ein kurzes YouTube-Demo-Video dazu) und umgehend landeten die PAX-Daten auch in meinem e-mail-Postfach.
Damit fühlte ich mich bestätigt in der Meinung, dass frei nach dem Motto "wer billig kauft, kauft zweimal" es dann letztendlich ein MultiChannel-Gateway sein muss. Beweisführung mit dem PaxCounter: SingleChannel = keine Verbindung, warten bis zum Sankt Nimmerleinstag; MultiChannel = sofortige Verbindung, alles klappt sofort. Das es dann doch ein klein wenig anders ist, sollte ich erst später herausfinden.
Elecrow LR1262 Dev Board und OTAA

Zeit, mein Elecrow LoRa Dev.-Board wieder raus zu kramen und da weiter zu programmieren. Nach dem ABP Modus wollte ich jetzt natürlich auch den OTAA-Modus ausprobieren. Würde das LR1262 hier auch so Schwierigkeiten machen?
Wollen wir noch mal kurz den Unterschied zwischen ABP und OTAA-Modus, den ich hier genauer erklärt habe, zusammenfassen - im Hinblick auf TTN:
Der ABP-Modus ("Ad-hoc") ist zustandslos, ähnlich wie UDP im Internet. Eine Nachricht wird einfach hinausgeblasen und es wird darauf gehofft, dass ein oder mehrere Gateways diese empfangen und ans TTN weiterleiten.
Der OTAA-Modus ("Join") hat eine Verbindung, ähnlich wie TCP im Internet. Der Client (Sensor) sucht sich ein Gateway und verbindet sich mit ihm ("joined" ihn, es wird eine "Session" erstellt). Gateway und Client kennen sich nun und das Gateway kann Nachrichteneingänge auch bestätigen ("confirm").
Der Client bleibt bei seinem Gateway und die Session kann monate- oder jahrelang aufrecht erhalten bleiben. Sie "stirbt" nicht, sondern wird beim nächsten Senden einer Nachricht weiterverwendet.
Beiden Modi ist gemein, dass sie einen inkrementierenden Frame-Counter brauchen, um die Einzel-Nachrichten auseinanderzuhalten. Bei OTAA fängt jeder Session wieder bei Null an. Bei ABP checkt das TTN, ob der FCnt größer ist als der zuletzt verwendete (gleich neue Nachricht). Eine Nachricht kann nämlich auch bei mehreren Gateway ankommen und weitergeleitet werden - das sehen wir gleich.
Die OTTAA-Routinen für mein RP2040-LoRa-Development-Board sind schnell geschrieben, denn ich kann viel Code wiederverwenden bzw. habe den bereits in Funktionen gekapselt. Im Prinzip muss ich mich nur an den Beispiel-Code auf der Elecrow-Seite halten und die richtigen AT-Commands zum LR1262 schicken:
AT+RESET
Komischerweise gibt es hier manchmal die Rückgabe AT_ERROR. Ich weiß zwar nicht, was bei einem Reset falsch gehen kann, aber es zeigt: Jede Rückgabe sollte auf Plausibilität überprüft werden.
AT+AppEui=0102030405060708
Bei TTN auch JoinEUI genannt. Wird als neues End Device unter Application im TTN angelegt und identifiziert den Sensor.
AT+ChannelMode=1
Multi-Channel Mode benutzen
AT+BAND=5
Die 5 steht für EU, 868 MHz, ist aber schon richtig im LR1262 gespeichert, also eigentlich nicht nötig
AT+JOIN=1,8
Die 1 steht für OTAA und die 8 ist die Anzahl der Versuche, eine Verbindung aufzubauen. Maximum ist 8. Ein Join auszuhandeln, dauert ein paar Sekunden. Das abwarten und dann erst Nutzdaten senden.
AT+SEND=1:1:313233
Die erste 1 steht für den Port. Hier keine 0 eingeben. Port 1 ist gut. Die zweite 1 ist der Confirmed-Mode. Wollen wir eine Bestätigung des Join? Klar, wollen wir, also 1. Dann folgen die Nutzdaten, hexadezimal kodiert, hier "313233" für den Text "123".

Für den nächsten Send brauchen wir keinen neuen Join mehr. Wir können jetzt regelmäßig etwas über diesen Kanal senden und bekommen auch immer mitgeteilt, dass die Nachricht entgegengenommen wurde.
Für den Fall, dass die Session irgendwann doch abreißt und alle Sends fehlschlagen, braucht es dann einen neuen Join. Am einfachsten ist es, die Firmware des Sensors einfach zu resetten, vielleicht hängt ja irgendwas im Code, weil der Speicher durch eine Fehlprogrammierung vollgelaufen ist. Ein Reset beseitigt ohne großen Aufwand eigentlich alle Probleme.
Ich habe mir als Demo mal meinen AHT20-Sensor hergenommen, der über Grove bzw. Crowtail am Dev.-Board angeschlossen ist. Der wird in Schleife alle 6 Sekunden ausgelesen und die Werte angezeigt und alle 60 Sekunden werden die Werte ans TTN über LoRaWAN übertragen.
Das funktioniert jetzt schon stundenlang zuverlässig.
Die TTN-Seite
Natürlich muss eine neue Application und ein neues End-Device auf TTN angelegt werden, damit TTN auch weiß, dass es für diesen Sensor zuständig sein soll:
Rechts im Bild sehen wir schon die dekodierten Nutzdaten: "text": "temp=23.14 humi=40.38"
Zuvor kommt das Paket aber bei meinem MultiChannel-Gateway an. Hier ein Auszug auf dem LoRa-Logfile:
Thu Jan 22 12:25:30 2026 daemon.info lora_pkt_fwd[11196]: INFO: [up] payload (34 bytes): 80FC5C0B26002C1001F686FA7064AE1CB196CB6245D4588248DCD21B5E0413B9F2D4
Es ist alles verschlüsselt. Das LoRaWAN-Gateway sieht nur die 34 Bytes an verschlüsselten Daten, mit denen niemand etwas anfangen kann, der nicht den Schlüssel hat. Denen kennen nur der Client, also der LR1262-SoC bzw. wenn ich ihn durch meine Sensor-Firmware anderweitig setze dann steht er da drin. Bei super sensiblen Daten sollte man den vielleicht nicht im Klartext in der Firmware drinstehen haben. Aber natürlich kann man den Schlüssel auch aus dem LR1262-SoC auslesen.. wer also den Sensor klaut, kommt auch an den Schlüssel, aber das ist jetzt nicht das Thema.Mein MultiChannel-Gateway "cool-8ch-zdf2" leitet die Daten dann über WLAN und Internet zum TTN, wo wir mal in die Live Data spicken wollen:

An der Device-Address 0x260b5cfc sehen wir schon, dass es sich hier um unseren AHT-20-Sensor handelt. Bei einem AT+RESET bekommen wir ja die LR1262-Daten angezeigt, auch diese Geräte-Adresse. Wir könnten hier jetzt auch auf eine Zeile klicken, um uns alle Einzeldaten anzuschauen, aber das heben wir uns für später auf. Die Daten bekomme ich ja eh noch in mein Postfach.
Jetzt die Überraschung: mein Single-Channel-Gateway "cool-1ch-zdf1" hat eine LoRa Message um 13:25:30 entgegengenommen und weitergeleitet:

Wie das? Bisher dachte ich doch, dass das Single-Channel-Gateway nur ABP kann und auf OTAA nicht reagiert. Das hatte doch der PAX-Counter bewiesen, oder nicht?
Da habe ich mich wohl getäuscht. Scheinbar geht es doch. Der Join und das eigentliche übertragen hat funktioniert. Also wenn man es selbst programmiert und den Elecrow LR1262 benutzt. Ich könnte jetzt noch ewig weiterforschen und herausfinden, woran es liegt, dass der PAX-Counter kein Join schafft bzw. warum der selbstprogrammierte LR1262 ein Join schafft. Aber eigentlich kann mir das egal sein, da ich ja jetzt ein MultiChannel-Gateway habe, das alles kann. Aber ich werde mal ein Auge nebenbei darauf haben und euch über etwaige neue Erkenntnisse informieren.
Daten auf dem eigenen Webserver
Dank Webhook auf TTN wird jede Nachricht an meinen eigenen Webserver weitergeleitet. Zur Entwicklungszwecken schicke ich mir den komplette XML-Datensatz an meine e-mail-Adresse. So sieht das dann aus:Array
(
[end_device_ids] => Array
(
[device_id] => lr1262-1-otaa
[application_ids] => Array
(
[application_id] => lora1262-dev
)
[dev_eui] => 0080E1150504A03F
[join_eui] => C001A99171262001
[dev_addr] => 260B5CFC
)
[correlation_ids] => Array
(
[0] => gs:uplink:01KFJQCGVSH2G4DXVTE9YCY65D
)
[received_at] => 2026-01-22T11:28:11.846478330Z
[uplink_message] => Array
(
[session_key_id] => AZvlSY/7RxgAwN6UVUzJdQ==
[f_port] => 1
[f_cnt] => 25
[frm_payload] => dGVtcD0yMy4xNSBodW1pPTM4Ljgz
[decoded_payload] => Array
(
[text] => temp=23.15 humi=38.83
)
[rx_metadata] => Array
(
[0] => Array
(
[gateway_ids] => Array
(
[gateway_id] => cool-8ch-zdf2
[eui] => C0016A7E00000002
)
[timestamp] => 3688073629
[rssi] => -54
[channel_rssi] => -54
[snr] => 10.8
[frequency_offset] => 102
[location] => Array
(
[latitude] => 49.450666
[longitude] => 10.948666
[altitude] => 343
[source] => SOURCE_REGISTRY
)
[uplink_token] => ChsKGQoNY29vbC04Y2gtemRmMhIIwAFqfgAAAAIQnZPO3g0aDAjLk8jLBhDxuKCxAiDImsaSq7IT
[received_at] => 2026-01-22T11:28:11.640162929Z
)
[1] => Array
(
[gateway_ids] => Array
(
[gateway_id] => eui-c0016a7e00000001
[eui] => C0016A7E00000001
)
[timestamp] => 59450535
[rssi] => -60
[channel_rssi] => -60
[snr] => 11
[location] => Array
(
[latitude] => 49.450666
[longitude] => 10.948666
[altitude] => 343
[source] => SOURCE_REGISTRY
)
[uplink_token] => CiIKIAoUZXVpLWMwMDE2YTdlMDAwMDAwMDESCMABan4AAAABEKfJrBwaDAjLk8jLBhDCmezFAiDY2Jy83dQO
[received_at] => 2026-01-22T11:28:11.683347138Z
)
)
[settings] => Array
(
[data_rate] => Array
(
[lora] => Array
(
[bandwidth] => 125000
[spreading_factor] => 12
[coding_rate] => 4/5
)
)
[frequency] => 868100000
[timestamp] => 3688073629
)
[received_at] => 2026-01-22T11:28:11.641975823Z
[confirmed] => 1
[consumed_airtime] => 1.810432s
[network_ids] => Array
(
[net_id] => 000013
[ns_id] => EC656E0000000181
[tenant_id] => ttn
[cluster_id] => eu1
[cluster_address] => eu1.cloud.thethings.network
)
[last_battery_percentage] => Array
(
[value] => 100
[received_at] => 2026-01-22T07:59:41.405710787Z
)
)
)Ich könnte meinen Web-Server jetzt natürlich so umprogrammieren, dass er die Nachricht nicht per e-mail weiterleitet, sondern die Daten nur verifiziert und wenn sie gültig sind, platzsparend in eine Datenbank schreibt. Und daraus kann man dann wieder die allerschönsten Charts und Verlaufsdiagramme für die Webpage basteln.
Videos
Das nachfolgende kleine Video zeigt die Übertragung von Sensordaten (AHT20) über das Elecrow LR1262 und das Seeed M2 MultiChannel-Gateway:Und in diesem kurzen Video zeige ich die Zusammenarbeit des LilyGo TTGO PAX-Counters mit dem Seeed M2 MultiChannel-Gateway:
Und in diesem Video demonstriere ich die Zusammenarbeit von LoRaWAN-Node, Gateway und The Things Network mit dem Single-Channel-LoRaWAN-Gateway:
Weiterlesen...
Als nächstes will ich auch versuchen, den Sensor aus dem Seeed Starter Kit mit TTN zusammen laufen zu lassen. Wenn ich das geschafft habe, werde ich den Artikel dann hier verlinken.Bis dahin sind bestimmt die in diesem Artikel verlinkten Artikel sehr lesenswert - im Grund muss man sie als Grundlage gelesen haben.
Quellen, Literaturverweise und weiterführende Links
- Wikipedia: LoRa / LoRaWAN
- The Things Network

- LoRaWAN-Kommunikation mit dem LR1262 Dev.-Board (RP2040) und einem Single-Channel Gateway
- Vorstellung des Elecrow LoRaWAN LR1262 Dev.-Board mit Raspi-Pico 2040
- Elecrow ESP32 Basic LoRaWAN-Gateway und The Things Network: Firmware und Konfiguration
- 8-Channel-LoRaWAN-Gateway M2 von Seeed Studio Hardware-Review
- Installation des 8-Channel-LoRaWAN-Gateway M2 Starter Kit von Seeed Studio
- Seeed 8-Channel-LoRaWAN-Gateway M2 auf TTN konfigurieren
- The Things Network Konfiguration: Mit Webhooks Messages an den eigenen Webserver weiterleiten
- Sensor Bosch BME680 als Thermometer, Hygrometer und VOC-Meter nutzen und über den I2C-Bus auslesen
- Den Sensor AHT20 als Thermometer und Hygrometer (Luftfeuchtigkeit) nutzen und über den I2C-Bus auslesen
- IC2-Sensoren am Elecrow LoRaWAN LR1262 Dev.-Board mit Raspi-Pico 2040
- Libraries und Software für das Elecrow LoRaWAN LR1262 Dev.-Board mit Raspi-Pico 2040
- Elecrow LoRaWAN LR1262 Development Board mit RP2040 und TFT, LoRa 868 MHz

- Elecrow ESP32 Basic Single-Channel LoRaWAN-Gateway

- Elecrow: LR1262 LoRaWAN AT Command Description

- Seeed SenseCAP M2 8-Channel LoRaWAN-Gateway

- Seeed SenseCAP M2 Starter Kit (lohnt sich preislich)
