In diesem Beitrag zeige ich dir, wie du mit einem TTGo LoRa ESP32 Board Datenpakete für TTN-Payload an das The Things Network (TTN) erstellst und dort wieder decodierst. Du lernst, wie du eine Payload effizient codierst und Daten wie Ganzzahlen, Fließkommazahlen und Strings über LoRaWAN überträgst. Außerdem schauen wir uns die Codierung auf Bit-Ebene an, sodass du verstehst, wie Bitshifting funktioniert. Am Ende erfährst du, wie du auf der TTN-Seite ein Decoding-Skript schreibst, um die Daten korrekt darzustellen.
1. Grundlagen der Payload-Erstellung
1.1 Was ist eine Payload?
Die Payload ist die Nutzlast eines Datenpakets, also der eigentliche Inhalt, der übertragen wird. Im TTN-Kontext umfasst dies z. B. Sensordaten wie Temperatur, Luftfeuchtigkeit, GPS-Koordinaten oder Statusmeldungen.
Beispiel:
- Temperatur: 25,57°C
- Luftfeuchtigkeit: 65 %
Die Payload könnte so codiert werden:
- Temperatur: 25,57 → 0x09 FD (2 Bytes als Integer 2557)
- Luftfeuchtigkeit: 65 → 0x41 (1 Byte)
- Gesamt-Payload: 09 FD 41 (3 Bytes)
1.2 Warum binäre Codierung?
1.2.1 Platzersparnis
Binäre Codierung stellt Daten kompakt dar. Im Vergleich zu Text-Formaten (z. B. JSON) spart binäre Codierung Speicherplatz.
Beispiel:
- Als Text: „25.57“ → 5 Bytes
- Binär codiert: 2557 → 2 Bytes
1.2.2 Effiziente Verarbeitung
Binär codierte Daten können von Mikrocontrollern direkt verarbeitet werden. Es sind keine Umwandlungen notwendig, was Rechenzeit spart.
uint16_t value = 2557; payload[0] = (value >> 8) & 0xFF; // High Byte payload[1] = value & 0xFF; // Low Byte
1.2.3 Vereinfachte Decodierung
Binär codierte Daten haben eine feste Struktur, die auf TTN einfach interpretiert werden kann.
var intValue = (bytes[0] << 8) | bytes[1]; // High Byte und Low Byte kombinieren
1.2.4 Mehrere Werte in einer Payload
Binär codierte Daten ermöglichen die Übertragung mehrerer Werte in einer kleinen Payload.
Beispiel:
- Temperatur (2 Bytes): 09 FD
- Luftfeuchtigkeit (1 Byte): 41
- Gesamt: 3 Bytes
Als Text würde dieselbe Payload mindestens 12 Bytes benötigen.
1.3 Anforderungen an Payloads für TTN
- Die Größe der Payload ist im LoRaWAN-Protokoll strikt begrenzt und hängt von der Datenrate (Spreading Factor, SF) ab. TTN hat dabei folgende Anforderungen:
- Für das europäische 863-870-MHz-Band variiert die maximale Anwendungspaketgröße :
- 51 Bytes für die langsamsten Datenraten, SF10, SF11 und SF12 auf 125 kHz
- 115 Bytes für SF9 auf 125 kHz
- 222 Bytes für schnellere Raten, SF7 und SF8 auf 125 kHz (und SF7 auf 250 kHz)
- Beachte bitte, dass das LoRaWAN-Protokoll mindestens 13 Bytes hinzufügt zur Anwendungsnutzlast.
- Einige Bibliotheken, wie LMiC, unterstützten nur 51 Bytes für alle Datenraten.
2. Implementierung der Payload-Erstellung
2.1 Payload-Logik: Wann welchen Datentyp verwenden?
Datentyp | Verwendung | Speicherbedarf |
---|---|---|
Byte | Statusmeldungen, Flags | 1 Byte |
Integer | Sensordaten, IDs | 2–4 Bytes |
Float | Präzise Werte (z. B. Temperatur) | 4 Bytes |
String | Textnachrichten (ineffizient) | 1 Byte/Zeichen |
2.2 Schritt-für-Schritt: Codierung einer Payload in Arduino/C++
Im Folgenden ein Beispiel für eine Payload, die Temperatur, Luftfeuchtigkeit und einen Statuswert enthält:
#include <Arduino.h> uint8_t payload[7]; // Payload-Array (7 Bytes) void setup() { Serial.begin(115200); // Sensordaten float temperature = 23.45; // Temperatur in °C uint16_t humidity = 655; // Luftfeuchtigkeit * 10 (z. B. 65,5 %) uint8_t status = 1; // Statusmeldung (z. B. 1 = OK) // Temperatur codieren (Float, 4 Bytes) memcpy(&payload[0], &temperature, sizeof(float)); // Luftfeuchtigkeit codieren (Integer, 2 Bytes) payload[4] = (humidity >> 8) & 0xFF; // High Byte payload[5] = humidity & 0xFF; // Low Byte // Status codieren (1 Byte) payload[6] = status; // Debugging der Payload Serial.print("Encoded Payload: "); for (int i = 0; i < sizeof(payload); i++) { Serial.print(payload[i], HEX); Serial.print(" "); } Serial.println(); } void loop() {}
Ergebnis (Payload in HEX):
- Temperatur: 41 BB 2D 5C (4 Bytes)
- Luftfeuchtigkeit: 02 8F (2 Bytes)
- Status: 01 (1 Byte)
- Gesamt-Payload: 41 BB 2D 5C 02 8F 01
Hier kann noch um 2 Bytes reduziert werden, wenn die Temperatur mit 100 multipliziert wird, kann ein Integer in nur 2 Bytes übertragen werden. Siehe Beispiel unter 2.2.
2.3 Decoding der Payload auf TTN
Ein Beispiel für ein Decoding-Skript in der TTN-Konsole (JavaScript):
function Decoder(bytes, port) { // Temperatur decodieren (4 Bytes, IEEE 754-Format) var temperatureBuffer = new ArrayBuffer(4); var temperatureView = new DataView(temperatureBuffer); // Bytes kopieren for (var i = 0; i < 4; i++) { temperatureView.setUint8(i, bytes[i]); } // Float-Wert auslesen var temperature = temperatureView.getFloat32(0, false); // Big Endian // Luftfeuchtigkeit decodieren (2 Bytes) var humidity = (bytes[4] << 8) | bytes[5]; // Status decodieren (1 Byte) var status = bytes[6]; return { temperature: temperature, // Temperatur in °C humidity: humidity / 10, // Luftfeuchtigkeit in % status: status // Status (z. B. 1 = OK) }; }
Mit diesem Skript kannst du die Payload in ihre ursprünglichen Werte zurückführen und z. B. als JSON-Objekt in der TTN-Datenbank speichern.
3. Zusammenfassung
- Effizientes Payload-Encoding: Nutze binäre Codierung, um Speicher und Energie zu sparen.
- Praxisnahes Decoding: Mit dem TTN-Decoding-Skript lassen sich die Daten leicht interpretieren.
- Flexibilität des TTGo LoRa ESP32: Dieses Board eignet sich hervorragend für IoT-Anwendungen, die lange Batterielaufzeiten und hohe Reichweiten erfordern.
Und schon sind wir wieder am Ende eines neuen DIYTechAdventures angelangt. Ich hoffe, es war nicht zu straff und du hast jetzt eine Idee, wie die Übertragung an TTN effizient gestaltet werden kann.
Im nächsten Beitrag zeige ich dir, wie du einen Node zum Beispiel mit dem TTGO LoRa Board ESP32 einrichtest, den Node in TTN einfügst und den payload formatter richtig einstellst.