Beispiel Sketch

Vorgaben bezüglich Duty Cycle

Um die Edu-Platine mit einem LoRaWAN Netz zu verbinden, muss ein Join gemacht werden. Das kann auf zwei Weisen gemacht werden OTAA (Over The Air Activation) oder ABP (Activation By Personalization).

Für OTAA werden Application EUI, Device EUI und Application Key benötigt. Die Encryption Keys werden pro Session generiert (Network/Application Session Key). Das Resultat ist eine sicherere Verbindung. Bei ABP sind die Encryption Keys bereits dem Server und dem Endgerät bekannt, es müssen also keine Session Keys vor dem Start der Kommunikation ausgetauscht werden.

Durch zuviele Sendungen besteht das Risiko, das Netz an die Grenzen der Duty Cycle Limitation zu bringen. Die Duty Cycle Limitation legt den Ressourcenverbrauch des Netzes fest. Die Limitation beträgt 1%, d.h. dass über das Netz nur 1% pro Stunde gesendet werden darf, also insgesamt 36 Sekunden pro Stunde. Für den normalen Gebrauch von LoRa Sensoren ist das ausreichend, da die Datenmengen und Time on Air (ToA) gering sind. Beim Testen von Geräten wird aber schnell das Netzwerk blockiert, wenn viele Geräte zeitnah und häufig dem Netzwerk beitreten wollen und jedesmal die Session Keys ausgetauscht werden müssen. Darum sollte im Rahmen des Hackathons der Join nur über ABP gemacht werden. Denn bei diesem Join-Verfahren sind die Session keys bereits Sensor und Server hinterlegt. Es werden also Device Adress, Application Session Key und Network Session Key benötigt. Dadurch verbraucht der Verbindungsaufbau weniger der begrenzten ToA.

Bitte verwende im Rahmen des Hackathons nur ABP mit Unconfirmed Uplinks um den Duty Cylce nicht zu gefährden. Andere Teilnehmer werden es dir danken!

Example Firmware

Download Arduino IDE Sketch

Benötigte Bauteile

  • (1) x SCS Edu-Platine

Benötigte Bibliothekten

  • LMIC
  • SPI

Unter Getting Started/Bibliotheken und Board Support findest du Links zu den Bibliotheken falls diese über den Bibliotheken-Manager nicht gefunden werden sollten oder du mehr darüber erfahren möchtest

Programmablauf

Zur besseren Übersicht, hier ein schemafreier Programmablauf:

LoRa Sketch Programmablauf

Code

#include <lmic.h>
#include <hal/hal.h>
#include <SPI.h>

Für den Join durch ABP müssen Device Adresse, Application Session Key und Network Session Key im Sketch hinterlegt werden. Die Keys sind inidivudell für jede Edu-Platine und wurden dir von der Hackathon-Leitung zur Verfügung gestellt. Die Device Adresse ist 4 Byte lang und wird als Hex-Zahl angegeben, die beiden Session Keys sind jeweils 16 Byte lang und werden als Array von 8 Byte Hex-Zahlen angegeben.

static const u4_t DEVADDR = 0x02F8FE3F;

static const PROGMEM u1_t APPSKEY[16] = { 0xCD, 0x3D, 0x9C, 0x56, 0x2E, 0x73, 0x93, 0xC9, 0xAC, 0x4B, 0xAA, 0xF1, 0x19, 0x61, 0x6F, 0x3C }; // CD3D9C562E7393C9AC4BAAF119616F3C

static const PROGMEM u1_t NWKSKEY[16] = { 0x67, 0xA3, 0x78, 0x71, 0x8F, 0x83, 0xEC, 0x51, 0xB1, 0xFD, 0xD3, 0xFC, 0x32, 0x7F, 0xFE, 0xA6 }; // 67A378718F83EC51B1FDD3FC327FFEA6

Anschließend deklarieren wir eine Variable welche uns beim Senden von Signalen hilft und legen das Sendeintervall in Sekunden fest.

static osjob_t sendjob;
const unsigned TX_INTERVAL = 100;

RST, IRQ und CS (bzw. nss) Pins müssen für die Edu-Platine korrekt gemappt werden.

const lmic_pinmap lmic_pins = {
  .nss = 8,
  .rxtx = LMIC_UNUSED_PIN,
  .rst = 4,
  .dio = {3, 6, LMIC_UNUSED_PIN},  
};

Wir implementieren die Methode zum versenden von Daten am Beispiel des Batteriestandes, hier manuell gesetzt, da die Edu-Platine per USB mit Strom versorgt wird.

void do_send(osjob_t* j) {
  if (LMIC.opmode & OP_TXRXPEND) {
    //currently another sending is in progress
  } else {
    float measuredvbat = 0;
    measuredvbat *= 2;      
    measuredvbat *= 3.3;    
    measuredvbat /= 1024;  
    float temp = measuredvbat;
    int intPart = (int)measuredvbat;
    temp -= intPart;
    temp *= 10000;
    int fracPart = (int)temp;
    char buffer[10];
    sprintf(buffer, "%d.%d", intPart, fracPart);
    String res = buffer;
    LMIC_setTxData2(1, (uint8_t*) buffer, res.length(), 0);
  }
}

Die LMIC-Bibliothek besitzt Hooks für Events, die wir hier verwenden um nach jedem gesendeten Paket (TXCOMPLETE) die nächste Sendung einzureihen:

void onEvent (ev_t ev) {
  switch (ev) {
    case EV_TXCOMPLETE:
      digitalWrite(LED_BUILTIN, LOW);
      time_start_ms_tx = millis();
      os_setTimedCallback(&sendjob, os_getTime() + sec2osticks(TX_INTERVAL), do_send);
      break;
    default:
      break;
  }
}

In der Setup Methode werden Datenrate und Transmission Power festgelegt. Der Spreading Factor (SF) muss zwischen 7 und 12 liegen. Dabei ist SF7 am besten geeignet für Transmissions die nur eine kurze Strecke zurücklegen müssen, SF12 für solche, die eine größere Reichweite erreichen müssen. Ein niedriger Spreading Factor kann die Größe des Sendeintervalls bzw. die Time on Air reduzieren, allerdings muss man damit rechnen, dass Pakete über längere Strecken häufiger verloren gehen.

LMIC_setDrTxpow(DR_SF8, 14);

Beim Hochladen des Sketches sendet die Platine automatisch einen Join Request, der vom Netzwerk empfangen wird. Danach sendet die Platine im festgelegten Sendeintervall (TX_INTERVAL) Datenpakete.