Eine Node nie ohne Antenne in Betrieb nehmen! Durch die reflektierte Sendenenergie nimmt der LoRa-Chip Schaden.
Aufbau einer LoRa-Node zur Überwachung von Temperatur und Feuchte in einem abgelegenen Gebäude.
Verwendung findet dabei der „Digitale Temperatur- und Feuchte-Sensor“ DHT22.
Da im Gebäude Strom verfügbar ist und die Überwachung nur temporär sein soll, wurden einige Vereinfachungen vorgenommen. Der Node wird über ein USB-Steckernetzteil versorgt. Der Aufbau ist in einem Halbschalengehäuse untergebracht. Der interne Aufbau ist „fliegend“.
Weiterhin werden die Messwerte auf ganze Zahlen gerundet. D.h. sowohl die Temperatur als auch die Angaben zur relativen Luftfeuchte werden nur in 1 °C - bzw. 1% RelH- Schritten übertragen. Dafür benötigt die Übertragung nur insgesamt zwei Byte Daten. Dieses kommt der Datansparsamkeit zugute. Weiterhin werden nur alle 30 Minuten Daten übertragen.
Benötigtes Material:
Der DHT22 besitzt vier Anschlüsse - VCC - Daten - NULL - GND (Datenblatt
Die Anschlüsse NULL und GND sind zusammenzulegen und auf GND zu führen. Zur Verkabelung kommen die aus den Arduino Workshops bekannten Steckerkabel zur Anwendung.
Am DHT22 besitzen die Kabel eine Buchse, am anderen Ende einen kleinen Steckstift. Dieser wird einfach in die entsprechende Buchsenleiste am LoRa Shield (VCC, GND und Digital Pin 4 ) gesteckt. Der DHT22 passt in die Buchsen der Steckerkabel.
Man verbindet zwei dieser Steckerkabel zu einem „Y“, d.h. zwei Buchsen auf der Seite des DHT22 und ein Stecker auf Seite des LoRa-Shields. (Durchschneiden, Abisolieren, Zusammenlöten, Schrumpfschlauch drüber)
Die vier Buchsen klebt man, nachdem sie am DHT22 gesteckt und damit ausgerichtet sind, mit einem kleinen Streifen Gewebeband zu einer vierpoligen „Buchsenleiste“ zusammen.
Die Stirnwand des Schalenghäuses ist in einer Führung einsetzbar und soll mit einem kleinen Durchführungsloch für die Schraubantenne gleichzeitg als „Halterung“ für den Arduino gelten.
An geigneter Stelle ein Loch bohren, Schraubanschluß hinhdurchstecken, Antenne aufschrauben - fertig.
An der gegenüberliegenden Stirnwand des Halbschalengehäuses an passender Stelle einen Schlitz zur Durchführung des USB-Kabel einarbeiten und am oberen Rand einen schmalen Bereich ausschneiden, um das Kabel für den Sensor durchführen zu können. Ist der Bereich schmal genug, klemmt der Deckel das Kabel etwas ein und sichert es dadurch auch etwas.
Zuletzt noch den Halbschalendeckel aufsetzen. Fertig ist die Node.
Was wäre eine Node ohne Programm (Sketch)? (siehe auch)
Zur Verwendung kommt der LoRa-Universalsketch (von mir gekürzt und ohne die Serial.print-Anweisungen) mit Erweiterungen zum Auslesen des Sensors DHT22.
Zum ersten Test wurden einige eigene Serial.print-Anweisungen verwendet. Sobald der Node funktionierte wurden sie deaktiviert.
Nartürlich muss die Node vorher wieder im TTN-Netzwerk in seiner zugehörigen Applikation registriert werden. Dadurch erhält man alle nötigen Adress- und Passwortangaben (APPEUI, DEVEUI und APPKEY) die im Sketch eingetragen werden müssen.
(Ich habe diese Daten im nachfolgenden Listing natürlich wieder unkenntlich gemacht)
Der Sketch wurde mit der Bibliothek „MCCI_LoRaWAN_LMIC_library“ compiliert.
/******************************************************************************* Copyright (c) 2015 Thomas Telkamp and Matthijs Kooijman Copyright (c) 2018 Terry Moore, MCCI Permission is hereby granted, free of charge, to anyone obtaining a copy of this document and accompanying files, to do whatever they want with them without any restriction, including, but not limited to, copying, modification and redistribution. NO WARRANTY OF ANY KIND IS PROVIDED. This example sends a valid LoRaWAN packet with payload "Hello, world!", using frequency and encryption settings matching those of the The Things Network. This uses OTAA (Over-the-air activation), where where a DevEUI and application key is configured, which are used in an over-the-air activation procedure where a DevAddr and session keys are assigned/generated for use with all further communication. Note: LoRaWAN per sub-band duty-cycle limitation is enforced (1% in g1, 0.1% in g2), but not the TTN fair usage policy (which is probably violated by this sketch when left running for longer)! To use this sketch, first register your application and device with the things network, to set or generate an AppEUI, DevEUI and AppKey. Multiple devices can use the same AppEUI, but each device has its own DevEUI and AppKey. Do not forget to define the radio type correctly in arduino-lmic/project_config/lmic_project_config.h or from your BOARDS.txt. *******************************************************************************/ #include <lmic.h> #include <hal/hal.h> #include <SPI.h> // //eigene Bibliotheken #include <SimpleDHT.h> // // eigene Defintitionen //DHT22 int pinDHT22 = 4; SimpleDHT22 dht22(pinDHT22); float temperature = 0; float humidity = 0; // // // Application EUI Reihenfolge LSB MSB static const u1_t PROGMEM APPEUI[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; void os_getArtEui (u1_t* buf) { memcpy_P(buf, APPEUI, 8); } //Device EUI Reihenfolge LSB MSB static const u1_t PROGMEM DEVEUI[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; void os_getDevEui (u1_t* buf) { memcpy_P(buf, DEVEUI, 8); } // Application Key Achtung: Reihenfolge MSB LSB static const u1_t PROGMEM APPKEY[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; void os_getDevKey (u1_t* buf) { memcpy_P(buf, APPKEY, 16); } static uint8_t payload[] = "XY"; static osjob_t sendjob; // Schedule TX every this many seconds (might become longer due to duty // cycle limitations). const unsigned TX_INTERVAL = 1800; //30 Min // Pin Mapping für Graduino LoRa Shield for Arduino const lmic_pinmap lmic_pins = { .nss = 10, .rxtx = LMIC_UNUSED_PIN, .rst = 9, .dio = {2, 6, 7}, }; void onEvent (ev_t ev) { switch (ev) { case EV_JOINED: { u4_t netid = 0; devaddr_t devaddr = 0; u1_t nwkKey[16]; u1_t artKey[16]; LMIC_getSessionKeys(&netid, &devaddr, nwkKey, artKey); } // Disable link check validation (automatically enabled // during join, but because slow data rates change max TX // size, we don't use it in this example. LMIC_setLinkCheckMode(0); break; case EV_TXCOMPLETE: // Schedule next transmission os_setTimedCallback(&sendjob, os_getTime() + sec2osticks(TX_INTERVAL), do_send); break; default: break; } } void do_send(osjob_t* j) { // Check if there is not a current TX/RX job running if (LMIC.opmode & OP_TXRXPEND) { } else { // Eigene Sensoren temperature = 0; humidity = 0; int err = SimpleDHTErrSuccess; if ((err = dht22.read(&temperature, &humidity, NULL)) != SimpleDHTErrSuccess) { //Serial.print("Read DHT22 failed, err="); Serial.println(err); delay(2000); //return; temperature=0; humidity=0; } //Serial.print("Sample OK: "); //Serial.print(temperature); Serial.print(" *C, "); //Serial.print(humidity); Serial.println(" RH%"); //DHT22 sampling rate is 0.5HZ. delay(2500); // die Integerwerte werden jeweils als 1 Byte übertragen, sie kommen im Hex-Format bei TTN an // d.h. Anzeige TTN 1. Byte 14 (Hex) ist 20 Grad Celsius // 2. Byte 38 (Hex) ist 56 % Rel H payload[0] = int(temperature); payload[1] = int(humidity); // Ende eigene Sensoren // Prepare upstream data transmission at the next possible time. LMIC_setTxData2(1, payload, sizeof(payload) - 1, 0); } // Next TX is scheduled after TX_COMPLETE event. } void setup() { // Eigenes Setup //Serial.begin(115200); //Serial.println("DHT22 - Test!"); // Ende eigenes Setup // // LMIC init os_init(); // Reset the MAC state. Session and pending data transfers will be discarded. LMIC_reset(); // Start job (sending automatically starts OTAA too) do_send(&sendjob); } void loop() { os_runloop_once(); }
Was kommt hinzu: (Zeilenangaben in Klammern)
Stand: 09.11.2020