Example to get the Dragino LoRa shield running on a Arduino Leonardo
/******************************************************************************* | |
* Copyright (c) 2015 Thomas Telkamp and Matthijs Kooijman | |
* | |
* 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 (early prototype version of) The Things Network. | |
* | |
* Note: LoRaWAN per sub-band duty-cycle limitation is enforced (1% in g1, | |
* 0.1% in g2). | |
* | |
* Change DEVADDR to a unique address! | |
* See http://thethingsnetwork.org/wiki/AddressSpace | |
* | |
* Do not forget to define the radio type correctly in config.h. | |
* | |
* | |
* Slightly changed by designer2k2.at for a first test run 24.01.2020 | |
* | |
*******************************************************************************/ | |
#include <lmic.h> | |
#include <hal/hal.h> | |
#include <SPI.h> | |
// LoRaWAN NwkSKey, network session key | |
// This is the default Semtech key, which is used by the prototype TTN | |
// network initially. | |
static const PROGMEM u1_t NWKSKEY[16] = { 0x19, 0x94, 0xAC, 0x00, 0x9C, 0xA2, 0xA7, 0xCE, 0x75, 0xD2, 0x00, 0xA5, 0x4F, 0x6F, 0xE4, 0x9C }; | |
// LoRaWAN AppSKey, application session key | |
// This is the default Semtech key, which is used by the prototype TTN | |
// network initially. | |
static const u1_t PROGMEM APPSKEY[16] = { 0xE0, 0xFB, 0xFD, 0x19, 0xFF, 0x06, 0x6A, 0x00, 0xCF, 0x56, 0x43, 0x8D, 0x2D, 0x16, 0x79, 0x8C }; | |
// LoRaWAN end-device address (DevAddr) | |
// See http://thethingsnetwork.org/wiki/AddressSpace | |
static const u4_t DEVADDR = 0x26012344 ; // <-- Change this address for every node! | |
// These callbacks are only used in over-the-air activation, so they are | |
// left empty here (we cannot leave them out completely unless | |
// DISABLE_JOIN is set in config.h, otherwise the linker will complain). | |
void os_getArtEui (u1_t* buf) { } | |
void os_getDevEui (u1_t* buf) { } | |
void os_getDevKey (u1_t* buf) { } | |
static uint8_t mydata[] = "HY"; //minimal to reduce band usage | |
static osjob_t sendjob; | |
// Schedule TX every this many seconds (might become longer due to duty | |
// cycle limitations). | |
const unsigned TX_INTERVAL = 20; | |
// Pin mapping Dragino Shield | |
const lmic_pinmap lmic_pins = { | |
.nss = 10, | |
.rxtx = LMIC_UNUSED_PIN, | |
.rst = 9, | |
.dio = {2, 6, 7}, | |
}; | |
const int ledPin = 13; // the number of the LED pin | |
void onEvent (ev_t ev) { | |
Serial.print(os_getTime()); | |
Serial.print(": "); | |
switch(ev) { | |
case EV_SCAN_TIMEOUT: | |
Serial.println(F("EV_SCAN_TIMEOUT")); | |
break; | |
case EV_BEACON_FOUND: | |
Serial.println(F("EV_BEACON_FOUND")); | |
break; | |
case EV_BEACON_MISSED: | |
Serial.println(F("EV_BEACON_MISSED")); | |
break; | |
case EV_BEACON_TRACKED: | |
Serial.println(F("EV_BEACON_TRACKED")); | |
break; | |
case EV_JOINING: | |
Serial.println(F("EV_JOINING")); | |
break; | |
case EV_JOINED: | |
Serial.println(F("EV_JOINED")); | |
break; | |
case EV_RFU1: | |
Serial.println(F("EV_RFU1")); | |
break; | |
case EV_JOIN_FAILED: | |
Serial.println(F("EV_JOIN_FAILED")); | |
break; | |
case EV_REJOIN_FAILED: | |
Serial.println(F("EV_REJOIN_FAILED")); | |
break; | |
break; | |
case EV_TXCOMPLETE: | |
Serial.println(F("EV_TXCOMPLETE (includes waiting for RX windows)")); | |
if(LMIC.dataLen) { | |
// data received in rx slot after tx | |
Serial.print(F("Data Received: ")); | |
Serial.write(LMIC.frame+LMIC.dataBeg, LMIC.dataLen); | |
Serial.println(); | |
} | |
// Schedule next transmission | |
os_setTimedCallback(&sendjob, os_getTime()+sec2osticks(TX_INTERVAL), do_send); | |
break; | |
case EV_LOST_TSYNC: | |
Serial.println(F("EV_LOST_TSYNC")); | |
break; | |
case EV_RESET: | |
Serial.println(F("EV_RESET")); | |
break; | |
case EV_RXCOMPLETE: | |
// data received in ping slot | |
Serial.println(F("EV_RXCOMPLETE")); | |
break; | |
case EV_LINK_DEAD: | |
Serial.println(F("EV_LINK_DEAD")); | |
break; | |
case EV_LINK_ALIVE: | |
Serial.println(F("EV_LINK_ALIVE")); | |
break; | |
default: | |
Serial.println(F("Unknown event")); | |
break; | |
} | |
} | |
void do_send(osjob_t* j){ | |
// Check if there is not a current TX/RX job running | |
if (LMIC.opmode & OP_TXRXPEND) { | |
Serial.println(F("OP_TXRXPEND, not sending")); | |
} else { | |
// Prepare upstream data transmission at the next possible time. | |
// set the LED with the ledState of the variable: | |
digitalWrite(ledPin, HIGH); | |
//hier noch den SF ändern, zwischen SF7 SF9 SF12 wechseln? | |
LMIC_setTxData2(1, mydata, sizeof(mydata)-1, 0); | |
Serial.println(F("Packet queued")); | |
Serial.print("LMIC.txChnl:"); | |
Serial.println(LMIC.txChnl); | |
Serial.print("LMIC.adrTxPow:"); | |
Serial.println(LMIC.adrTxPow); | |
Serial.print("LMIC.txpow:"); | |
Serial.println(LMIC.txpow); | |
Serial.print("LMIC.globalDutyRate:"); | |
Serial.println(LMIC.globalDutyRate); | |
Serial.print("LMIC.globalDutyAvail:"); | |
Serial.println(LMIC.globalDutyAvail); | |
digitalWrite(ledPin, LOW); | |
} | |
// Next TX is scheduled after TX_COMPLETE event. | |
} | |
void setup() { | |
Serial.begin(115200); | |
Serial.println(F("Starting")); | |
#ifdef VCC_ENABLE | |
// For Pinoccio Scout boards | |
pinMode(VCC_ENABLE, OUTPUT); | |
digitalWrite(VCC_ENABLE, HIGH); | |
delay(1000); | |
#endif | |
// set the digital pin as output: | |
pinMode(ledPin, OUTPUT); | |
// LMIC init | |
os_init(); | |
// Reset the MAC state. Session and pending data transfers will be discarded. | |
// This also triggers initDefaultChannels in CFG_us915 | |
LMIC_reset(); | |
// Set static session parameters. Instead of dynamically establishing a session | |
// by joining the network, precomputed session parameters are be provided. | |
#ifdef PROGMEM | |
// On AVR, these values are stored in flash and only copied to RAM | |
// once. Copy them to a temporary buffer here, LMIC_setSession will | |
// copy them into a buffer of its own again. | |
uint8_t appskey[sizeof(APPSKEY)]; | |
uint8_t nwkskey[sizeof(NWKSKEY)]; | |
memcpy_P(appskey, APPSKEY, sizeof(APPSKEY)); | |
memcpy_P(nwkskey, NWKSKEY, sizeof(NWKSKEY)); | |
LMIC_setSession (0x1, DEVADDR, nwkskey, appskey); | |
#else | |
// If not running an AVR with PROGMEM, just use the arrays directly | |
LMIC_setSession (0x1, DEVADDR, NWKSKEY, APPSKEY); | |
#endif | |
// Set up the channels used by the Things Network, which corresponds | |
// to the defaults of most gateways. Without this, only three base | |
// channels from the LoRaWAN specification are used, which certainly | |
// works, so it is good for debugging, but can overload those | |
// frequencies, so be sure to configure the full frequency range of | |
// your network here (unless your network autoconfigures them). | |
// Setting up channels should happen after LMIC_setSession, as that | |
// configures the minimal channel set. | |
LMIC_setupChannel(0, 868100000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g1-band | |
LMIC_setupChannel(1, 868300000, DR_RANGE_MAP(DR_SF12, DR_SF7B), BAND_CENTI); // g1-band | |
LMIC_setupChannel(2, 868500000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g1-band | |
LMIC_setupChannel(3, 867100000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band | |
LMIC_setupChannel(4, 867300000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band | |
LMIC_setupChannel(5, 867500000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band | |
LMIC_setupChannel(6, 867700000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band | |
LMIC_setupChannel(7, 867900000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band | |
// TTN defines an additional channel at 869.525Mhz using SF9 for class B | |
// devices' ping slots. LMIC does not have an easy way to define set this | |
// frequency and support for class B is spotty and untested, so this | |
// frequency is not configured here. | |
// Disable link check validation | |
LMIC_setLinkCheckMode(0); | |
// Set data rate and transmit power (note: txpow seems to be ignored by the library) | |
LMIC_setDrTxpow(DR_SF7,14); | |
// Start job | |
do_send(&sendjob); | |
} | |
void loop() { | |
os_runloop_once(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment