LoRaWAN smart agriculture application using FRDM-K64F ARM mbed board along with SX1272MB2xAS LoRa shield as the LoRa Node.
Dependencies: DHT11 LMiC SX1272Lib mbed
Fork of LoRaWAN-lmic-app by
main.cpp@11:dc6e995a7849, 2018-04-11 (annotated)
- Committer:
- GTsapparellas
- Date:
- Wed Apr 11 19:52:17 2018 +0000
- Revision:
- 11:dc6e995a7849
- Parent:
- 10:0a4ad1388e05
version 1.0 (Commenting)
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
GTsapparellas | 6:3758685f4b75 | 1 | /******************************************************************************* |
GTsapparellas | 6:3758685f4b75 | 2 | * Internet of Things (IoT) smart monitoring |
GTsapparellas | 6:3758685f4b75 | 3 | * device for agriculture using LoRaWAN technology. |
GTsapparellas | 6:3758685f4b75 | 4 | * |
GTsapparellas | 6:3758685f4b75 | 5 | * LoRa Gateway: Single-channel Dragino LG01-P LoRa Gateway |
GTsapparellas | 6:3758685f4b75 | 6 | * |
GTsapparellas | 6:3758685f4b75 | 7 | * Measurement parameters: Temperature (Celcius) |
GTsapparellas | 6:3758685f4b75 | 8 | * Humidity (Relative Humidity %) |
GTsapparellas | 6:3758685f4b75 | 9 | * Light Intenisty (Volts) |
GTsapparellas | 6:3758685f4b75 | 10 | * Soil Moisture (Volts) |
GTsapparellas | 6:3758685f4b75 | 11 | * |
GTsapparellas | 6:3758685f4b75 | 12 | * Evaluation board: FRDM-K64F ARM mbed board |
GTsapparellas | 6:3758685f4b75 | 13 | * |
GTsapparellas | 6:3758685f4b75 | 14 | * LoRa shield: Semtech SX1272MB2xAS |
GTsapparellas | 6:3758685f4b75 | 15 | * |
GTsapparellas | 6:3758685f4b75 | 16 | * IoT Cloud Server: The Things Network (Europe EU-868.1 frequency band) |
GTsapparellas | 6:3758685f4b75 | 17 | * |
GTsapparellas | 6:3758685f4b75 | 18 | * API Platform: All Things Talk Maker |
GTsapparellas | 6:3758685f4b75 | 19 | * |
GTsapparellas | 6:3758685f4b75 | 20 | * - Time-triggered program periodically sends playload data (including |
GTsapparellas | 6:3758685f4b75 | 21 | * temperature, humidity, light intensity and soil moisture sensor parameters) |
GTsapparellas | 6:3758685f4b75 | 22 | * by using FRDM-K64F ARM mbed board and Semtech SX1272MB2xAS as the LoRa Node. |
GTsapparellas | 6:3758685f4b75 | 23 | * |
GTsapparellas | 6:3758685f4b75 | 24 | * - DHT library and Digital Input pin used for the successful measurement |
GTsapparellas | 6:3758685f4b75 | 25 | * of temperature and humidity sensor parameters. |
GTsapparellas | 6:3758685f4b75 | 26 | * |
GTsapparellas | 6:3758685f4b75 | 27 | * - Analog Input pins used for the successful employement of soil moisture and |
GTsapparellas | 6:3758685f4b75 | 28 | * light intensity sensor parameters. |
GTsapparellas | 6:3758685f4b75 | 29 | * |
GTsapparellas | 6:3758685f4b75 | 30 | * - Semtech's SX1272Lib used for the successful configuration and set up of |
GTsapparellas | 6:3758685f4b75 | 31 | * of SX1272MB2xAS LoRa shield. |
GTsapparellas | 6:3758685f4b75 | 32 | * |
GTsapparellas | 6:3758685f4b75 | 33 | * - IBM's LMiC library used for the successful implementation of LoRa modulation. |
GTsapparellas | 6:3758685f4b75 | 34 | * |
GTsapparellas | 6:3758685f4b75 | 35 | * - LoRa Node transmitting playload data directly to the single-channel Dragino |
GTsapparellas | 6:3758685f4b75 | 36 | * LG01-P LoRa Gateway which is connected to The Things Network Cloud Server. |
GTsapparellas | 6:3758685f4b75 | 37 | * |
GTsapparellas | 6:3758685f4b75 | 38 | * - ABP (Activation By Personalization) selected as the activation method over |
GTsapparellas | 6:3758685f4b75 | 39 | * The Things Network Cloud Server. |
GTsapparellas | 6:3758685f4b75 | 40 | * |
GTsapparellas | 6:3758685f4b75 | 41 | * - The Things Network Cloud Server makes playload data available online. |
GTsapparellas | 6:3758685f4b75 | 42 | * |
GTsapparellas | 6:3758685f4b75 | 43 | * - Through required integration, The Things Network Cloud Server passes |
GTsapparellas | 6:3758685f4b75 | 44 | * playload data to All Things Talk Maker API which visualizes the data in |
GTsapparellas | 7:8ffc2f64b0f8 | 45 | * a meaningful way for end-user's reference. |
GTsapparellas | 7:8ffc2f64b0f8 | 46 | * |
GTsapparellas | 7:8ffc2f64b0f8 | 47 | * - Fully reset device through RESET BUTTON pressed. |
GTsapparellas | 6:3758685f4b75 | 48 | * |
GTsapparellas | 6:3758685f4b75 | 49 | * @Author: Giorgos Tsapparellas |
GTsapparellas | 10:0a4ad1388e05 | 50 | * @Date: 25th February 2018 |
GTsapparellas | 6:3758685f4b75 | 51 | * |
GTsapparellas | 9:f3e9b3a6eded | 52 | * Code available at: 1) https://os.mbed.com/users/GTsapparellas/code/LoRaWAN_mbed_lmic_agriculture_app/ |
GTsapparellas | 9:f3e9b3a6eded | 53 | * 2) https://github.com/GTsapparellas/LoRaWAN_mbed_lmic_agriculture_app |
GTsapparellas | 6:3758685f4b75 | 54 | * |
GTsapparellas | 7:8ffc2f64b0f8 | 55 | * SEE readME.txt file for instructions of how to compile and run the program. |
GTsapparellas | 6:3758685f4b75 | 56 | * |
GTsapparellas | 6:3758685f4b75 | 57 | *******************************************************************************/ |
mluis | 1:60184eda0066 | 58 | |
GTsapparellas | 6:3758685f4b75 | 59 | #include <mbed.h> |
GTsapparellas | 6:3758685f4b75 | 60 | #include <lmic.h> |
GTsapparellas | 6:3758685f4b75 | 61 | #include <hal.h> |
GTsapparellas | 6:3758685f4b75 | 62 | #include <SPI.h> |
GTsapparellas | 6:3758685f4b75 | 63 | #include <DHT.h> |
GTsapparellas | 6:3758685f4b75 | 64 | #include <debug.h> |
mluis | 0:a2929fa6e4f0 | 65 | |
GTsapparellas | 6:3758685f4b75 | 66 | /////////////////////////////////////////////////// |
GTsapparellas | 6:3758685f4b75 | 67 | // DEFINITION DECLARATIONS // |
GTsapparellas | 6:3758685f4b75 | 68 | ///////////////////////////////////////////////// |
GTsapparellas | 6:3758685f4b75 | 69 | |
GTsapparellas | 7:8ffc2f64b0f8 | 70 | #define MAX_EU_CHANNELS 16 // Frequency channels automatically initialized for EU reqion. |
GTsapparellas | 6:3758685f4b75 | 71 | #define SINGLE_CHANNEL_GATEWAY // Force it to use 868.1 MHz frequency band only due to Dragino LG01-P LoRa Gateway hardware limitation. |
GTsapparellas | 11:dc6e995a7849 | 72 | #define TRANSMIT_INTERVAL 300 // Transmit interval in seconds, too often may get traffic ignored. |
GTsapparellas | 6:3758685f4b75 | 73 | #define DEBUG_LEVEL 0 // Set debug level to 1 for outputting messages to the UART Terminal (e.g. Tera Term). |
GTsapparellas | 6:3758685f4b75 | 74 | #define ACTIVATION_METHOD 0 // Set activation method to 0 for ABP (Activation By Personalization) |
GTsapparellas | 6:3758685f4b75 | 75 | // Set activation method to 1 for OTAA (Over The Air Activation) |
mluis | 0:a2929fa6e4f0 | 76 | |
GTsapparellas | 6:3758685f4b75 | 77 | /////////////////////////////////////////////////// |
GTsapparellas | 6:3758685f4b75 | 78 | // GLOBAL VARIABLES DECLARATIONS // |
GTsapparellas | 6:3758685f4b75 | 79 | ///////////////////////////////////////////////// |
GTsapparellas | 6:3758685f4b75 | 80 | |
GTsapparellas | 6:3758685f4b75 | 81 | // Transmit interval in seconds. |
GTsapparellas | 6:3758685f4b75 | 82 | uint16_t transmit_interval = TRANSMIT_INTERVAL; |
mluis | 1:60184eda0066 | 83 | |
GTsapparellas | 7:8ffc2f64b0f8 | 84 | // Static osjob_t sendjob variable used by loop function |
GTsapparellas | 7:8ffc2f64b0f8 | 85 | static osjob_t sendjob; |
GTsapparellas | 7:8ffc2f64b0f8 | 86 | |
GTsapparellas | 7:8ffc2f64b0f8 | 87 | // Unsigned integer packet counter used by transmit function. |
GTsapparellas | 7:8ffc2f64b0f8 | 88 | unsigned int packetCounter = 1; |
GTsapparellas | 7:8ffc2f64b0f8 | 89 | |
GTsapparellas | 7:8ffc2f64b0f8 | 90 | // Disable data rate adaption. |
GTsapparellas | 7:8ffc2f64b0f8 | 91 | // Set to 1 in order to enable data rate adaption. |
GTsapparellas | 7:8ffc2f64b0f8 | 92 | static const bit_t disableAdrMode = 0; |
GTsapparellas | 7:8ffc2f64b0f8 | 93 | |
GTsapparellas | 7:8ffc2f64b0f8 | 94 | // Disable link check validadtion. |
GTsapparellas | 7:8ffc2f64b0f8 | 95 | // Set to 1 in order to enable link check validation. |
GTsapparellas | 7:8ffc2f64b0f8 | 96 | static const bit_t disableLinkCheck = 0; |
GTsapparellas | 7:8ffc2f64b0f8 | 97 | |
GTsapparellas | 7:8ffc2f64b0f8 | 98 | // Set LoRa Node's transmission power to 14 dBm. |
GTsapparellas | 7:8ffc2f64b0f8 | 99 | static const s1_t txPower = 14; |
GTsapparellas | 7:8ffc2f64b0f8 | 100 | |
GTsapparellas | 7:8ffc2f64b0f8 | 101 | // Set LoRa Node's network id to 0x1. |
GTsapparellas | 7:8ffc2f64b0f8 | 102 | static const u4_t NETID = 0x1; |
GTsapparellas | 7:8ffc2f64b0f8 | 103 | |
GTsapparellas | 7:8ffc2f64b0f8 | 104 | /* LMiC frame initializations. */ |
GTsapparellas | 7:8ffc2f64b0f8 | 105 | |
GTsapparellas | 6:3758685f4b75 | 106 | // Playload frame length of size 8. |
GTsapparellas | 7:8ffc2f64b0f8 | 107 | static const u1_t LMIC_FRAME_LENGTH = 8; |
GTsapparellas | 7:8ffc2f64b0f8 | 108 | |
GTsapparellas | 7:8ffc2f64b0f8 | 109 | // Set listening port to 1. |
GTsapparellas | 7:8ffc2f64b0f8 | 110 | static const u1_t LMIC_PORT = 1; |
GTsapparellas | 7:8ffc2f64b0f8 | 111 | |
GTsapparellas | 7:8ffc2f64b0f8 | 112 | // Disable confirmation of transmitted LMiC data. |
GTsapparellas | 7:8ffc2f64b0f8 | 113 | // Set to 1 in order to enable confirmation of transmitted LMiC data. |
GTsapparellas | 7:8ffc2f64b0f8 | 114 | static const u1_t LMIC_CONFIRMED = 0; |
GTsapparellas | 6:3758685f4b75 | 115 | |
GTsapparellas | 6:3758685f4b75 | 116 | #if ACTIVATION_METHOD == 1 // if OTAA (Over The Air Activation) is applied. |
mluis | 1:60184eda0066 | 117 | |
GTsapparellas | 6:3758685f4b75 | 118 | // LoRaWAN Application identifier (AppEUI) associated with The Things Network Cloud Server. |
GTsapparellas | 6:3758685f4b75 | 119 | static const u1_t APPEUI[8] = { 0x70, 0xB3, 0xD5, 0x7E, 0xD0, 0x00, 0xA4, 0x54 }; |
GTsapparellas | 6:3758685f4b75 | 120 | |
GTsapparellas | 6:3758685f4b75 | 121 | // LoRaWAN unique device ID (DevEUI) associated with The Things Network Cloud Server. |
GTsapparellas | 6:3758685f4b75 | 122 | static const u1_t DEVEUI[8] = { 0x00, 0x1D, 0x45, 0x32, 0xEC, 0xA8, 0x01, 0x59 }; |
mluis | 1:60184eda0066 | 123 | |
mluis | 1:60184eda0066 | 124 | #endif |
mluis | 1:60184eda0066 | 125 | |
GTsapparellas | 6:3758685f4b75 | 126 | // Acquired activation method |
GTsapparellas | 6:3758685f4b75 | 127 | #if ACTIVATION_METHOD == 0 // if ABP (Activation By Personalization) is applied. |
mluis | 1:60184eda0066 | 128 | |
GTsapparellas | 6:3758685f4b75 | 129 | // LoRaWAN network session key (NwkSKey) associated with The Things Network Cloud Server. |
GTsapparellas | 6:3758685f4b75 | 130 | static const u1_t NWKSKEY[16] = { 0xDF, 0x9B, 0xB1, 0x30, 0xE8, 0x33, 0x42, 0x76, 0x33, 0x0C, 0x88, 0xBB, 0x30, 0xE2, 0xC2, 0xE9 }; |
mluis | 1:60184eda0066 | 131 | |
GTsapparellas | 6:3758685f4b75 | 132 | // LoRaWAN application session key (AppSKey) associated with The Things Network Cloud Server. |
GTsapparellas | 6:3758685f4b75 | 133 | static const u1_t APPSKEY[16] = { 0xE0, 0x52, 0x18, 0x15, 0x0B, 0xE1, 0xEF, 0x1F, 0xAF, 0x8C, 0x8A, 0x31, 0x09, 0xB9, 0xAB, 0x9C }; |
mluis | 1:60184eda0066 | 134 | |
GTsapparellas | 6:3758685f4b75 | 135 | // LoRaWAN end-device address (DevAddr) associated with The Things Network Cloud Server. |
GTsapparellas | 6:3758685f4b75 | 136 | static const u4_t DEVADDR = 0x26011B39 ; |
mluis | 1:60184eda0066 | 137 | |
mluis | 1:60184eda0066 | 138 | #endif |
mluis | 0:a2929fa6e4f0 | 139 | |
GTsapparellas | 7:8ffc2f64b0f8 | 140 | /* Sensor declarations. */ |
GTsapparellas | 7:8ffc2f64b0f8 | 141 | |
GTsapparellas | 6:3758685f4b75 | 142 | // Digital Input pin of temperature and humidity sensor set to D6. |
GTsapparellas | 6:3758685f4b75 | 143 | DHT sensorTempHum(D6, DHT11); |
GTsapparellas | 6:3758685f4b75 | 144 | |
GTsapparellas | 6:3758685f4b75 | 145 | // Analog Input pin of light intensity sensor set to A1. |
GTsapparellas | 6:3758685f4b75 | 146 | AnalogIn sensorLight(A1); |
GTsapparellas | 6:3758685f4b75 | 147 | |
GTsapparellas | 6:3758685f4b75 | 148 | // Analog Input pin of soil moisture sensor set to A3. |
GTsapparellas | 6:3758685f4b75 | 149 | AnalogIn sensorSoilMoisture(A3); |
mluis | 0:a2929fa6e4f0 | 150 | |
GTsapparellas | 6:3758685f4b75 | 151 | /////////////////////////////////////////////////// |
GTsapparellas | 7:8ffc2f64b0f8 | 152 | // LMiC APPLICATION CALLBACKS // |
GTsapparellas | 7:8ffc2f64b0f8 | 153 | ///////////////////////////////////////////////// |
GTsapparellas | 7:8ffc2f64b0f8 | 154 | |
GTsapparellas | 7:8ffc2f64b0f8 | 155 | /* |
GTsapparellas | 7:8ffc2f64b0f8 | 156 | * os_getArtEui callback of type void. |
GTsapparellas | 7:8ffc2f64b0f8 | 157 | * |
GTsapparellas | 7:8ffc2f64b0f8 | 158 | * Copies application ID (8 bytes) of The Things Network Cloud Server into |
GTsapparellas | 7:8ffc2f64b0f8 | 159 | * memory if OTAA(Over The Air Activation) is applied. |
GTsapparellas | 7:8ffc2f64b0f8 | 160 | * |
GTsapparellas | 7:8ffc2f64b0f8 | 161 | * Input parameters: unsigned char buf of APPEUI. |
GTsapparellas | 7:8ffc2f64b0f8 | 162 | * |
GTsapparellas | 7:8ffc2f64b0f8 | 163 | */ |
GTsapparellas | 7:8ffc2f64b0f8 | 164 | void os_getArtEui (u1_t* buf) { |
GTsapparellas | 7:8ffc2f64b0f8 | 165 | #if ACTIVATION_METHOD == 1 // if OTAA (Over The Air Activation) is applied. |
GTsapparellas | 7:8ffc2f64b0f8 | 166 | memcpy(buf, APPEUI, 8); |
GTsapparellas | 7:8ffc2f64b0f8 | 167 | #endif |
GTsapparellas | 7:8ffc2f64b0f8 | 168 | }// end of os_getArtEui callback. |
GTsapparellas | 7:8ffc2f64b0f8 | 169 | |
GTsapparellas | 7:8ffc2f64b0f8 | 170 | /* |
GTsapparellas | 7:8ffc2f64b0f8 | 171 | * os_getDevEui callback of type void. |
GTsapparellas | 7:8ffc2f64b0f8 | 172 | * |
GTsapparellas | 7:8ffc2f64b0f8 | 173 | * Copies device ID (8 bytes) of The Things Network Cloud Server into |
GTsapparellas | 7:8ffc2f64b0f8 | 174 | * memory if OTAA(Over The Air Activation) is applied. |
GTsapparellas | 7:8ffc2f64b0f8 | 175 | * |
GTsapparellas | 7:8ffc2f64b0f8 | 176 | * Input parameters: unsigned char buf of DEVEUI. |
GTsapparellas | 7:8ffc2f64b0f8 | 177 | * |
GTsapparellas | 7:8ffc2f64b0f8 | 178 | */ |
GTsapparellas | 7:8ffc2f64b0f8 | 179 | void os_getDevEui (u1_t* buf) { |
GTsapparellas | 7:8ffc2f64b0f8 | 180 | #if ACTIVATION_METHOD == 1 // if OTAA (Over The Air Activation) is applied. |
GTsapparellas | 7:8ffc2f64b0f8 | 181 | memcpy(buf, DEVEUI, 8); |
GTsapparellas | 7:8ffc2f64b0f8 | 182 | #endif |
GTsapparellas | 7:8ffc2f64b0f8 | 183 | }// end of os_getDevEui callback. |
GTsapparellas | 7:8ffc2f64b0f8 | 184 | |
GTsapparellas | 7:8ffc2f64b0f8 | 185 | /* |
GTsapparellas | 7:8ffc2f64b0f8 | 186 | * os_getDevKey callback of type void. |
GTsapparellas | 7:8ffc2f64b0f8 | 187 | * |
GTsapparellas | 7:8ffc2f64b0f8 | 188 | * Copies device network session ID (16 bytes) of The Things Network Cloud Server |
GTsapparellas | 7:8ffc2f64b0f8 | 189 | * into memory. |
GTsapparellas | 7:8ffc2f64b0f8 | 190 | * |
GTsapparellas | 7:8ffc2f64b0f8 | 191 | * Input parameters: unsigned char buf of NWKSKEY. |
GTsapparellas | 7:8ffc2f64b0f8 | 192 | * |
GTsapparellas | 7:8ffc2f64b0f8 | 193 | */ |
GTsapparellas | 7:8ffc2f64b0f8 | 194 | void os_getDevKey (u1_t* buf) { |
GTsapparellas | 7:8ffc2f64b0f8 | 195 | memcpy(buf, NWKSKEY, 16); |
GTsapparellas | 7:8ffc2f64b0f8 | 196 | }// end of os_getDevKey callback. |
GTsapparellas | 7:8ffc2f64b0f8 | 197 | |
GTsapparellas | 7:8ffc2f64b0f8 | 198 | /* |
GTsapparellas | 7:8ffc2f64b0f8 | 199 | * onEvent callback of type void. |
GTsapparellas | 7:8ffc2f64b0f8 | 200 | * |
GTsapparellas | 9:f3e9b3a6eded | 201 | * Outputs UART message depending on |
GTsapparellas | 7:8ffc2f64b0f8 | 202 | * related event. |
GTsapparellas | 7:8ffc2f64b0f8 | 203 | * |
GTsapparellas | 7:8ffc2f64b0f8 | 204 | * NOTICE THAT: Not all events are being |
GTsapparellas | 7:8ffc2f64b0f8 | 205 | * used due to significant set up |
GTsapparellas | 7:8ffc2f64b0f8 | 206 | * of LMiC environment. |
GTsapparellas | 7:8ffc2f64b0f8 | 207 | * |
GTsapparellas | 7:8ffc2f64b0f8 | 208 | * Input parameters: ev_t event. |
GTsapparellas | 7:8ffc2f64b0f8 | 209 | * |
GTsapparellas | 7:8ffc2f64b0f8 | 210 | */ |
GTsapparellas | 7:8ffc2f64b0f8 | 211 | void onEvent (ev_t ev) { |
GTsapparellas | 7:8ffc2f64b0f8 | 212 | |
GTsapparellas | 7:8ffc2f64b0f8 | 213 | switch(ev) { // Switch events. |
GTsapparellas | 7:8ffc2f64b0f8 | 214 | case EV_SCAN_TIMEOUT: |
GTsapparellas | 7:8ffc2f64b0f8 | 215 | printf("EV_SCAN_TIMEOUT\n"); // Scan timeout. |
GTsapparellas | 7:8ffc2f64b0f8 | 216 | break; |
GTsapparellas | 7:8ffc2f64b0f8 | 217 | case EV_BEACON_FOUND: |
GTsapparellas | 7:8ffc2f64b0f8 | 218 | printf("EV_BEACON_FOUND\n"); // Beacon found. |
GTsapparellas | 7:8ffc2f64b0f8 | 219 | break; |
GTsapparellas | 7:8ffc2f64b0f8 | 220 | case EV_BEACON_MISSED: |
GTsapparellas | 7:8ffc2f64b0f8 | 221 | printf("EV_BEACON_MISSED\n"); // Beacon missed. |
GTsapparellas | 7:8ffc2f64b0f8 | 222 | break; |
GTsapparellas | 7:8ffc2f64b0f8 | 223 | case EV_BEACON_TRACKED: |
GTsapparellas | 7:8ffc2f64b0f8 | 224 | printf("EV_BEACON_TRACKED\n"); // Beacon tracked. |
GTsapparellas | 7:8ffc2f64b0f8 | 225 | break; |
GTsapparellas | 7:8ffc2f64b0f8 | 226 | case EV_JOINING: |
GTsapparellas | 7:8ffc2f64b0f8 | 227 | printf("EV_JOINING\n"); // Joining the network. |
GTsapparellas | 7:8ffc2f64b0f8 | 228 | break; |
GTsapparellas | 7:8ffc2f64b0f8 | 229 | case EV_JOINED: |
GTsapparellas | 7:8ffc2f64b0f8 | 230 | printf("EV_JOINED\n"); // Network joined. |
GTsapparellas | 7:8ffc2f64b0f8 | 231 | break; |
GTsapparellas | 7:8ffc2f64b0f8 | 232 | case EV_RFU1: |
GTsapparellas | 7:8ffc2f64b0f8 | 233 | printf("EV_RFU1\n"); // RFU1 event. |
GTsapparellas | 7:8ffc2f64b0f8 | 234 | break; |
GTsapparellas | 7:8ffc2f64b0f8 | 235 | case EV_JOIN_FAILED: |
GTsapparellas | 7:8ffc2f64b0f8 | 236 | printf("EV_JOIN_FAILED\n"); // Joining failed. |
GTsapparellas | 7:8ffc2f64b0f8 | 237 | break; |
GTsapparellas | 7:8ffc2f64b0f8 | 238 | case EV_REJOIN_FAILED: |
GTsapparellas | 7:8ffc2f64b0f8 | 239 | printf("EV_REJOIN_FAILED\n"); // Re-joining failed. |
GTsapparellas | 7:8ffc2f64b0f8 | 240 | break; |
GTsapparellas | 7:8ffc2f64b0f8 | 241 | case EV_TXCOMPLETE: |
GTsapparellas | 9:f3e9b3a6eded | 242 | printf("EV_TXCOMPLETE\n"); // Transmission complete. |
GTsapparellas | 7:8ffc2f64b0f8 | 243 | if (LMIC.txrxFlags & TXRX_ACK) // Check if acknowledgment received. |
GTsapparellas | 7:8ffc2f64b0f8 | 244 | { |
GTsapparellas | 7:8ffc2f64b0f8 | 245 | printf("Received ack\n"); |
GTsapparellas | 7:8ffc2f64b0f8 | 246 | } |
GTsapparellas | 7:8ffc2f64b0f8 | 247 | if(LMIC.dataLen) // Output playload's data length. |
GTsapparellas | 7:8ffc2f64b0f8 | 248 | { |
GTsapparellas | 7:8ffc2f64b0f8 | 249 | printf("Received "); |
GTsapparellas | 7:8ffc2f64b0f8 | 250 | printf("%u", LMIC.dataLen); |
GTsapparellas | 7:8ffc2f64b0f8 | 251 | printf(" bytes of payload\n"); |
GTsapparellas | 7:8ffc2f64b0f8 | 252 | } |
GTsapparellas | 7:8ffc2f64b0f8 | 253 | break; |
GTsapparellas | 7:8ffc2f64b0f8 | 254 | case EV_LOST_TSYNC: |
GTsapparellas | 7:8ffc2f64b0f8 | 255 | printf("EV_LOST_TSYNC\n"); // Lost transmision sync. |
GTsapparellas | 7:8ffc2f64b0f8 | 256 | break; |
GTsapparellas | 7:8ffc2f64b0f8 | 257 | case EV_RESET: |
GTsapparellas | 7:8ffc2f64b0f8 | 258 | printf("EV_RESET\n"); // Reset. |
GTsapparellas | 7:8ffc2f64b0f8 | 259 | break; |
GTsapparellas | 7:8ffc2f64b0f8 | 260 | case EV_RXCOMPLETE: |
GTsapparellas | 7:8ffc2f64b0f8 | 261 | printf("EV_RXCOMPLETE\n"); // Reception complete. |
GTsapparellas | 7:8ffc2f64b0f8 | 262 | break; |
GTsapparellas | 7:8ffc2f64b0f8 | 263 | case EV_LINK_DEAD: |
GTsapparellas | 7:8ffc2f64b0f8 | 264 | printf("EV_LINK_DEAD\n"); // Link dead. |
GTsapparellas | 7:8ffc2f64b0f8 | 265 | break; |
GTsapparellas | 7:8ffc2f64b0f8 | 266 | case EV_LINK_ALIVE: |
GTsapparellas | 7:8ffc2f64b0f8 | 267 | printf("EV_LINK_ALIVE\n"); // Link alive. |
GTsapparellas | 7:8ffc2f64b0f8 | 268 | break; |
GTsapparellas | 7:8ffc2f64b0f8 | 269 | default: |
GTsapparellas | 7:8ffc2f64b0f8 | 270 | printf("Unknown event\n"); // Default unknown event. |
GTsapparellas | 7:8ffc2f64b0f8 | 271 | break; |
GTsapparellas | 7:8ffc2f64b0f8 | 272 | } |
GTsapparellas | 9:f3e9b3a6eded | 273 | printf("\n"); // New line. |
GTsapparellas | 7:8ffc2f64b0f8 | 274 | }// end of onEvent callback. |
GTsapparellas | 7:8ffc2f64b0f8 | 275 | |
GTsapparellas | 7:8ffc2f64b0f8 | 276 | /////////////////////////////////////////////////// |
GTsapparellas | 6:3758685f4b75 | 277 | // LOCAL FUNCTIONS DECLARATIONS // |
GTsapparellas | 6:3758685f4b75 | 278 | ///////////////////////////////////////////////// |
GTsapparellas | 6:3758685f4b75 | 279 | |
GTsapparellas | 6:3758685f4b75 | 280 | /* |
GTsapparellas | 7:8ffc2f64b0f8 | 281 | * setUp function of type void. |
GTsapparellas | 7:8ffc2f64b0f8 | 282 | * |
GTsapparellas | 7:8ffc2f64b0f8 | 283 | * Initializes mbed OS, LMiC OS as well as |
GTsapparellas | 7:8ffc2f64b0f8 | 284 | * disabling all channels but 0 (868.1 MHz) for single-channel |
GTsapparellas | 7:8ffc2f64b0f8 | 285 | * gateway compatibility. |
GTsapparellas | 7:8ffc2f64b0f8 | 286 | * |
GTsapparellas | 7:8ffc2f64b0f8 | 287 | * Input parameters: None. |
GTsapparellas | 7:8ffc2f64b0f8 | 288 | * |
GTsapparellas | 7:8ffc2f64b0f8 | 289 | */ |
GTsapparellas | 7:8ffc2f64b0f8 | 290 | void setUp() { |
GTsapparellas | 7:8ffc2f64b0f8 | 291 | |
GTsapparellas | 7:8ffc2f64b0f8 | 292 | #if DEBUG_LEVEL == 1 |
GTsapparellas | 7:8ffc2f64b0f8 | 293 | printf("IoT smart monitoring device for agriculture using LoRaWAN technology\n\n"); |
GTsapparellas | 7:8ffc2f64b0f8 | 294 | #endif |
GTsapparellas | 7:8ffc2f64b0f8 | 295 | // Initializes OS. |
GTsapparellas | 7:8ffc2f64b0f8 | 296 | os_init(); |
GTsapparellas | 7:8ffc2f64b0f8 | 297 | |
GTsapparellas | 7:8ffc2f64b0f8 | 298 | #if DEBUG_LEVEL == 1 |
GTsapparellas | 7:8ffc2f64b0f8 | 299 | printf("OS_INIT\n\n"); |
GTsapparellas | 7:8ffc2f64b0f8 | 300 | #endif |
GTsapparellas | 7:8ffc2f64b0f8 | 301 | |
GTsapparellas | 7:8ffc2f64b0f8 | 302 | // Reset the MAC state. Session and pending data transfers are being discarded. |
GTsapparellas | 7:8ffc2f64b0f8 | 303 | LMIC_reset(); |
GTsapparellas | 7:8ffc2f64b0f8 | 304 | |
GTsapparellas | 7:8ffc2f64b0f8 | 305 | // Set static session parameters. Instead of dynamically establishing a session |
GTsapparellas | 7:8ffc2f64b0f8 | 306 | // by joining the network, precomputed session parameters are be provided. |
GTsapparellas | 7:8ffc2f64b0f8 | 307 | LMIC_setSession (NETID, DEVADDR, (uint8_t*)NWKSKEY, (uint8_t*)APPSKEY); |
GTsapparellas | 7:8ffc2f64b0f8 | 308 | |
GTsapparellas | 7:8ffc2f64b0f8 | 309 | // Disable data rate adaptation. |
GTsapparellas | 7:8ffc2f64b0f8 | 310 | LMIC_setAdrMode(disableAdrMode); |
GTsapparellas | 7:8ffc2f64b0f8 | 311 | |
GTsapparellas | 7:8ffc2f64b0f8 | 312 | // Disable link check validation. |
GTsapparellas | 7:8ffc2f64b0f8 | 313 | LMIC_setLinkCheckMode(disableLinkCheck); |
GTsapparellas | 7:8ffc2f64b0f8 | 314 | |
GTsapparellas | 7:8ffc2f64b0f8 | 315 | // Disable beacon tracking. |
GTsapparellas | 7:8ffc2f64b0f8 | 316 | LMIC_disableTracking(); |
GTsapparellas | 7:8ffc2f64b0f8 | 317 | |
GTsapparellas | 7:8ffc2f64b0f8 | 318 | // Stop listening for downstream data (periodical reception) as LoRa Node |
GTsapparellas | 7:8ffc2f64b0f8 | 319 | // is only transmitting data to the Gateway. |
GTsapparellas | 7:8ffc2f64b0f8 | 320 | LMIC_stopPingable(); |
GTsapparellas | 7:8ffc2f64b0f8 | 321 | |
GTsapparellas | 7:8ffc2f64b0f8 | 322 | // Set data rate and transmit power. |
GTsapparellas | 7:8ffc2f64b0f8 | 323 | LMIC_setDrTxpow(DR_SF7,txPower); |
GTsapparellas | 7:8ffc2f64b0f8 | 324 | |
GTsapparellas | 7:8ffc2f64b0f8 | 325 | // If single-channel gateway is being used disable |
GTsapparellas | 7:8ffc2f64b0f8 | 326 | // all the other channels except channel 0. |
GTsapparellas | 7:8ffc2f64b0f8 | 327 | #ifdef SINGLE_CHANNEL_GATEWAY |
GTsapparellas | 7:8ffc2f64b0f8 | 328 | #if DEBUG_LEVEL == 1 |
GTsapparellas | 7:8ffc2f64b0f8 | 329 | printf(" ----->Disabling all channels but 0 (868.1 MHz) for single-channel gateway compatibility\n\n\n"); |
GTsapparellas | 7:8ffc2f64b0f8 | 330 | #endif |
GTsapparellas | 7:8ffc2f64b0f8 | 331 | |
GTsapparellas | 7:8ffc2f64b0f8 | 332 | for (int i=1; i < MAX_EU_CHANNELS; i++) |
GTsapparellas | 7:8ffc2f64b0f8 | 333 | { |
GTsapparellas | 7:8ffc2f64b0f8 | 334 | LMIC_disableChannel(i); |
GTsapparellas | 7:8ffc2f64b0f8 | 335 | } |
GTsapparellas | 7:8ffc2f64b0f8 | 336 | #endif |
GTsapparellas | 7:8ffc2f64b0f8 | 337 | |
GTsapparellas | 7:8ffc2f64b0f8 | 338 | #if DEBUG_LEVEL == 1 |
GTsapparellas | 7:8ffc2f64b0f8 | 339 | printf("//////////Entering into TIME-TRIGGERED packet sending through LoRaWAN//////////\n"); |
GTsapparellas | 7:8ffc2f64b0f8 | 340 | printf("---------------------Packets to be sent every %u seconds----------------------\n\n", transmit_interval); |
GTsapparellas | 7:8ffc2f64b0f8 | 341 | #endif |
GTsapparellas | 7:8ffc2f64b0f8 | 342 | }// end of setUp function. |
GTsapparellas | 7:8ffc2f64b0f8 | 343 | |
GTsapparellas | 7:8ffc2f64b0f8 | 344 | /* |
GTsapparellas | 6:3758685f4b75 | 345 | * getTemperatureHumidity function of type void. |
GTsapparellas | 6:3758685f4b75 | 346 | * |
GTsapparellas | 6:3758685f4b75 | 347 | * Gets temperature (celcius) and humidity (relative humidity %) |
GTsapparellas | 6:3758685f4b75 | 348 | * measurements using DHT library. Otherwise, print an error. |
GTsapparellas | 6:3758685f4b75 | 349 | * |
GTsapparellas | 6:3758685f4b75 | 350 | * Input parameters: float temperature |
GTsapparellas | 6:3758685f4b75 | 351 | * float humidity |
GTsapparellas | 6:3758685f4b75 | 352 | */ |
GTsapparellas | 6:3758685f4b75 | 353 | void getTemperatureHumidity(float& temperature, float& humidity) { |
mluis | 0:a2929fa6e4f0 | 354 | |
GTsapparellas | 6:3758685f4b75 | 355 | // Set err variable to 0 (none). |
GTsapparellas | 6:3758685f4b75 | 356 | uint8_t err = ERROR_NONE; |
GTsapparellas | 6:3758685f4b75 | 357 | // Set humidity variable to 0. |
GTsapparellas | 6:3758685f4b75 | 358 | humidity = 0.0f; |
GTsapparellas | 6:3758685f4b75 | 359 | // Set temperature variable to 0. |
GTsapparellas | 6:3758685f4b75 | 360 | temperature = 0.0f; |
GTsapparellas | 6:3758685f4b75 | 361 | |
GTsapparellas | 6:3758685f4b75 | 362 | // Store sensor data (40 bits(16-bit temperature, 16-bit humidity and 8-bit |
GTsapparellas | 6:3758685f4b75 | 363 | // CRC checksum)) into err variable. |
GTsapparellas | 6:3758685f4b75 | 364 | err = sensorTempHum.readData(); |
GTsapparellas | 6:3758685f4b75 | 365 | |
GTsapparellas | 6:3758685f4b75 | 366 | if (err == ERROR_NONE) // if err equals to 0. |
GTsapparellas | 6:3758685f4b75 | 367 | { |
GTsapparellas | 6:3758685f4b75 | 368 | // Store float temperature value in celcius. |
GTsapparellas | 6:3758685f4b75 | 369 | temperature = sensorTempHum.ReadTemperature(CELCIUS); |
GTsapparellas | 6:3758685f4b75 | 370 | // Store float humidity value. |
GTsapparellas | 6:3758685f4b75 | 371 | humidity = sensorTempHum.ReadHumidity(); |
GTsapparellas | 6:3758685f4b75 | 372 | |
GTsapparellas | 6:3758685f4b75 | 373 | // Output temperature and humidity values on UART Terminal |
GTsapparellas | 6:3758685f4b75 | 374 | #if DEBUG_LEVEL == 1 |
GTsapparellas | 6:3758685f4b75 | 375 | printf("Temperature: %4.2f Celsius \r\n", temperature); |
GTsapparellas | 9:f3e9b3a6eded | 376 | printf("Humidity: %4.2f Relative Humidity \r\n", humidity); |
GTsapparellas | 6:3758685f4b75 | 377 | #endif |
GTsapparellas | 6:3758685f4b75 | 378 | } |
GTsapparellas | 6:3758685f4b75 | 379 | else // if err occurs. |
GTsapparellas | 6:3758685f4b75 | 380 | { |
GTsapparellas | 6:3758685f4b75 | 381 | // Output error message on UART Terminal and flash the RED LED. |
GTsapparellas | 6:3758685f4b75 | 382 | #if DEBUG_LEVEL == 1 |
GTsapparellas | 6:3758685f4b75 | 383 | printf("Error: %d\r\n", err); |
GTsapparellas | 6:3758685f4b75 | 384 | #endif |
GTsapparellas | 6:3758685f4b75 | 385 | } |
GTsapparellas | 6:3758685f4b75 | 386 | }// end of getTemperatureHumidity function. |
mluis | 0:a2929fa6e4f0 | 387 | |
GTsapparellas | 6:3758685f4b75 | 388 | /* |
GTsapparellas | 6:3758685f4b75 | 389 | * getLightIntensity function of type void. |
GTsapparellas | 6:3758685f4b75 | 390 | * |
GTsapparellas | 6:3758685f4b75 | 391 | * Gets the light's intensity analogue value at first instance |
GTsapparellas | 6:3758685f4b75 | 392 | * and then converts it using 16-bit ADC converter into voltage |
GTsapparellas | 6:3758685f4b75 | 393 | * counting from 0.0 to 5.0. |
GTsapparellas | 6:3758685f4b75 | 394 | * |
GTsapparellas | 6:3758685f4b75 | 395 | * Input parameters: float lightIntensityVoltage |
GTsapparellas | 6:3758685f4b75 | 396 | * |
GTsapparellas | 6:3758685f4b75 | 397 | */ |
GTsapparellas | 6:3758685f4b75 | 398 | void getLightIntensity(float& lightIntensityVoltage) { |
GTsapparellas | 6:3758685f4b75 | 399 | |
GTsapparellas | 6:3758685f4b75 | 400 | // Set light intensity voltage variable to 0. |
GTsapparellas | 6:3758685f4b75 | 401 | lightIntensityVoltage = 0.0f; |
GTsapparellas | 6:3758685f4b75 | 402 | // Set light intensity analogue value to 0. |
GTsapparellas | 6:3758685f4b75 | 403 | uint16_t lightIntensityAnalogue = 0; |
GTsapparellas | 6:3758685f4b75 | 404 | |
GTsapparellas | 6:3758685f4b75 | 405 | // Read light intensity 16-bit analogue value. |
GTsapparellas | 6:3758685f4b75 | 406 | lightIntensityAnalogue = sensorLight.read_u16(); |
GTsapparellas | 6:3758685f4b75 | 407 | //Convert the light intensity analog reading (which goes from 0 - 65536) to a voltage (0 - 5V). |
GTsapparellas | 6:3758685f4b75 | 408 | lightIntensityVoltage = (float) lightIntensityAnalogue*(5.0/65536.0); |
GTsapparellas | 6:3758685f4b75 | 409 | |
GTsapparellas | 6:3758685f4b75 | 410 | // Output light intensity voltage as well as resistance value on UART Terminal. |
GTsapparellas | 6:3758685f4b75 | 411 | #if DEBUG_LEVEL == 1 |
GTsapparellas | 6:3758685f4b75 | 412 | float resistance = 0.0f; |
GTsapparellas | 6:3758685f4b75 | 413 | // Groove's calculation for resistance value. |
GTsapparellas | 6:3758685f4b75 | 414 | resistance = (float)(65536-lightIntensityAnalogue)*10/lightIntensityAnalogue; |
GTsapparellas | 6:3758685f4b75 | 415 | printf("Light Intensity: %2.2f Volts -- ", lightIntensityVoltage); |
GTsapparellas | 6:3758685f4b75 | 416 | printf("Resistance: %2.2f Kiloohm \r\n", resistance); |
GTsapparellas | 6:3758685f4b75 | 417 | #endif |
GTsapparellas | 6:3758685f4b75 | 418 | }// end of getLightIntensity function. |
mluis | 0:a2929fa6e4f0 | 419 | |
GTsapparellas | 6:3758685f4b75 | 420 | /* |
GTsapparellas | 6:3758685f4b75 | 421 | * getSoilMoisture function of type void. |
GTsapparellas | 6:3758685f4b75 | 422 | * |
GTsapparellas | 6:3758685f4b75 | 423 | * Gets the soil's moisture analogue value at first instance |
GTsapparellas | 6:3758685f4b75 | 424 | * and then converts it using 16-bit ADC converter into voltage |
GTsapparellas | 6:3758685f4b75 | 425 | * counting from 0.0 to 5.0. |
GTsapparellas | 6:3758685f4b75 | 426 | * |
GTsapparellas | 6:3758685f4b75 | 427 | * Input parameters: float lightOutputVoltage |
mluis | 1:60184eda0066 | 428 | * |
GTsapparellas | 6:3758685f4b75 | 429 | */ |
GTsapparellas | 6:3758685f4b75 | 430 | void getSoilMoisture(float& soilMoistureVoltage) { |
GTsapparellas | 6:3758685f4b75 | 431 | |
GTsapparellas | 6:3758685f4b75 | 432 | // Set soil moisture voltage variable to 0. |
GTsapparellas | 6:3758685f4b75 | 433 | soilMoistureVoltage = 0.0f; |
GTsapparellas | 6:3758685f4b75 | 434 | // Set soil moisture analogue value to 0. |
GTsapparellas | 6:3758685f4b75 | 435 | uint16_t soilMoistureAnalogue = 0; |
GTsapparellas | 6:3758685f4b75 | 436 | |
GTsapparellas | 6:3758685f4b75 | 437 | // Read soil moisture 16-bit analogue value. |
GTsapparellas | 6:3758685f4b75 | 438 | soilMoistureAnalogue = sensorSoilMoisture.read_u16(); |
GTsapparellas | 7:8ffc2f64b0f8 | 439 | // Convert the soil moisture analog reading (which goes from 0 - 65536) to a voltage (0 - 5V). |
GTsapparellas | 6:3758685f4b75 | 440 | soilMoistureVoltage = (float) soilMoistureAnalogue*(5.0/65536.0); |
GTsapparellas | 6:3758685f4b75 | 441 | |
GTsapparellas | 6:3758685f4b75 | 442 | // Output soil moisture voltage as well as soil moisture analogue value on UART Terminal. |
GTsapparellas | 6:3758685f4b75 | 443 | #if DEBUG_LEVEL == 1 |
GTsapparellas | 6:3758685f4b75 | 444 | printf("Soil Moisture: %2.2f Volts -- ", soilMoistureVoltage); |
GTsapparellas | 6:3758685f4b75 | 445 | printf("Analogue Value: %d \r\n", soilMoistureAnalogue); |
GTsapparellas | 6:3758685f4b75 | 446 | #endif |
GTsapparellas | 6:3758685f4b75 | 447 | }// end of getSoilMoisture function. |
mluis | 1:60184eda0066 | 448 | |
GTsapparellas | 7:8ffc2f64b0f8 | 449 | /* |
GTsapparellas | 7:8ffc2f64b0f8 | 450 | * transmit function of type void. |
GTsapparellas | 7:8ffc2f64b0f8 | 451 | * |
GTsapparellas | 7:8ffc2f64b0f8 | 452 | * Checking if channel is ready. |
GTsapparellas | 7:8ffc2f64b0f8 | 453 | * If no, waiting until channel becomes free. |
GTsapparellas | 7:8ffc2f64b0f8 | 454 | * If yes, calling getTemperatureHumidity, |
GTsapparellas | 7:8ffc2f64b0f8 | 455 | * getLightIntensity and getSoilMoisture functions |
GTsapparellas | 7:8ffc2f64b0f8 | 456 | * to gather measuring parameters. Then, prepares |
GTsapparellas | 7:8ffc2f64b0f8 | 457 | * the LoRa packet and finally sending the packet |
GTsapparellas | 7:8ffc2f64b0f8 | 458 | * using os_setTimedCallback LMiC callback. |
GTsapparellas | 7:8ffc2f64b0f8 | 459 | * |
GTsapparellas | 7:8ffc2f64b0f8 | 460 | * Input parameters: osjob_t* j |
GTsapparellas | 7:8ffc2f64b0f8 | 461 | * |
GTsapparellas | 7:8ffc2f64b0f8 | 462 | */ |
GTsapparellas | 7:8ffc2f64b0f8 | 463 | void transmit(osjob_t* j) |
GTsapparellas | 7:8ffc2f64b0f8 | 464 | { |
GTsapparellas | 7:8ffc2f64b0f8 | 465 | // Define sensor measuring parameters. |
GTsapparellas | 7:8ffc2f64b0f8 | 466 | float temperature, humidity, lightIntensity, soilMoisture; |
GTsapparellas | 7:8ffc2f64b0f8 | 467 | |
GTsapparellas | 7:8ffc2f64b0f8 | 468 | #if DEBUG_LEVEL == 1 |
GTsapparellas | 7:8ffc2f64b0f8 | 469 | printf("txChannel: %u , Channel Ready? ", LMIC.txChnl); |
GTsapparellas | 6:3758685f4b75 | 470 | #endif |
GTsapparellas | 7:8ffc2f64b0f8 | 471 | |
GTsapparellas | 7:8ffc2f64b0f8 | 472 | if (LMIC.opmode & (1 << 7)) // Is channel ready for transmission? |
GTsapparellas | 6:3758685f4b75 | 473 | { |
GTsapparellas | 6:3758685f4b75 | 474 | printf("NO, waiting...\n\n"); |
GTsapparellas | 6:3758685f4b75 | 475 | } |
GTsapparellas | 6:3758685f4b75 | 476 | else |
GTsapparellas | 6:3758685f4b75 | 477 | { |
GTsapparellas | 7:8ffc2f64b0f8 | 478 | #if DEBUG_LEVEL == 1 |
GTsapparellas | 7:8ffc2f64b0f8 | 479 | printf("YES, sensor readings...\n\n"); |
GTsapparellas | 7:8ffc2f64b0f8 | 480 | #endif |
GTsapparellas | 7:8ffc2f64b0f8 | 481 | |
GTsapparellas | 7:8ffc2f64b0f8 | 482 | // Gather sensor readings. |
GTsapparellas | 7:8ffc2f64b0f8 | 483 | getTemperatureHumidity(temperature, humidity); |
GTsapparellas | 7:8ffc2f64b0f8 | 484 | getLightIntensity(lightIntensity); |
GTsapparellas | 7:8ffc2f64b0f8 | 485 | getSoilMoisture(soilMoisture); |
GTsapparellas | 6:3758685f4b75 | 486 | |
GTsapparellas | 7:8ffc2f64b0f8 | 487 | #if DEBUG_LEVEL == 1 |
GTsapparellas | 7:8ffc2f64b0f8 | 488 | printf(" ----->Preparing LoRa packet...\n"); |
GTsapparellas | 7:8ffc2f64b0f8 | 489 | #endif |
GTsapparellas | 7:8ffc2f64b0f8 | 490 | |
GTsapparellas | 7:8ffc2f64b0f8 | 491 | // Prepare upstream data transmission at the next possible time. |
GTsapparellas | 7:8ffc2f64b0f8 | 492 | // Multiply all sensor readings by 100. |
GTsapparellas | 7:8ffc2f64b0f8 | 493 | int16_t temp = temperature*100; |
GTsapparellas | 7:8ffc2f64b0f8 | 494 | int16_t hum = humidity*100; |
GTsapparellas | 7:8ffc2f64b0f8 | 495 | int16_t light = lightIntensity*100; |
GTsapparellas | 7:8ffc2f64b0f8 | 496 | int16_t soil = soilMoisture*100; |
GTsapparellas | 6:3758685f4b75 | 497 | |
GTsapparellas | 7:8ffc2f64b0f8 | 498 | // Allocate measurements into LMIC frame array ready for transmission. |
GTsapparellas | 7:8ffc2f64b0f8 | 499 | // Each sensor measurement allocates 2 positions in frame array. |
GTsapparellas | 7:8ffc2f64b0f8 | 500 | // First, value is right shifted for 8 bits, while on the next |
GTsapparellas | 7:8ffc2f64b0f8 | 501 | // array's position least significant bits are taken as the desired |
GTsapparellas | 7:8ffc2f64b0f8 | 502 | // value for each sensor measurement. |
GTsapparellas | 7:8ffc2f64b0f8 | 503 | // This procedure is required in order to send playload data |
GTsapparellas | 10:0a4ad1388e05 | 504 | // to the gateway which forwards it to The Things Network Cloud Server. |
GTsapparellas | 7:8ffc2f64b0f8 | 505 | // Data will then be converted in a meaningful way through |
GTsapparellas | 7:8ffc2f64b0f8 | 506 | // All Things Talk ABCL custom JSON binary conversion script. |
GTsapparellas | 7:8ffc2f64b0f8 | 507 | LMIC.frame[0] = temp >> 8; |
GTsapparellas | 7:8ffc2f64b0f8 | 508 | LMIC.frame[1] = temp & 0xFF; |
GTsapparellas | 7:8ffc2f64b0f8 | 509 | LMIC.frame[2] = hum >> 8; |
GTsapparellas | 7:8ffc2f64b0f8 | 510 | LMIC.frame[3] = hum & 0xFF; |
GTsapparellas | 7:8ffc2f64b0f8 | 511 | LMIC.frame[4] = light >> 8; |
GTsapparellas | 7:8ffc2f64b0f8 | 512 | LMIC.frame[5] = light & 0xFF; |
GTsapparellas | 7:8ffc2f64b0f8 | 513 | LMIC.frame[6] = soil >> 8; |
GTsapparellas | 7:8ffc2f64b0f8 | 514 | LMIC.frame[7] = soil & 0xFF; |
GTsapparellas | 6:3758685f4b75 | 515 | |
GTsapparellas | 7:8ffc2f64b0f8 | 516 | // Set the transmission data. |
GTsapparellas | 7:8ffc2f64b0f8 | 517 | LMIC_setTxData2(LMIC_PORT, LMIC.frame, LMIC_FRAME_LENGTH, LMIC_CONFIRMED); |
GTsapparellas | 7:8ffc2f64b0f8 | 518 | |
GTsapparellas | 7:8ffc2f64b0f8 | 519 | #if DEBUG_LEVEL == 1 |
GTsapparellas | 7:8ffc2f64b0f8 | 520 | printf(" ----->LoRa Packet READY\n\n"); |
GTsapparellas | 7:8ffc2f64b0f8 | 521 | printf(" ----->Sending LoRa packet %u of byte size %u\n\n", packetCounter++, LMIC_FRAME_LENGTH); |
GTsapparellas | 7:8ffc2f64b0f8 | 522 | #endif |
GTsapparellas | 6:3758685f4b75 | 523 | } |
GTsapparellas | 7:8ffc2f64b0f8 | 524 | // Schedule a time-triggered job to run based on TRANSMIT_INTERVAL time value. |
GTsapparellas | 6:3758685f4b75 | 525 | os_setTimedCallback(j, os_getTime()+sec2osticks(TRANSMIT_INTERVAL), transmit); |
GTsapparellas | 7:8ffc2f64b0f8 | 526 | |
GTsapparellas | 7:8ffc2f64b0f8 | 527 | }// end of transmit function. |
mluis | 0:a2929fa6e4f0 | 528 | |
GTsapparellas | 7:8ffc2f64b0f8 | 529 | /* |
GTsapparellas | 7:8ffc2f64b0f8 | 530 | * loop function of type void. |
GTsapparellas | 7:8ffc2f64b0f8 | 531 | * |
GTsapparellas | 7:8ffc2f64b0f8 | 532 | * Calling transmit as well as os_runloop_once functions |
GTsapparellas | 7:8ffc2f64b0f8 | 533 | * for a repeatedly time-triggered behaviour |
GTsapparellas | 7:8ffc2f64b0f8 | 534 | * program execution. |
GTsapparellas | 7:8ffc2f64b0f8 | 535 | * |
GTsapparellas | 7:8ffc2f64b0f8 | 536 | * Input parameters: None. |
GTsapparellas | 7:8ffc2f64b0f8 | 537 | * |
GTsapparellas | 7:8ffc2f64b0f8 | 538 | */ |
GTsapparellas | 7:8ffc2f64b0f8 | 539 | void loop() |
GTsapparellas | 7:8ffc2f64b0f8 | 540 | { |
GTsapparellas | 7:8ffc2f64b0f8 | 541 | // Calling transmit local function for acquiring next transmission |
GTsapparellas | 7:8ffc2f64b0f8 | 542 | // job of LoRa Node. |
GTsapparellas | 7:8ffc2f64b0f8 | 543 | transmit(&sendjob); |
mluis | 0:a2929fa6e4f0 | 544 | |
GTsapparellas | 7:8ffc2f64b0f8 | 545 | // Super loop running os_runloop_once LMiC callback in a time-triggered behaviour. |
GTsapparellas | 7:8ffc2f64b0f8 | 546 | while(1) |
GTsapparellas | 7:8ffc2f64b0f8 | 547 | { |
GTsapparellas | 7:8ffc2f64b0f8 | 548 | // Calling LMiC os_runloop_once callback. |
GTsapparellas | 7:8ffc2f64b0f8 | 549 | os_runloop_once(); |
GTsapparellas | 7:8ffc2f64b0f8 | 550 | // Delay of 20 ms. |
GTsapparellas | 7:8ffc2f64b0f8 | 551 | wait_ms(20); |
GTsapparellas | 7:8ffc2f64b0f8 | 552 | } |
GTsapparellas | 7:8ffc2f64b0f8 | 553 | // Never arives here! |
GTsapparellas | 7:8ffc2f64b0f8 | 554 | |
GTsapparellas | 7:8ffc2f64b0f8 | 555 | }// end of loop function. |
GTsapparellas | 6:3758685f4b75 | 556 | |
GTsapparellas | 7:8ffc2f64b0f8 | 557 | /* |
GTsapparellas | 7:8ffc2f64b0f8 | 558 | * main function of type integer. |
GTsapparellas | 7:8ffc2f64b0f8 | 559 | * |
GTsapparellas | 7:8ffc2f64b0f8 | 560 | * Calling setUp as well as loop functions |
GTsapparellas | 7:8ffc2f64b0f8 | 561 | * for a repeatedly time-triggered behaviour |
GTsapparellas | 7:8ffc2f64b0f8 | 562 | * program execution. |
GTsapparellas | 7:8ffc2f64b0f8 | 563 | * |
GTsapparellas | 7:8ffc2f64b0f8 | 564 | * Input parameters: integer argc. |
GTsapparellas | 7:8ffc2f64b0f8 | 565 | * char **argv. |
GTsapparellas | 7:8ffc2f64b0f8 | 566 | * |
GTsapparellas | 7:8ffc2f64b0f8 | 567 | */ |
GTsapparellas | 7:8ffc2f64b0f8 | 568 | int main(int argc, char **argv) |
GTsapparellas | 7:8ffc2f64b0f8 | 569 | { |
GTsapparellas | 7:8ffc2f64b0f8 | 570 | // Calling setUp local function for OS initialization. |
GTsapparellas | 6:3758685f4b75 | 571 | setUp(); |
GTsapparellas | 7:8ffc2f64b0f8 | 572 | |
GTsapparellas | 7:8ffc2f64b0f8 | 573 | // Super loop running loop local funcion in a time-triggered behaviour. |
GTsapparellas | 7:8ffc2f64b0f8 | 574 | while(1) |
GTsapparellas | 7:8ffc2f64b0f8 | 575 | { |
GTsapparellas | 7:8ffc2f64b0f8 | 576 | loop(); |
GTsapparellas | 7:8ffc2f64b0f8 | 577 | } |
GTsapparellas | 7:8ffc2f64b0f8 | 578 | // Never arrives here! |
GTsapparellas | 7:8ffc2f64b0f8 | 579 | |
GTsapparellas | 7:8ffc2f64b0f8 | 580 | } // end of main function. |