diff --git a/Examples/LoRaWAN-LMIC-OTAA/LoRaWAN-LMIC-OTAA.ino b/Examples/LoRaWAN-LMIC-OTAA/LoRaWAN-LMIC-OTAA.ino new file mode 100644 index 0000000..7953bff --- /dev/null +++ b/Examples/LoRaWAN-LMIC-OTAA/LoRaWAN-LMIC-OTAA.ino @@ -0,0 +1,249 @@ +/******************************************************************************* + * 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 config.h. + * + *******************************************************************************/ + +#include +#include +#include + +#define UPLINK_CHANNEL 1 + +// +// For normal use, we require that you edit the sketch to replace FILLMEIN +// with values assigned by the TTN console. However, for regression tests, +// we want to be able to compile these scripts. The regression tests define +// COMPILE_REGRESSION_TEST, and in that case we define FILLMEIN to a non- +// working but innocuous value. +// + +// This EUI must be in little-endian format, so least-significant-byte +// first. When copying an EUI from ttnctl output, this means to reverse +// the bytes. For TTN issued EUIs the last bytes should be 0xD5, 0xB3, +// 0x70. +static const u1_t PROGMEM APPEUI[8] = { 0x4D, 0x41, 0x01, 0xD0, 0x7E, 0xD5, 0xB3, 0x70 }; +void os_getArtEui (u1_t* buf) { memcpy_P(buf, APPEUI, 8);} + +// This should also be in little endian format, see above. +static const u1_t PROGMEM DEVEUI[8] = { 0xA1, 0x4C, 0x99, 0xC5, 0x8D, 0xA1, 0x2E, 0x00 }; +void os_getDevEui (u1_t* buf) { memcpy_P(buf, DEVEUI, 8);} + +// This key should be in big endian format (or, since it is not really a +// number but a block of memory, endianness does not really apply). In +// practice, a key taken from ttnctl can be copied as-is. +static const u1_t PROGMEM APPKEY[16] = { 0xCB, 0x95, 0x29, 0x6C, 0x57, 0x88, 0x24, 0xCD, 0xBA, 0x6A, 0x90, 0xA8, 0x8E, 0x99, 0x7C, 0x64 }; +void os_getDevKey (u1_t* buf) { memcpy_P(buf, APPKEY, 16);} + +static uint8_t mydata[] = "Hello, world!"; +static osjob_t sendjob; + +// Schedule TX every this many seconds (might become longer due to duty +// cycle limitations). +const unsigned TX_INTERVAL = 60; + +// Pin mapping +const lmic_pinmap lmic_pins = { + .nss = 10, + .rxtx = LMIC_UNUSED_PIN, + .rst = 5, + .dio = {2, 3, 4}, +}; + + +// Disables all channels, except for the one defined above, and sets the +// data rate (SF). This only affects uplinks; for downlinks the default +// channels or the configuration from the OTAA Join Accept are used. +// +// Not LoRaWAN compliant; FOR TESTING ONLY! +// +void forceTxSingleChannelDr(int channel, int data_rate) { + for(int i=0; i<9; i++) { // For EU; for US use i<71 + if(i != channel) { + LMIC_disableChannel(i); + } + } + // Set data rate (SF) and transmit power for uplink + LMIC_setDrTxpow(data_rate, 14); +} + +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")); + { + u4_t netid = 0; + devaddr_t devaddr = 0; + u1_t nwkKey[16]; + u1_t artKey[16]; + LMIC_getSessionKeys(&netid, &devaddr, nwkKey, artKey); + Serial.print("netid: "); + Serial.println(netid, DEC); + Serial.print("devaddr: "); + Serial.println(devaddr, HEX); + Serial.print("artKey: "); + for (int i=0; i