├── images ├── data.png ├── lmic.png ├── port.png ├── account.png ├── add-zip.png ├── console.png ├── create.png ├── feather.png ├── library.png ├── adafruit.png ├── finished.jpg ├── pro-micro.png ├── sparkfun.png ├── add-device.png ├── board-menu.png ├── components.jpg ├── console-link.png ├── feather-port.png ├── github-lmic.png ├── not-unique.png ├── preferences.png ├── library-added.png ├── pro-micro-3v3.png ├── pro-placement.jpg ├── serial-monitor.png ├── add-application.png ├── device-settings.png ├── register-device.png └── rfm95-placement.jpg ├── pro-micro-sketch └── pro-micro-sketch.ino ├── lora32u4-sketch └── lora32u4-sketch.ino ├── lora32u4.md └── readme.md /images/data.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kersing/node-workshop/HEAD/images/data.png -------------------------------------------------------------------------------- /images/lmic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kersing/node-workshop/HEAD/images/lmic.png -------------------------------------------------------------------------------- /images/port.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kersing/node-workshop/HEAD/images/port.png -------------------------------------------------------------------------------- /images/account.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kersing/node-workshop/HEAD/images/account.png -------------------------------------------------------------------------------- /images/add-zip.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kersing/node-workshop/HEAD/images/add-zip.png -------------------------------------------------------------------------------- /images/console.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kersing/node-workshop/HEAD/images/console.png -------------------------------------------------------------------------------- /images/create.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kersing/node-workshop/HEAD/images/create.png -------------------------------------------------------------------------------- /images/feather.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kersing/node-workshop/HEAD/images/feather.png -------------------------------------------------------------------------------- /images/library.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kersing/node-workshop/HEAD/images/library.png -------------------------------------------------------------------------------- /images/adafruit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kersing/node-workshop/HEAD/images/adafruit.png -------------------------------------------------------------------------------- /images/finished.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kersing/node-workshop/HEAD/images/finished.jpg -------------------------------------------------------------------------------- /images/pro-micro.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kersing/node-workshop/HEAD/images/pro-micro.png -------------------------------------------------------------------------------- /images/sparkfun.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kersing/node-workshop/HEAD/images/sparkfun.png -------------------------------------------------------------------------------- /images/add-device.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kersing/node-workshop/HEAD/images/add-device.png -------------------------------------------------------------------------------- /images/board-menu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kersing/node-workshop/HEAD/images/board-menu.png -------------------------------------------------------------------------------- /images/components.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kersing/node-workshop/HEAD/images/components.jpg -------------------------------------------------------------------------------- /images/console-link.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kersing/node-workshop/HEAD/images/console-link.png -------------------------------------------------------------------------------- /images/feather-port.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kersing/node-workshop/HEAD/images/feather-port.png -------------------------------------------------------------------------------- /images/github-lmic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kersing/node-workshop/HEAD/images/github-lmic.png -------------------------------------------------------------------------------- /images/not-unique.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kersing/node-workshop/HEAD/images/not-unique.png -------------------------------------------------------------------------------- /images/preferences.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kersing/node-workshop/HEAD/images/preferences.png -------------------------------------------------------------------------------- /images/library-added.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kersing/node-workshop/HEAD/images/library-added.png -------------------------------------------------------------------------------- /images/pro-micro-3v3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kersing/node-workshop/HEAD/images/pro-micro-3v3.png -------------------------------------------------------------------------------- /images/pro-placement.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kersing/node-workshop/HEAD/images/pro-placement.jpg -------------------------------------------------------------------------------- /images/serial-monitor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kersing/node-workshop/HEAD/images/serial-monitor.png -------------------------------------------------------------------------------- /images/add-application.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kersing/node-workshop/HEAD/images/add-application.png -------------------------------------------------------------------------------- /images/device-settings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kersing/node-workshop/HEAD/images/device-settings.png -------------------------------------------------------------------------------- /images/register-device.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kersing/node-workshop/HEAD/images/register-device.png -------------------------------------------------------------------------------- /images/rfm95-placement.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kersing/node-workshop/HEAD/images/rfm95-placement.jpg -------------------------------------------------------------------------------- /pro-micro-sketch/pro-micro-sketch.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2015 Thomas Telkamp and Matthijs Kooijman 3 | * 4 | * Permission is hereby granted, free of charge, to anyone 5 | * obtaining a copy of this document and accompanying files, 6 | * to do whatever they want with them without any restriction, 7 | * including, but not limited to, copying, modification and redistribution. 8 | * NO WARRANTY OF ANY KIND IS PROVIDED. 9 | * 10 | * This example will send Temperature and Humidity 11 | * using frequency and encryption settings matching those of 12 | * the The Things Network. Application will 'sleep' 7x8 seconds (56 seconds) 13 | * 14 | * This uses OTAA (Over-the-air activation), where where a DevEUI and 15 | * application key is configured, which are used in an over-the-air 16 | * activation procedure where a DevAddr and session keys are 17 | * assigned/generated for use with all further communication. 18 | * 19 | * Note: LoRaWAN per sub-band duty-cycle limitation is enforced (1% in 20 | * g1, 0.1% in g2), but not the TTN fair usage policy (which is probably 21 | * violated by this sketch when left running for longer)! 22 | 23 | * To use this sketch, first register your application and device with 24 | * the things network, to set or generate an AppEUI, DevEUI and AppKey. 25 | * Multiple devices can use the same AppEUI, but each device has its own 26 | * DevEUI and AppKey. 27 | * 28 | * Do not forget to define the radio type correctly in config.h. 29 | * 30 | *******************************************************************************/ 31 | 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include "LowPower.h" 38 | 39 | #include 40 | 41 | int sleepcycles = 7; // every sleepcycle will last 8 secs, total sleeptime will be sleepcycles * 8 sec 42 | bool joined = false; 43 | bool sleeping = false; 44 | #define LedPin 22 // pin 13 LED is not used, because it is connected to the SPI port 45 | 46 | // This EUI must be in little-endian format, so least-significant-byte 47 | // first. When copying an EUI from ttnctl output, this means to reverse 48 | // the bytes. For TTN issued EUIs the last bytes should be 0xD5, 0xB3, 49 | // 0x70. 50 | 51 | static const u1_t DEVEUI[8] = { 0xD1, 0x60, 0x79, 0xEE, 0x70, 0x76, 0x51, 0x00 }; 52 | static const u1_t APPEUI[8] = { 0xBD, 0x7C, 0x00, 0xD0, 0x7E, 0xD5, 0xB3, 0x70 }; 53 | 54 | // This key should be in big endian format (or, since it is not really a 55 | // number but a block of memory, endianness does not really apply). In 56 | // practice, a key taken from ttnctl can be copied as-is. 57 | // The key shown here is the semtech default key. 58 | static const u1_t APPKEY[16] = { 0xC6, 0xDC, 0xE3, 0x2F, 0x24, 0xC7, 0x24, 0x08, 0xC2, 0x8B, 0xC1, 0x30, 0xF5, 0xED, 0x78, 0x55 }; 59 | 60 | static void initfunc (osjob_t*); 61 | 62 | // provide APPEUI (8 bytes, LSBF) 63 | void os_getArtEui (u1_t* buf) { 64 | memcpy(buf, APPEUI, 8); 65 | } 66 | 67 | // provide DEVEUI (8 bytes, LSBF) 68 | void os_getDevEui (u1_t* buf) { 69 | memcpy(buf, DEVEUI, 8); 70 | } 71 | 72 | // provide APPKEY key (16 bytes) 73 | void os_getDevKey (u1_t* buf) { 74 | memcpy(buf, APPKEY, 16); 75 | } 76 | 77 | static osjob_t sendjob; 78 | static osjob_t initjob; 79 | 80 | // Pin mapping is hardware specific. 81 | // Pin mapping 82 | const lmic_pinmap lmic_pins = { 83 | .nss = 10, //8, 84 | .rxtx = LMIC_UNUSED_PIN, 85 | .rst = 0, //9, 86 | .dio = {4, 5, 7},//{2,5, LMIC_UNUSED_PIN}, //DIO0 and DIO1 connected 87 | }; 88 | 89 | 90 | void onEvent (ev_t ev) { 91 | int i,j; 92 | switch (ev) { 93 | case EV_SCAN_TIMEOUT: 94 | Serial.println(F("EV_SCAN_TIMEOUT")); 95 | break; 96 | case EV_BEACON_FOUND: 97 | Serial.println(F("EV_BEACON_FOUND")); 98 | break; 99 | case EV_BEACON_MISSED: 100 | Serial.println(F("EV_BEACON_MISSED")); 101 | break; 102 | case EV_BEACON_TRACKED: 103 | Serial.println(F("EV_BEACON_TRACKED")); 104 | break; 105 | case EV_JOINING: 106 | Serial.println(F("EV_JOINING")); 107 | break; 108 | case EV_JOINED: 109 | Serial.println(F("EV_JOINED")); 110 | // Disable link check validation (automatically enabled 111 | // during join, but not supported by TTN at this time). 112 | LMIC_setLinkCheckMode(0); 113 | digitalWrite(LedPin,LOW); 114 | // after Joining a job with the values will be sent. 115 | joined = true; 116 | break; 117 | case EV_RFU1: 118 | Serial.println(F("EV_RFU1")); 119 | break; 120 | case EV_JOIN_FAILED: 121 | Serial.println(F("EV_JOIN_FAILED")); 122 | break; 123 | case EV_REJOIN_FAILED: 124 | Serial.println(F("EV_REJOIN_FAILED")); 125 | // Re-init 126 | os_setCallback(&initjob, initfunc); 127 | break; 128 | case EV_TXCOMPLETE: 129 | sleeping = true; 130 | if (LMIC.dataLen) { 131 | // data received in rx slot after tx 132 | // if any data received, a LED will blink 133 | // this number of times, with a maximum of 10 134 | Serial.print(F("Data Received: ")); 135 | Serial.println(LMIC.frame[LMIC.dataBeg],HEX); 136 | i=(LMIC.frame[LMIC.dataBeg]); 137 | // i (0..255) can be used as data for any other application 138 | // like controlling a relay, showing a display message etc. 139 | if (i>10){ 140 | i=10; // maximum number of BLINKs 141 | } 142 | for(j=0;j 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include "LowPower.h" 38 | 39 | #include 40 | 41 | // DIO Pin mapping is hardware specific. 42 | // The unversioned board needs a wire bridge from pin DIO1 (at the end of the large connector) to D6 (on the smaller connector). 43 | // The v1.2 board needs the solder bridges connected, especially the DIO1 1 bridge. 44 | // Only docs for the unversioned board are available currently. 45 | // See: https://docs.bsfrance.fr/documentation/11355_LORA32U4II/Datasheet_LoRa32u4II_1.1.pdf 46 | // 47 | // Uncomment the define line below if you have a LoRa32u4II without a version number (v1.x) 48 | //#define LoRa32u4II_VERSION LoRa32u4II_1_1 49 | // Uncomment the define line below if you have a LoRa32u4II with version number (v1.2) 50 | //#define LoRa32u4II_VERSION LoRa32u4II_1_2 51 | 52 | #define LoRa32u4II_1_1 11 53 | #define LoRa32u4II_1_2 12 54 | 55 | #if LoRa32u4II_VERSION == LoRa32u4II_1_1 56 | #define DIO0 7 57 | #define DIO1 6 58 | #define DIO2 LMIC_UNUSED_PIN 59 | #define RESET_PIN 1 60 | #elif LoRa32u4II_VERSION == LoRa32u4II_1_2 61 | #define DIO0 0 62 | #define DIO1 1 63 | #define DIO2 2 64 | #define RESET_PIN 4 65 | #else 66 | #define DIO0 0 67 | #define DIO1 0 68 | #define DIO2 0 69 | #define RESET_PIN 0 70 | #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" 71 | #endif 72 | 73 | int sleepcycles = 7; // every sleepcycle will last 8 secs, total sleeptime will be sleepcycles * 8 sec 74 | bool joined = false; 75 | bool sleeping = false; 76 | #define LedPin 22 // pin 13 LED is not used, because it is connected to the SPI port 77 | 78 | // This EUI must be in little-endian format, so least-significant-byte 79 | // first. When copying an EUI from ttnctl output, this means to reverse 80 | // the bytes. For TTN issued EUIs the last bytes should be 0xD5, 0xB3, 81 | // 0x70. 82 | 83 | static const u1_t DEVEUI[8] = { 0x76, 0xA0, 0xA6, 0x01, 0xAC, 0xC2, 0x8B, 0x00 }; 84 | static const u1_t APPEUI[8] = { 0xBD, 0x7C, 0x00, 0xD0, 0x7E, 0xD5, 0xB3, 0x70 }; 85 | 86 | // This key should be in big endian format (or, since it is not really a 87 | // number but a block of memory, endianness does not really apply). In 88 | // practice, a key taken from ttnctl can be copied as-is. 89 | // The key shown here is the semtech default key. 90 | static const u1_t APPKEY[16] = { 0xAE, 0x6A, 0xFA, 0xA3, 0x30, 0x9C, 0xEF, 0xE4, 0xAE, 0x69, 0x2F, 0x63, 0xC3, 0x34, 0x96, 0xF6 }; 91 | 92 | static void initfunc (osjob_t*); 93 | 94 | // provide APPEUI (8 bytes, LSBF) 95 | void os_getArtEui (u1_t* buf) { 96 | memcpy(buf, APPEUI, 8); 97 | } 98 | 99 | // provide DEVEUI (8 bytes, LSBF) 100 | void os_getDevEui (u1_t* buf) { 101 | memcpy(buf, DEVEUI, 8); 102 | } 103 | 104 | // provide APPKEY key (16 bytes) 105 | void os_getDevKey (u1_t* buf) { 106 | memcpy(buf, APPKEY, 16); 107 | } 108 | 109 | static osjob_t sendjob; 110 | static osjob_t initjob; 111 | 112 | const lmic_pinmap lmic_pins = { 113 | .nss = 8, 114 | .rxtx = LMIC_UNUSED_PIN, 115 | .rst = RESET_PIN, // Needed on RFM92/RFM95? (probably not) D0/GPIO16 on v1.1 116 | .dio = {DIO0, DIO1, DIO2}, // Specify pin numbers for DIO0, DIO1, DIO2 117 | }; 118 | 119 | 120 | void onEvent (ev_t ev) { 121 | int i,j; 122 | switch (ev) { 123 | case EV_SCAN_TIMEOUT: 124 | Serial.println(F("EV_SCAN_TIMEOUT")); 125 | break; 126 | case EV_BEACON_FOUND: 127 | Serial.println(F("EV_BEACON_FOUND")); 128 | break; 129 | case EV_BEACON_MISSED: 130 | Serial.println(F("EV_BEACON_MISSED")); 131 | break; 132 | case EV_BEACON_TRACKED: 133 | Serial.println(F("EV_BEACON_TRACKED")); 134 | break; 135 | case EV_JOINING: 136 | Serial.println(F("EV_JOINING")); 137 | break; 138 | case EV_JOINED: 139 | Serial.println(F("EV_JOINED")); 140 | // Disable link check validation (automatically enabled 141 | // during join, but not supported by TTN at this time). 142 | LMIC_setLinkCheckMode(0); 143 | digitalWrite(LedPin,LOW); 144 | // after Joining a job with the values will be sent. 145 | joined = true; 146 | break; 147 | case EV_RFU1: 148 | Serial.println(F("EV_RFU1")); 149 | break; 150 | case EV_JOIN_FAILED: 151 | Serial.println(F("EV_JOIN_FAILED")); 152 | break; 153 | case EV_REJOIN_FAILED: 154 | Serial.println(F("EV_REJOIN_FAILED")); 155 | // Re-init 156 | os_setCallback(&initjob, initfunc); 157 | break; 158 | case EV_TXCOMPLETE: 159 | sleeping = true; 160 | if (LMIC.dataLen) { 161 | // data received in rx slot after tx 162 | // if any data received, a LED will blink 163 | // this number of times, with a maximum of 10 164 | Serial.print(F("Data Received: ")); 165 | Serial.println(LMIC.frame[LMIC.dataBeg],HEX); 166 | i=(LMIC.frame[LMIC.dataBeg]); 167 | // i (0..255) can be used as data for any other application 168 | // like controlling a relay, showing a display message etc. 169 | if (i>10){ 170 | i=10; // maximum number of BLINKs 171 | } 172 | for(j=0;j 2 | 3 | - [Workshop: Build a TTN LoRaWAN Node](#workshop-build-a-ttn-lorawan-node) 4 | - [Hardware](#hardware) 5 | - [Adding the antenna and/or headers](#adding-the-antenna-andor-headers) 6 | - [Connecting DIO1 to D6](#connecting-dio1-to-d6) 7 | - [Software: Getting started](#software-getting-started) 8 | - [Adding the LORA32U4](#adding-the-lora32u4) 9 | - [Selecting the correct board](#selecting-the-correct-board) 10 | - [Get the LMIC library](#get-the-lmic-library) 11 | - [Get the low power library](#get-the-low-power-library) 12 | - [Create a TTN account](#create-a-ttn-account) 13 | - [The Console](#the-console) 14 | - [Creating an application](#creating-an-application) 15 | - [Adding a node](#adding-a-node) 16 | - [Creating the Arduino sketch](#creating-the-arduino-sketch) 17 | - [Check the console for output](#check-the-console-for-output) 18 | 19 | 20 | 21 | # Workshop: Build a TTN LoRaWAN Node 22 | 23 | In this workshop we will use a prebuild LoRaWAN node to be used with The Things Network based on an Arduino Pro Micro and RFM95 module. The node software used is LMIC. 24 | 25 | ## Hardware 26 | 27 | The hardware used for this workshop is the LORA32U4 module. 28 | 29 | ## Adding the antenna and/or headers 30 | 31 | Upon delivery the module has no antenna connected. There are two options, connect an antenna using the u.FL connector on the bottom of the module or solder a wire antenna to the hole marked "ANT'. An wire is included, a u.FL to SMA pigtail and SMA antenna are optional components. 32 | 33 | For breadboard use two rows of headers can added to the module. 34 | 35 | ## Connecting DIO1 to D6 36 | 37 | For the LoRaWAN stack to work two pins on the need to be wired together. Pin DIO1 (at the end of the large connector) needs to be connected to D6 (on the smaller connector). 38 | 39 | # Software: Getting started 40 | 41 | Start by downloading and installing the [Arduino IDE](https://www.arduino.cc/en/Main/Software). Once installed, start the IDE. 42 | 43 | ## Adding the LORA32U4 44 | 45 | The LORA32U4 board has not been developed by Arduino. As a result the boards are not available in a newly installed IDE. To add the boards to the IDE open 'Preferences' from the 'File' menu. 46 | In the 'Additional Boards Manager URL' enter 'https://adafruit.github.io/arduino-board-index/package_adafruit_index.json', Close the dialog with 'OK'. 47 | 48 | ![preferences](images/preferences.png) 49 | 50 | Now go to the 'Tools' menu, item 'Board: "Arduino/Genuino Uno"', this will open a sub menu, select 'Board Manager' from this new menu. 51 | 52 | ![boards](images/board-menu.png) 53 | 54 | In the boards manager, type 'Adafruit' in the dialog to show all SparkFun provided board packages. Click on 'Adafruit AVR Boards' to select the package and click 'Install' to install the board definitions on your system. 55 | 56 | ![boards manager](images/adafruit.png) 57 | 58 | ## Selecting the correct board 59 | 60 | Open the 'Tools' menu and go to the 'Board: "Arduino/Genuino Uno"' again. Now select 'Adafruit Feather 32u4' from the list. 61 | 62 | ![pro micro](images/feather.png) 63 | 64 | ## Get the LMIC library 65 | 66 | The RFM95 is a 'plain' LoRa module. To make the module talk to The Things Network we need to implement the LoRaWAN layer in our code. Luckily we do not need to write the LoRaWAN stack from scratch, there are a number of implementations available on the Internet, LMIC being one of them. 67 | If you search GitHub (or Google) for LMIC you will find numerous versions of the code. The one we will be using is maintained by Matthijs Kooijman. 68 | 69 | 1. Goto [https://github.com/matthijskooijman/arduino-lmic](https://github.com/matthijskooijman/arduino-lmic) 70 | 1. Choose 'Clone or download' 71 | 1. Download ZIP (remember the location you save the file) 72 | 73 | ![download lmic](images/github-lmic.png) 74 | 75 | 4. In the Arduino IDE select 'Sketch', 'Include Library' and select 'Add .ZIP library' in the sub menu. 76 | ![add zip](images/add-zip.png) 77 | 78 | 1. Browse to the file you just downloaded and open it 79 | 1. The green status bar at the bottom of the Arduino IDE should show a message indicating success. 80 | 81 | ![library added](images/library-added.png) 82 | 83 | ## Get the low power library 84 | 85 | 1. Goto [https://github.com/rocketscream/Low-Power](https://github.com/rocketscream/Low-Power) 86 | 1. Choose 'Clone or download' 87 | 1. Download ZIP (again, remember the location you save the file) 88 | 1. In the Arduino IDE select 'Sketch', 'Include Library' and select 'Add .ZIP library' in the sub menu. 89 | 1. Browse to the file you just downloaded and open it 90 | 91 | # Create a TTN account 92 | 93 | If you do not yet have a TTN account (not a forum account) this is the time to create one. Surf to [https://account.thethingsnetwork.org/users/login](https://account.thethingsnetwork.org/users/login) and click on Create an account 94 | 95 | ![account](images/account.png) 96 | 97 | Enter valid information in the form, **read** the "Term and Conditions" and "Privacy Policy" and if you agree with the policies, "Create account". 98 | 99 | ![create account](images/create.png) 100 | 101 | On the next page you will see a message regarding email validation. You will be able to use the account during the workshop, however it will expire at the time and date mentioned if not confirmed before that moment. 102 | 103 | # The Console 104 | 105 | The Things Network Console is where you register you nodes and (if you happen to own any) your gateways. Once you logged into the account server the console can be reached with a link at the top of the page. 106 | 107 | ![console link](images/console-link.png) 108 | 109 | On the console main page choose "Applications" because for TTN nodes are assigned to applications. 110 | 111 | ![console](images/console.png) 112 | 113 | ## Creating an application 114 | 115 | Because nodes are part of an application the first thing to do is to create an application. On the application page click on "add application". 116 | 117 | On the "add application" screen you will need to enter a number of values: 118 | 119 | - Application ID : this needs to be a globally unique application identifier which can be seen by other users of the network. Do not use 'sensitive' information as it is not a secret! 120 | - Description : any description that allows you to recognize the application. 121 | - Application EUI : leave empty, the value will be generated. 122 | - Handler registration : use 'ttn-handler-eu'. 123 | 124 | ![add application](images/add-application.png) 125 | 126 | Click on the "Add Application" button to create the application. 127 | 128 | If you enter an application ID that is already in use an error will appear when you try to add it. 129 | 130 | ![not unique](images/not-unique.png) 131 | 132 | In that case choose a different ID and try again. 133 | 134 | ## Adding a node 135 | 136 | Now we have the application we can register our node. On the application page scroll down to "DEVICES" and click on "register device" on the right hand side. 137 | 138 | ![add device](images/add-device.png) 139 | 140 | On the newly opened form enter the required information: 141 | 142 | - Device ID : unique identifier to allow you to easily recognize the device. 143 | - Device EUI : click on the interlinked arrows at the start of the field to change it to a pencil, now a unique EUI will be generated for us. 144 | - App Key : leave blank, this will be generated as well. 145 | 146 | ![register node](images/register-device.png) 147 | 148 | Keep this page open, we will need some of the information during the next steps. 149 | 150 | # Creating the Arduino sketch 151 | 152 | Everything is now in place to start coding our first Arduino sketch to connect our hardware to TTN. 153 | 154 | Download the sample sketch from [https://raw.githubusercontent.com/kersing/node-workshop/master/lora32u4-sketch/lora32u4-sketch.ino](https://raw.githubusercontent.com/kersing/node-workshop/master/lora32u4-sketch/lora32u4-sketch.ino) or cut-and-paste the code below: 155 | ``` 156 | /******************************************************************************* 157 | * Copyright (c) 2015 Thomas Telkamp and Matthijs Kooijman 158 | * 159 | * Permission is hereby granted, free of charge, to anyone 160 | * obtaining a copy of this document and accompanying files, 161 | * to do whatever they want with them without any restriction, 162 | * including, but not limited to, copying, modification and redistribution. 163 | * NO WARRANTY OF ANY KIND IS PROVIDED. 164 | * 165 | * This example will send Temperature and Humidity 166 | * using frequency and encryption settings matching those of 167 | * the The Things Network. Application will 'sleep' 7x8 seconds (56 seconds) 168 | * 169 | * This uses OTAA (Over-the-air activation), where where a DevEUI and 170 | * application key is configured, which are used in an over-the-air 171 | * activation procedure where a DevAddr and session keys are 172 | * assigned/generated for use with all further communication. 173 | * 174 | * Note: LoRaWAN per sub-band duty-cycle limitation is enforced (1% in 175 | * g1, 0.1% in g2), but not the TTN fair usage policy (which is probably 176 | * violated by this sketch when left running for longer)! 177 | 178 | * To use this sketch, first register your application and device with 179 | * the things network, to set or generate an AppEUI, DevEUI and AppKey. 180 | * Multiple devices can use the same AppEUI, but each device has its own 181 | * DevEUI and AppKey. 182 | * 183 | * Do not forget to define the radio type correctly in config.h. 184 | * 185 | *******************************************************************************/ 186 | 187 | #include 188 | #include 189 | #include 190 | #include 191 | #include 192 | #include "LowPower.h" 193 | 194 | #include 195 | 196 | int sleepcycles = 7; // every sleepcycle will last 8 secs, total sleeptime will be sleepcycles * 8 sec 197 | bool joined = false; 198 | bool sleeping = false; 199 | #define LedPin 22 // pin 13 LED is not used, because it is connected to the SPI port 200 | 201 | // This EUI must be in little-endian format, so least-significant-byte 202 | // first. When copying an EUI from ttnctl output, this means to reverse 203 | // the bytes. For TTN issued EUIs the last bytes should be 0xD5, 0xB3, 204 | // 0x70. 205 | 206 | static const u1_t DEVEUI[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; 207 | static const u1_t APPEUI[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; 208 | 209 | // This key should be in big endian format (or, since it is not really a 210 | // number but a block of memory, endianness does not really apply). In 211 | // practice, a key taken from ttnctl can be copied as-is. 212 | // The key shown here is the semtech default key. 213 | static const u1_t APPKEY[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; 214 | 215 | static void initfunc (osjob_t*); 216 | 217 | // provide APPEUI (8 bytes, LSBF) 218 | void os_getArtEui (u1_t* buf) { 219 | memcpy(buf, APPEUI, 8); 220 | } 221 | 222 | // provide DEVEUI (8 bytes, LSBF) 223 | void os_getDevEui (u1_t* buf) { 224 | memcpy(buf, DEVEUI, 8); 225 | } 226 | 227 | // provide APPKEY key (16 bytes) 228 | void os_getDevKey (u1_t* buf) { 229 | memcpy(buf, APPKEY, 16); 230 | } 231 | 232 | static osjob_t sendjob; 233 | static osjob_t initjob; 234 | 235 | // Pin mapping is hardware specific. 236 | // Pin mapping 237 | const lmic_pinmap lmic_pins = { 238 | .nss = 8, 239 | .rxtx = LMIC_UNUSED_PIN, 240 | .rst = 1, // Needed on RFM92/RFM95? (probably not) D0/GPIO16 241 | .dio = {7, 6, LMIC_UNUSED_PIN}, // Specify pin numbers for DIO0, 1, 2 242 | // connected to D7, D6, - 243 | }; 244 | 245 | 246 | void onEvent (ev_t ev) { 247 | int i,j; 248 | switch (ev) { 249 | case EV_SCAN_TIMEOUT: 250 | Serial.println(F("EV_SCAN_TIMEOUT")); 251 | break; 252 | case EV_BEACON_FOUND: 253 | Serial.println(F("EV_BEACON_FOUND")); 254 | break; 255 | case EV_BEACON_MISSED: 256 | Serial.println(F("EV_BEACON_MISSED")); 257 | break; 258 | case EV_BEACON_TRACKED: 259 | Serial.println(F("EV_BEACON_TRACKED")); 260 | break; 261 | case EV_JOINING: 262 | Serial.println(F("EV_JOINING")); 263 | break; 264 | case EV_JOINED: 265 | Serial.println(F("EV_JOINED")); 266 | // Disable link check validation (automatically enabled 267 | // during join, but not supported by TTN at this time). 268 | LMIC_setLinkCheckMode(0); 269 | digitalWrite(LedPin,LOW); 270 | // after Joining a job with the values will be sent. 271 | joined = true; 272 | break; 273 | case EV_RFU1: 274 | Serial.println(F("EV_RFU1")); 275 | break; 276 | case EV_JOIN_FAILED: 277 | Serial.println(F("EV_JOIN_FAILED")); 278 | break; 279 | case EV_REJOIN_FAILED: 280 | Serial.println(F("EV_REJOIN_FAILED")); 281 | // Re-init 282 | os_setCallback(&initjob, initfunc); 283 | break; 284 | case EV_TXCOMPLETE: 285 | sleeping = true; 286 | if (LMIC.dataLen) { 287 | // data received in rx slot after tx 288 | // if any data received, a LED will blink 289 | // this number of times, with a maximum of 10 290 | Serial.print(F("Data Received: ")); 291 | Serial.println(LMIC.frame[LMIC.dataBeg],HEX); 292 | i=(LMIC.frame[LMIC.dataBeg]); 293 | // i (0..255) can be used as data for any other application 294 | // like controlling a relay, showing a display message etc. 295 | if (i>10){ 296 | i=10; // maximum number of BLINKs 297 | } 298 | for(j=0;j' and one with two arrows. For all three values press the '<>' icon to show the values C-style (with '{' and 0x), for DEVEUI and APPEUI hit the arrow icon once to change to LSB setting. 407 | 408 | ![device settings](images/device-settings.png) 409 | 410 | Now copy the three values to your sketch. Use the 'notepad' icon at the end of the value to copy the value to the clipboard. 411 | 412 | Save the result and compile the sketch by hitting the check mark icon below 'File'. If no error are shown connect your node to your system using an USB mini cable. A red LED should light indicating the module is powered. 413 | 414 | Wait a few seconds for the system to install the appropriate USB drivers. Next go to 'Tool', 'Port' in the Arduino IDE and select the port your LORA32U4 is connected to. 415 | 416 | ![select port](images/feather-port.png) 417 | 418 | Now send the sketch to the board using the arrow icon below 'Edit'. Once the upload is finished open the 'Serial monitor' from the 'Tools' menu. After a few seconds output should start to appear in the monitor. 419 | 420 | ![serial port monitor](images/serial-monitor.png) 421 | 422 | ## Check the console for output 423 | 424 | In the web browser with the TTN console switch to the 'Data' tab. Data should start to appear on this page once the node is up and running. 425 | 426 | ![data](images/data.png) 427 | 428 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | - [Workshop: Build a TTN LoRaWAN Node](#workshop-build-a-ttn-lorawan-node) 4 | - [Component list](#component-list) 5 | - [Hardware: Getting started](#hardware-getting-started) 6 | - [Mounting the RFM95](#mounting-the-rfm95) 7 | - [Mounting the Arduino Pro Micro](#mounting-the-arduino-pro-micro) 8 | - [Mount the antenna](#mount-the-antenna) 9 | - [Option 1: SMA](#option-1-sma) 10 | - [Option 2: Wire antenna](#option-2-wire-antenna) 11 | - [The Finished Node](#the-finished-node) 12 | - [Software: Getting started](#software-getting-started) 13 | - [Adding the Arduino Pro Micro](#adding-the-arduino-pro-micro) 14 | - [Selecting the correct board](#selecting-the-correct-board) 15 | - [Get the LMIC library](#get-the-lmic-library) 16 | - [Get the low power library](#get-the-low-power-library) 17 | - [Create a TTN account](#create-a-ttn-account) 18 | - [The Console](#the-console) 19 | - [Creating an application](#creating-an-application) 20 | - [Adding a node](#adding-a-node) 21 | - [Creating the Arduino sketch](#creating-the-arduino-sketch) 22 | - [Check the console for output](#check-the-console-for-output) 23 | - [Low power operation](#low-power-operation) 24 | 25 | 26 | 27 | # Workshop: Build a TTN LoRaWAN Node 28 | 29 | In this workshop we will build a LoRaWAN node to be used with The Things Network based on an Arduino Pro Micro and RFM95 module. The node software used is LMIC. 30 | 31 | ![component picture](images/components.jpg) 32 | 33 | ## Component list 34 | 35 | 1. Arduino Pro Micro 3.3V/8MHz. N.B. 5V/16MHz will not work and damage the other components. 36 | 1. RFM Module RFM95. 37 | 1. PCB 'DougLarue'. 38 | 1. Copper coil antenna (alternative 2dBi SMA antenna and SMA connector at additional cost). 39 | 1. 1 LED. 40 | 41 | # Hardware: Getting started 42 | 43 | The first steps will be assembling the components by soldering the RFM95 module and Arduino Pro Micro onto the PCB. 44 | 45 | ## Mounting the RFM95 46 | 47 | Position the RFM95 module on the PCB as shown in the picture below. 48 | 49 | ![rfm95 placement](images/rfm95-placement.jpg) 50 | 51 | Solder it to the PCB. The easiest way to do this is to solder one corner (make sure to position the module correctly!), next solder the opposite corner to fix the module and finish by soldering the other contacts. 52 | 53 | ## Mounting the Arduino Pro Micro 54 | 55 | First solder the two 12 pin headers to the Arduino Micro Pro module. Use the short metal side of the connector for the Arduino. Next plug the Arduino Pro Micro with connectors into the 'ProMini' footprint. 56 | 57 | NOTE: We will not be using the two pin connector inside the right (as shown on the pictures) connector, this is for Arduino Pro Mini only to bring out the I2C pins. The I2C pins for the Arduino Pro Micro are available on D2 (SDA) and pin D3 (SCL). If you want to use the I2C connector at the edge of the PCB you can connect a wire (on the reverse side of the PCB from D2 and D3 to the two holes, make sure to cross the wires so wire D2 which is the top pin to the bottom hole and vice versa.) Keep in mind any connector at that location will adversely affect a wire/coil antenna mounted next to it! 58 | 59 | ![pro placement](images/pro-placement.jpg) 60 | 61 | ## Mount the antenna 62 | 63 | Included in the kit is a coil antenna. This antenna will work for short distances. There are two options for better antenna 64 | 65 | 1. Mount a SMA connector and use it to mount a 'stick' antenna. 66 | 1. Use a wire antenna. 67 | 68 | ### Option 1: SMA 69 | 70 | Mounting the SMA antenna using a SMA edge connector should not pose any challenges, slide it onto the three strips next to the RFM95 module with the center pin on top of the PCB. Keep in mind the SMA connector will get **very** hot when soldering it! 71 | 72 | ### Option 2: Wire antenna 73 | 74 | A wire antenna is lowest cost solution which works surprisingly well. To create one, cut a piece of wire at about 10cm. Now strip about 5mm, tin it (for stranded wire) and solder it to the PCB using the hole next to the three strips at the PCB edge next to the RFM95 module. 75 | Now trim the wire above the PCB to 82.2mm. 76 | 77 | ## The Finished Node 78 | 79 | The picture below shows the finished node. 80 | 81 | ![finished node](images/finished.jpg) 82 | 83 | Additional headers can be mounted at the remaining footprints as required. See the note at 'Mounting the Arduino Pro Micro' concerning the I2C header. 84 | 85 | # Software: Getting started 86 | 87 | Start by downloading and installing the [Arduino IDE](https://www.arduino.cc/en/Main/Software). Once installed, start the IDE. 88 | 89 | ## Adding the Arduino Pro Micro 90 | 91 | The Pro Micro boards have not been developed by Arduino. As a result the boards are not available in a newly installed IDE. To add the boards to the IDE open 'Preferences' from the 'File' menu. 92 | In the 'Additional Boards Manager URL' enter 'https://raw.githubusercontent.com/sparkfun/Arduino_Boards/master/IDE_Board_Manager/package_sparkfun_index.json', Close the dialog with 'OK'. 93 | 94 | ![preferences](images/preferences.png) 95 | 96 | Now go to the 'Tools' menu, item 'Board: "Arduino/Genuino Uno"', this will open a sub menu, select 'Board Manager' from this new menu. 97 | 98 | ![boards](images/board-menu.png) 99 | 100 | In the boards manager, type 'sparkfun' in the dialog to show all SparkFun provided board packages. Click on 'SparkFun AVR Boards' to select the package and click 'Install' to install the board definitions on your system. 101 | 102 | ![boards manager](images/sparkfun.png) 103 | 104 | ## Selecting the correct board 105 | 106 | Open the 'Tools' menu and go to the 'Board: "Arduino/Genuino Uno"' again. Now select 'SparkFun Pro Micro' from the list. 107 | 108 | ![pro micro](images/pro-micro.png) 109 | 110 | **NOTE:** the next step is **very** important. Not selecting the correct processor will disable the USB boot loader making it impossible to update the code after the first upload. 111 | Open the 'Tools' menu again, at 'Processor' select "ATmega32u4 (3.3V, 8MHz)." 112 | 113 | ![pro micro 3.3v](images/pro-micro-3v3.png) 114 | 115 | **NOTE: MAKE SURE you have selected the correct board!!** 116 | 117 | ## Get the LMIC library 118 | 119 | The RFM95 is a 'plain' LoRa module. To make the module talk to The Things Network we need to implement the LoRaWAN layer in our code. Luckily we do not need to write the LoRaWAN stack from scratch, there are a number of implementations available on the Internet, LMIC being one of them. 120 | If you search GitHub (or Google) for LMIC you will find numerous versions of the code. The one we will be using is maintained by Matthijs Kooijman. 121 | 122 | 1. Goto [https://github.com/matthijskooijman/arduino-lmic](https://github.com/matthijskooijman/arduino-lmic) 123 | 1. Choose 'Clone or download' 124 | 1. Download ZIP (remember the location you save the file) 125 | 126 | ![download lmic](images/github-lmic.png) 127 | 128 | 4. In the Arduino IDE select 'Sketch', 'Include Library' and select 'Add .ZIP library' in the sub menu. 129 | ![add zip](images/add-zip.png) 130 | 131 | 1. Browse to the file you just downloaded and open it 132 | 1. The green status bar at the bottom of the Arduino IDE should show a message indicating success. 133 | 134 | ![library added](images/library-added.png) 135 | 136 | ## Get the low power library 137 | 138 | 1. Goto [https://github.com/rocketscream/Low-Power](https://github.com/rocketscream/Low-Power) 139 | 1. Choose 'Clone or download' 140 | 1. Download ZIP (again, remember the location you save the file) 141 | 1. In the Arduino IDE select 'Sketch', 'Include Library' and select 'Add .ZIP library' in the sub menu. 142 | 1. Browse to the file you just downloaded and open it 143 | 144 | # Create a TTN account 145 | 146 | If you do not yet have a TTN account (not a forum account) this is the time to create one. Surf to [https://account.thethingsnetwork.org/users/login](https://account.thethingsnetwork.org/users/login) and click on Create an account 147 | 148 | ![account](images/account.png) 149 | 150 | Enter valid information in the form, **read** the "Term and Conditions" and "Privacy Policy" and if you agree with the policies, "Create account". 151 | 152 | ![create account](images/create.png) 153 | 154 | On the next page you will see a message regarding email validation. You will be able to use the account during the workshop, however it will expire at the time and date mentioned if not confirmed before that moment. 155 | 156 | # The Console 157 | 158 | The Things Network Console is where you register you nodes and (if you happen to own any) your gateways. Once you logged into the account server the console can be reached with a link at the top of the page. 159 | 160 | ![console link](images/console-link.png) 161 | 162 | On the console main page choose "Applications" because for TTN nodes are assigned to applications. 163 | 164 | ![console](images/console.png) 165 | 166 | ## Creating an application 167 | 168 | Because nodes are part of an application the first thing to do is to create an application. On the application page click on "add application". 169 | 170 | On the "add application" screen you will need to enter a number of values: 171 | 172 | - Application ID : this needs to be a globally unique application identifier which can be seen by other users of the network. Do not use 'sensitive' information as it is not a secret! 173 | - Description : any description that allows you to recognize the application. 174 | - Application EUI : leave empty, the value will be generated. 175 | - Handler registration : use 'ttn-handler-eu'. 176 | 177 | ![add application](images/add-application.png) 178 | 179 | Click on the "Add Application" button to create the application. 180 | 181 | If you enter an application ID that is already in use an error will appear when you try to add it. 182 | 183 | ![not unique](images/not-unique.png) 184 | 185 | In that case choose a different ID and try again. 186 | 187 | ## Adding a node 188 | 189 | Now we have the application we can register our node. On the application page scroll down to "DEVICES" and click on "register device" on the right hand side. 190 | 191 | ![add device](images/add-device.png) 192 | 193 | On the newly opened form enter the required information: 194 | 195 | - Device ID : unique identifier to allow you to easily recognize the device. 196 | - Device EUI : click on the interlinked arrows at the start of the field to change it to a pencil, now a unique EUI will be generated for us. 197 | - App Key : leave blank, this will be generated as well. 198 | 199 | ![register node](images/register-device.png) 200 | 201 | Keep this page open, we will need some of the information during the next steps. 202 | 203 | # Creating the Arduino sketch 204 | 205 | Everything is now in place to start coding our first Arduino sketch to connect our hardware to TTN. 206 | 207 | Download the sample sketch from [https://raw.githubusercontent.com/kersing/node-workshop/master/pro-micro-sketch/pro-micro-sketch.ino](https://raw.githubusercontent.com/kersing/node-workshop/master/pro-micro-sketch/pro-micro-sketch.ino) or cut-and-paste the code below: 208 | ``` 209 | /******************************************************************************* 210 | * Copyright (c) 2015 Thomas Telkamp and Matthijs Kooijman 211 | * 212 | * Permission is hereby granted, free of charge, to anyone 213 | * obtaining a copy of this document and accompanying files, 214 | * to do whatever they want with them without any restriction, 215 | * including, but not limited to, copying, modification and redistribution. 216 | * NO WARRANTY OF ANY KIND IS PROVIDED. 217 | * 218 | * This example will send Temperature and Humidity 219 | * using frequency and encryption settings matching those of 220 | * the The Things Network. Application will 'sleep' 7x8 seconds (56 seconds) 221 | * 222 | * This uses OTAA (Over-the-air activation), where where a DevEUI and 223 | * application key is configured, which are used in an over-the-air 224 | * activation procedure where a DevAddr and session keys are 225 | * assigned/generated for use with all further communication. 226 | * 227 | * Note: LoRaWAN per sub-band duty-cycle limitation is enforced (1% in 228 | * g1, 0.1% in g2), but not the TTN fair usage policy (which is probably 229 | * violated by this sketch when left running for longer)! 230 | 231 | * To use this sketch, first register your application and device with 232 | * the things network, to set or generate an AppEUI, DevEUI and AppKey. 233 | * Multiple devices can use the same AppEUI, but each device has its own 234 | * DevEUI and AppKey. 235 | * 236 | * Do not forget to define the radio type correctly in config.h. 237 | * 238 | *******************************************************************************/ 239 | 240 | #include 241 | #include 242 | #include 243 | #include 244 | #include 245 | #include "LowPower.h" 246 | 247 | #include 248 | 249 | int sleepcycles = 7; // every sleepcycle will last 8 secs, total sleeptime will be sleepcycles * 8 sec 250 | bool joined = false; 251 | bool sleeping = false; 252 | #define LedPin 22 // pin 13 LED is not used, because it is connected to the SPI port 253 | 254 | // This EUI must be in little-endian format, so least-significant-byte 255 | // first. When copying an EUI from ttnctl output, this means to reverse 256 | // the bytes. For TTN issued EUIs the last bytes should be 0xD5, 0xB3, 257 | // 0x70. 258 | 259 | static const u1_t DEVEUI[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; 260 | static const u1_t APPEUI[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; 261 | 262 | // This key should be in big endian format (or, since it is not really a 263 | // number but a block of memory, endianness does not really apply). In 264 | // practice, a key taken from ttnctl can be copied as-is. 265 | // The key shown here is the semtech default key. 266 | static const u1_t APPKEY[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; 267 | 268 | static void initfunc (osjob_t*); 269 | 270 | // provide APPEUI (8 bytes, LSBF) 271 | void os_getArtEui (u1_t* buf) { 272 | memcpy(buf, APPEUI, 8); 273 | } 274 | 275 | // provide DEVEUI (8 bytes, LSBF) 276 | void os_getDevEui (u1_t* buf) { 277 | memcpy(buf, DEVEUI, 8); 278 | } 279 | 280 | // provide APPKEY key (16 bytes) 281 | void os_getDevKey (u1_t* buf) { 282 | memcpy(buf, APPKEY, 16); 283 | } 284 | 285 | static osjob_t sendjob; 286 | static osjob_t initjob; 287 | 288 | // Pin mapping is hardware specific. 289 | // Pin mapping 290 | const lmic_pinmap lmic_pins = { 291 | .nss = 10, //8, 292 | .rxtx = LMIC_UNUSED_PIN, 293 | .rst = 0, //9, 294 | .dio = {4, 5, 7},//{2,5, LMIC_UNUSED_PIN}, //DIO0 and DIO1 connected 295 | }; 296 | 297 | 298 | void onEvent (ev_t ev) { 299 | int i,j; 300 | switch (ev) { 301 | case EV_SCAN_TIMEOUT: 302 | Serial.println(F("EV_SCAN_TIMEOUT")); 303 | break; 304 | case EV_BEACON_FOUND: 305 | Serial.println(F("EV_BEACON_FOUND")); 306 | break; 307 | case EV_BEACON_MISSED: 308 | Serial.println(F("EV_BEACON_MISSED")); 309 | break; 310 | case EV_BEACON_TRACKED: 311 | Serial.println(F("EV_BEACON_TRACKED")); 312 | break; 313 | case EV_JOINING: 314 | Serial.println(F("EV_JOINING")); 315 | break; 316 | case EV_JOINED: 317 | Serial.println(F("EV_JOINED")); 318 | // Disable link check validation (automatically enabled 319 | // during join, but not supported by TTN at this time). 320 | LMIC_setLinkCheckMode(0); 321 | digitalWrite(LedPin,LOW); 322 | // after Joining a job with the values will be sent. 323 | joined = true; 324 | break; 325 | case EV_RFU1: 326 | Serial.println(F("EV_RFU1")); 327 | break; 328 | case EV_JOIN_FAILED: 329 | Serial.println(F("EV_JOIN_FAILED")); 330 | break; 331 | case EV_REJOIN_FAILED: 332 | Serial.println(F("EV_REJOIN_FAILED")); 333 | // Re-init 334 | os_setCallback(&initjob, initfunc); 335 | break; 336 | case EV_TXCOMPLETE: 337 | sleeping = true; 338 | if (LMIC.dataLen) { 339 | // data received in rx slot after tx 340 | // if any data received, a LED will blink 341 | // this number of times, with a maximum of 10 342 | Serial.print(F("Data Received: ")); 343 | Serial.println(LMIC.frame[LMIC.dataBeg],HEX); 344 | i=(LMIC.frame[LMIC.dataBeg]); 345 | // i (0..255) can be used as data for any other application 346 | // like controlling a relay, showing a display message etc. 347 | if (i>10){ 348 | i=10; // maximum number of BLINKs 349 | } 350 | for(j=0;j' and one with two arrows. For all three values press the '<>' icon to show the values C-style (with '{' and 0x), for DEVEUI and APPEUI hit the arrow icon once to change to LSB setting. 459 | 460 | ![device settings](images/device-settings.png) 461 | 462 | Now copy the three values to your sketch. Use the 'notepad' icon at the end of the value to copy the value to the clipboard. 463 | 464 | Save the result and compile the sketch by hitting the check mark icon below 'File'. If no error are shown connect your node to your system using an USB mini cable. A red LED should light indicating the module is powered. 465 | 466 | Wait a few seconds for the system to install the appropriate USB drivers. Next go to 'Tool', 'Port' in the Arduino IDE and select the port your Pro Micro is connected to. 467 | 468 | ![select port](images/port.png) 469 | 470 | **NOTE:** At this point you should double check the Board and Processor settings are (still) correct. Board should be 'SparkFun Pro Micro' and processor 'ATmega32U4 (3.3V, 8MHz)'. Correct the values if required! 471 | 472 | Now send the sketch to the board using the arrow icon below 'Edit'. Once the upload is finished open the 'Serial monitor' from the 'Tools' menu. After a few seconds output should start to appear in the monitor. 473 | 474 | ![serial port monitor](images/serial-monitor.png) 475 | 476 | ## Check the console for output 477 | 478 | In the web browser with the TTN console switch to the 'Data' tab. Data should start to appear on this page once the node is up and running. 479 | 480 | ![data](images/data.png) 481 | 482 | # Low power operation 483 | 484 | To reduce the amount of power used by the node you want to disable all LEDs as these use a relatively large amount of power. This means disabling/removing the power led on the Pro Mini module. Only attempt this if you are very comfortable with removal of SMD parts as it might damage the module beyond repair. --------------------------------------------------------------------------------