Das LoRa Bee basiert auf dem SX1276/SX1278 Transceiver Chip.
Bezugsquelle LoRa Bee Modul Zusätzlich zum Modul empfiehlt es sich noch das Breakout Board dazuzunehmen. Dann kann Das Modul nämlich direkt in ein Breadboard gesteckt werden. https://shop.boxtec.ch/breakout-board-fuer-xbee-modul-p-42052.html
Falls Ihr für die Verwendung von dem LoRa Bee Modul als Single Channel Gateway interessiert seit, findet Ihr hier Informationen: LoRa Bee Modul als Single Channel Gateway
Wichtigster Punkt: Da Modul kann nur mit 3.3 Volt betrieben werden! Es wird also ein 3.3 Volt Arudino benötigt oder ein Level Shifter.
Einige Informationen sind auf der Wiki Seite von Dragino hilfreich: http://wiki.dragino.com/index.php?title=Lora_BEE
Jedoch fehlt ein einfaches Beispiel für den Anschluss an einen Arduino.
Hier mein Setup:
Das Setup muss dann mit der Konfiguration im Programm zusammenpassen. Folgendes habe ich definiert:
// Pin mapping const lmic_pinmap lmic_pins = { .nss = 10, .rxtx = LMIC_UNUSED_PIN, .rst = 9, .dio = {2, 6, LMIC_UNUSED_PIN}, };
Da ich keinen 3.3 Volt Arduino zur Hand hatte. Habe überbrücke ich Spannungs Level mit dem FTDI Kabel von 5 Volt auf 3.3 Volt. Dadurch läuft der Arduino mit 3.3 Volt und natürlich auch der Lora Bee.
Das ganze sieht dann so aus:
Die Arduino LMIC Library eignet sich sehr gut für den Betrieb vom LoRa Bee Modul. Schaut Euch auch im Detail die Informationen der Library auf Github an, die sind sehr gut gemacht.
https://github.com/matthijskooijman/arduino-lmic
Bevor man starten kann muss man allerdings in der Library in der Datei config.h noch den Chip definieren. Dazu die richtige Zeile aktivieren. (Führende Kommentar Zeichen entfernen)
// This is the SX1272/SX1273 radio, which is also used on the HopeRF // RFM92 boards. //#define CFG_sx1272_radio 1 // This is the SX1276/SX1277/SX1278/SX1279 radio, which is also used on // the HopeRF RFM95 boards. #define CFG_sx1276_radio 1
Alternativ gibt es auch noch die LoRa Library: https://github.com/sandeepmistry/arduino-LoRa/tree/master/examples
Auch hier müssen wir die Pin's welche mit der Arduino verbunden sind definieren. Für unser Setup sieht das so aus:
const int csPin = 10; // LoRa radio chip select const int resetPin = 9; // LoRa radio reset const int irqPin = 2; // change for your board; must be a hardware interrupt pin
Um einen einfachen Test mit der LMIC Library durchzuführen sollten zwei Module und zwei Arduino's vorhanden sein. Dazu einfach das Beispiel Programm “RAW” der LMIC Library laden.
Damit zwei Module mit dem LoRa Protokoll miteinander reden können muss in der Library noch etwas umgestellt werden. Normalerweise sollen die Nodes ja nur mit Gateways kommunizieren. Dazu in der Library im File config.h folgende Zeile aktivieren:
// In LoRaWAN, a gateway applies I/Q inversion on TX, and nodes do the // same on RX. This ensures that gateways can talk to nodes and vice // versa, but gateways will not hear other gateways and nodes will not // hear other nodes. By defining this macro in lmic_project_config.h, // this inversion is disabled and this node can hear other nodes. If // two nodes both have this macro set, they can talk to each other // (but they can no longer hear gateways). This should probably only // be used when debugging and/or when talking to the radio directly // (e.g. like in the "raw" example). #define DISABLE_INVERT_IQ_ON_RX
Achtung diese Anpassung an der config.h Datei muss für den normalen Betrieb vom Lora Bee mit einem Gateway wieder deaktiviert werden.
Dann habe ich mich mit dem Seriellen Monitor der Arduino IDE auf ersten Arduino und mit Putty auf den 2. Arduino verbunden. Damit ich den Datenfluss noch etwas besser sehe habe ich das Beispiel in Zeile 111 noch etwas angepasst:
// say hello tx("Hello, world from USB0!", txdone_func);
Hier sieht man schön wie die beiden miteinander kommunizieren.
Hier ein Testaufbau für mit der LoRa Library. Wir benötigen wieder zwei Module mit zwei Arduino's verbunden. In den Beispielen der LoRa Library nehmen wir das “Duplex” Beispiel und passen den Teil mit den Pins an. (Zeile 17-19)
const int csPin = 10; // LoRa radio chip select const int resetPin = 9; // LoRa radio reset const int irqPin = 2; // change for your board; must be a hardware interrupt pin
Zudem müssen wir die Frequenz in Zeile 38 noch anpassen:
if (!LoRa.begin(868E6)) { // initialize ratio at 915 MHz
Jetzt laden wir das Programm auf den ersten Arduino. Für den Zweiten Arduino passen wir die Variable localAddress auf 0xAA an. Dann laden wir dieses Programm auf den zweiten Arduino. Jetzt und öffnen wir die beiden seriellen Schnittstellen. Hier sehen wir schön, dass die beiden miteinander kommunizieren.
Jetzt wollen wir aber den Lora Bee richtig nutzen und Daten an das “The Things Network” https://www.thethingsnetwork.org/ senden. Zuerst prüft Ihr am besten auf der Karte von TTN ob es einen Gatway in Eurer Nähe gibt. Falls ja ist alles bestens und Ihr könnt hier weitermachen. Falls nicht empfiehlt es sich einen “Test Gatway” zu bauen. Ansonsten dazu mehr hier: LoRa Bee Modul als Single Channel Gateway
Dazu muss man sich zuerst auf der Website registrieren. Danach die Console https://console.thethingsnetwork.org öffnen und eine “Application” erstellen.
Danach unter “Devices” eine neue Device anlegen. Jetzt müssen wir uns für eine Aktivierungs Methode entscheiden. Wir nehmen APB “Activation by personalization”
Unter “Example Code” können wir uns den Code für das Arduino Programm kopieren.
Jetzt holen wir uns das Beispiel “ttn-abp” in der Arduino IDE von der LMIC Library und müssen die 3 Variablen: NWKSKEY, APPSKEY und DEVADDR mit dem Inhalt von der TTN Webseite belegt werden. Da sieht dann Beispielhaft so aus:
Zusätzlich müssen wir wieder das Pin mapping anpassen.
// Pin mapping const lmic_pinmap lmic_pins = { .nss = 10, .rxtx = LMIC_UNUSED_PIN, .rst = 9, .dio = {2, 6, LMIC_UNUSED_PIN}, };
In der Seriellen Konsole können wir beobachten was passiert.
Wenn wir jetzt einen TTN Gateway erreichen sollten die Daten “Hello, world!” dann bei uns in der TTN Console erscheinen. Wenn wir noch ein “Payload” format definieren können wir das “Hello, world!” auch noch als Daten erkennen.
Hier das Payload format:
Hier unter “Application Data” sieht man die Daten, zuerst im Hex Format und dann umgesetzt als Zeichen.
Natürlich macht es keinen Sinn irgendwelchen Text im TTN Netzwerk zu übertragen. Dazu nehmen folgendes Coding, welches zusätzlich zum Lora Bee Chip noch einen DHT22 Sensor ansteuert.
Den Lora Bee haben wir wie oben beschrieben angeschlossen. Den DHT22 Sensor haben wir über den Pin 5 am Arduino angeschlossen. Natürlich verbinden wir den DHT22 auch mit GND und 3.3V.
Am Serial Port sehen wir folgendes Protokoll:
In der TTN Console sehen wir, dass die Daten angekommen sind. Hier hat also der Node die Daten: 00EA0245 übertragen. Das ist nicht 1:1 was in der Serial Konsole sichtbar ist, aber das liegt nur an der Zeitverschiebung die Temperatur und die Luftfeuchtigkeit haben sich gerade verändert.
Wenn wir uns im Detail das Coding vom Node anschauen, sehen wir folgendes.
// Convert the float readings from the libraries into integers to // easily encode, send and decode. // // DHT22 temperature readings are -40.0 to +80.0°C ±0.5°C accuracy // (-40.0 to 176.0°F), while a 16 bits signed integer supports -32768 // through 32767. After multiplying by 10, -400 through +1760 easily // fits into those 2 bytes. We could even multiply by 100, but that's // beyond the sensor's accuracy anyway. (false: return DHT22 reading // which is Celcius; true: let the library convert it to Fahrenheit) int16_t temp = 10 * DHT.temperature; // Humidity readings are 0-100% with 2-5% accuracy, while an 8 bits // unsigned integer supports 0 through 255, so the measurement fits. uint16_t hum = 10 * DHT.humidity; uint8_t buff[4]; // reserve 3 bytes in memory // Handle high byte (MSB) first; 0xFF for -234 or 0x00 for +234 // 0xFF16 >> 8 shifts the 0x16 out of memory, leaving 0x00FF // 0x00FF does not fit in a single byte, so only 0xFF is stored in buff[0]: buff[0] = temp >> 8; // Handle low byte (LSB) next; 0x16 for -234 or 0xEA for +234 // 0xFF16 does not fit in a single byte, so only 0x16 is stored in buff[1]: buff[1] = temp; // humitidy buff[2] = hum >> 8; buff[3] = hum;
Wir haben also 4 Bytes, in den ersten zwei Bytes speichern wir die Temperatur und in den zweiten zwei Bytes die Luftfeuchtigkeit. In beiden Bytes wird der Sensor Wert zuerst mit 10 multipliziert. Wenn wir also die Daten welche wir erhalten haben wieder auseinander nehmen.
Beispiel Daten: 00EA0245
Sensor | Hex Wert | Dezimal | /10 |
Temp | 00 EA | 234 | 23.4 |
Feuchtigkeit | 02 45 | 581 | 58.1 |
Das gleiche was wir jetzt hier manuell gemacht haben kann das TTN unter dem Thema “Payload Formats” automatisch machen. Dazu müssen wir folgendes Coding imDecoder hinterlegen:
function Decoder(bytes, port) { // Sign-extend 16 bits to 32 bits to support negative values var temp = bytes[0]<<24>>16 | bytes[1]; var hum = bytes[2]<<24>>16 | bytes[3]; var myTestValue = String.fromCharCode.apply(null, bytes); return { temp: temp / 10, hum: hum / 10, }; }
Hier können auch direkt Test mit Testdaten gemacht werden. Damit ist schnell sichbar ob der Decoder richtig funktioniert.
Wenn wir dann nochmals die Daten anschauen sehen wir die zwei lesbaren Werte: temp und hum für die Temparatur und die Luftfeuchtigkeit welche direkt berechnet werden.