/******************************************************************************* * 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 will send Temperature and Humidity * using frequency and encryption settings matching those of * the The Things Network. Application will 'sleep' 7x8 seconds (56 seconds) * * 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 #include #include #include "LowPower.h" #include // DIO Pin mapping is hardware specific. // The unversioned board needs a wire bridge from pin DIO1 (at the end of the large connector) to D6 (on the smaller connector). // The v1.2 board needs the solder bridges connected, especially the DIO1 1 bridge. // Only docs for the unversioned board are available currently. // See: https://docs.bsfrance.fr/documentation/11355_LORA32U4II/Datasheet_LoRa32u4II_1.1.pdf // // Uncomment the define line below if you have a LoRa32u4II without a version number (v1.x) //#define LoRa32u4II_VERSION LoRa32u4II_1_1 // Uncomment the define line below if you have a LoRa32u4II with version number (v1.2) //#define LoRa32u4II_VERSION LoRa32u4II_1_2 #define LoRa32u4II_1_1 11 #define LoRa32u4II_1_2 12 #if LoRa32u4II_VERSION == LoRa32u4II_1_1 #define DIO0 7 #define DIO1 6 #define DIO2 LMIC_UNUSED_PIN #define RESET_PIN 1 #elif LoRa32u4II_VERSION == LoRa32u4II_1_2 #define DIO0 0 #define DIO1 1 #define DIO2 2 #define RESET_PIN 4 #else #define DIO0 0 #define DIO1 0 #define DIO2 0 #define RESET_PIN 0 #error "Please specify which LoRa32u4 II version you have by commenting out the specific define line at the top of the ino file that starts with #define LoRa32u4II_VERSION" #endif int sleepcycles = 7; // every sleepcycle will last 8 secs, total sleeptime will be sleepcycles * 8 sec bool joined = false; bool sleeping = false; #define LedPin 22 // pin 13 LED is not used, because it is connected to the SPI port // 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 DEVEUI[8] = { 0x76, 0xA0, 0xA6, 0x01, 0xAC, 0xC2, 0x8B, 0x00 }; static const u1_t APPEUI[8] = { 0xBD, 0x7C, 0x00, 0xD0, 0x7E, 0xD5, 0xB3, 0x70 }; // 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. // The key shown here is the semtech default key. static const u1_t APPKEY[16] = { 0xAE, 0x6A, 0xFA, 0xA3, 0x30, 0x9C, 0xEF, 0xE4, 0xAE, 0x69, 0x2F, 0x63, 0xC3, 0x34, 0x96, 0xF6 }; static void initfunc (osjob_t*); // provide APPEUI (8 bytes, LSBF) void os_getArtEui (u1_t* buf) { memcpy(buf, APPEUI, 8); } // provide DEVEUI (8 bytes, LSBF) void os_getDevEui (u1_t* buf) { memcpy(buf, DEVEUI, 8); } // provide APPKEY key (16 bytes) void os_getDevKey (u1_t* buf) { memcpy(buf, APPKEY, 16); } static osjob_t sendjob; static osjob_t initjob; const lmic_pinmap lmic_pins = { .nss = 8, .rxtx = LMIC_UNUSED_PIN, .rst = RESET_PIN, // Needed on RFM92/RFM95? (probably not) D0/GPIO16 on v1.1 .dio = {DIO0, DIO1, DIO2}, // Specify pin numbers for DIO0, DIO1, DIO2 }; void onEvent (ev_t ev) { int i,j; 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")); // Disable link check validation (automatically enabled // during join, but not supported by TTN at this time). LMIC_setLinkCheckMode(0); digitalWrite(LedPin,LOW); // after Joining a job with the values will be sent. joined = true; 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")); // Re-init os_setCallback(&initjob, initfunc); break; case EV_TXCOMPLETE: sleeping = true; if (LMIC.dataLen) { // data received in rx slot after tx // if any data received, a LED will blink // this number of times, with a maximum of 10 Serial.print(F("Data Received: ")); Serial.println(LMIC.frame[LMIC.dataBeg],HEX); i=(LMIC.frame[LMIC.dataBeg]); // i (0..255) can be used as data for any other application // like controlling a relay, showing a display message etc. if (i>10){ i=10; // maximum number of BLINKs } for(j=0;j