LMIC transmit example for NAmote-72 with GPS
Dependencies: lib_gps lib_mpl3115a2 lmic_MOTE_L152RC mbed
Deprecated and replaced with
Import programLoRaWAN-NAMote72-Application-Demo
Demonstration of Class-A LoRaWAN device using NAMote-72
LoRaWAN Network Configuration (in Config.h)
For Over the Air (OTA) activation of an End-Device, it must be configured with the following parameters:
DEVEUI
(8 Bytes) : Fist 3 Bytes is the Organizationally Unique Identifier (OUI) followed by 5 bytes of unique ID.APPEUI
(8 Bytes)APPKey
(or DEVKEY) (16 Bytes) The parameters can be entered as shown in the figure below
LoRaWAN Transmission Configuration (in Config.h)
- Inter-Frame Delay :
One can change the delay between each frame transmission using
MS_DELAY_NEXT_TX
It is advisable thatMS_DELAY_NEXT_TX
is greater than or equal to 3sec.
- Payload Length :
The lenght of the payload (in bytes) to be transmitted can be configured using
PAYLOAD_LENGTH
- Data Rate :
The data rate can be configured as per LoRaWAN specification using the paramter
FIXED_DR
- Channel Configuration :
In the case where the End-Device is transmitting over frequencies corresponding to a block of 8 channels, the block can be specified using
CHNL_HYBRID
. The value 0 corresponds to Block A, 1 corresponds to Block B and so on. When the End-Device transmits over more than 50 channels,CHNL_HYBRID
needs to be commented out
- Transmit Power :
The power of the data to be transmitted can be configured using the parameter
FIXED_TX_POWER
. The maximum transmit power allowed is as per FCC regulation, depending upon the mode of transmission.
Serial Terminal Display
By using a serial port connection using applications such as teraterm or putty, one can view the status of the End-Device. Once the End-Device Joins the network, transmission parameters such as payload data, transmit power, battery level etc. are displayed on the terminal.
Default Application Payload
This application defaults to sending uplink data to logical port 5. The application payload consists of:
Sample Application Payload Calculation for Longitude/Latitude
Payload => 00 19 F6 352BBA A94C20 FFFF
Temperature Calculation
19H => 2510
Temp = 25/2 = 12.5 oC
Battery Level
FFH => 100 %
F6H => 96.5 %
Longitude Calculation
longitude = A94C20H => 1109507210
longitudinal coordinate = -360 + (longitude10 x 180/(223))
longitudinal coordinate = -121.93
Latitude Calculation
latitude = 352BBAH = 348460210
latitude coordinate = (latitude10 x 90/(223-1))
latitude coordinate = 37.39
main.cpp@2:a8f00db60fdb, 2015-07-02 (annotated)
- Committer:
- dudmuck
- Date:
- Thu Jul 02 01:03:13 2015 +0000
- Revision:
- 2:a8f00db60fdb
- Parent:
- 0:a5e3347bad61
- Child:
- 3:d81e4a63fb2e
support V3 mote board
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
dudmuck | 0:a5e3347bad61 | 1 | /* |
dudmuck | 0:a5e3347bad61 | 2 | / _____) _ | | |
dudmuck | 0:a5e3347bad61 | 3 | ( (____ _____ ____ _| |_ _____ ____| |__ |
dudmuck | 0:a5e3347bad61 | 4 | \____ \| ___ | (_ _) ___ |/ ___) _ \ |
dudmuck | 0:a5e3347bad61 | 5 | _____) ) ____| | | || |_| ____( (___| | | | |
dudmuck | 0:a5e3347bad61 | 6 | (______/|_____)_|_|_| \__)_____)\____)_| |_| |
dudmuck | 0:a5e3347bad61 | 7 | (C)2013 Semtech |
dudmuck | 0:a5e3347bad61 | 8 | |
dudmuck | 0:a5e3347bad61 | 9 | Description: MBED example application |
dudmuck | 0:a5e3347bad61 | 10 | |
dudmuck | 0:a5e3347bad61 | 11 | License: Revised BSD License, see LICENSE.TXT file include in the project |
dudmuck | 0:a5e3347bad61 | 12 | |
dudmuck | 0:a5e3347bad61 | 13 | Maintainer: Miguel Luis and Gregory Cristian |
dudmuck | 0:a5e3347bad61 | 14 | */ |
dudmuck | 0:a5e3347bad61 | 15 | #include "mbed.h" |
dudmuck | 0:a5e3347bad61 | 16 | #include "lmic.h" |
dudmuck | 0:a5e3347bad61 | 17 | #include "mpl3115a2.h" |
dudmuck | 0:a5e3347bad61 | 18 | #include "gps.h" |
dudmuck | 0:a5e3347bad61 | 19 | #include "debug.h" |
dudmuck | 0:a5e3347bad61 | 20 | |
dudmuck | 2:a8f00db60fdb | 21 | |
dudmuck | 0:a5e3347bad61 | 22 | #define SENET_F |
dudmuck | 0:a5e3347bad61 | 23 | //#define SMTC |
dudmuck | 0:a5e3347bad61 | 24 | |
dudmuck | 2:a8f00db60fdb | 25 | typedef enum { |
dudmuck | 2:a8f00db60fdb | 26 | MOTE_NONE = 0, |
dudmuck | 2:a8f00db60fdb | 27 | MOTE_V2, |
dudmuck | 2:a8f00db60fdb | 28 | MOTE_V3 |
dudmuck | 2:a8f00db60fdb | 29 | } mote_version_e; |
dudmuck | 2:a8f00db60fdb | 30 | mote_version_e mote_version = MOTE_NONE; |
dudmuck | 2:a8f00db60fdb | 31 | |
dudmuck | 2:a8f00db60fdb | 32 | DigitalOut pc_7(PC_7); |
dudmuck | 2:a8f00db60fdb | 33 | DigitalIn pc_1(PC_1); |
dudmuck | 2:a8f00db60fdb | 34 | |
dudmuck | 2:a8f00db60fdb | 35 | |
dudmuck | 0:a5e3347bad61 | 36 | /* ****************************************** */ |
dudmuck | 0:a5e3347bad61 | 37 | /* ***** Basic App and Network Parameters *** */ |
dudmuck | 0:a5e3347bad61 | 38 | /* ****************************************** */ |
dudmuck | 0:a5e3347bad61 | 39 | // Hybrid Mode must be defined in lmic.h // |
dudmuck | 0:a5e3347bad61 | 40 | // DevEUI and Keys defined by Activation type // |
dudmuck | 0:a5e3347bad61 | 41 | #define APP_DATA_SIZE 11 |
dudmuck | 0:a5e3347bad61 | 42 | #define APP_ACK 0 |
dudmuck | 0:a5e3347bad61 | 43 | #define DELAY_NEXT_TX 10 |
dudmuck | 0:a5e3347bad61 | 44 | #ifdef SMTC |
dudmuck | 0:a5e3347bad61 | 45 | #define OVER_THE_AIR_ACTIVATION 0 |
dudmuck | 0:a5e3347bad61 | 46 | #else |
dudmuck | 0:a5e3347bad61 | 47 | #define OVER_THE_AIR_ACTIVATION 1 |
dudmuck | 0:a5e3347bad61 | 48 | #endif /* SMTC */ |
dudmuck | 0:a5e3347bad61 | 49 | |
dudmuck | 0:a5e3347bad61 | 50 | /* ***************************************** */ |
dudmuck | 0:a5e3347bad61 | 51 | |
dudmuck | 0:a5e3347bad61 | 52 | #define LED_RED PB_1 |
dudmuck | 0:a5e3347bad61 | 53 | #define LED_YEL PB_10 |
dudmuck | 0:a5e3347bad61 | 54 | |
dudmuck | 0:a5e3347bad61 | 55 | static DigitalOut led1(LED_RED); |
dudmuck | 0:a5e3347bad61 | 56 | static DigitalOut led2(LED_YEL); |
dudmuck | 0:a5e3347bad61 | 57 | |
dudmuck | 0:a5e3347bad61 | 58 | /* gps(tx, rx, en); */ |
dudmuck | 0:a5e3347bad61 | 59 | GPS gps(PB_6, PB_7, PB_11); |
dudmuck | 0:a5e3347bad61 | 60 | |
dudmuck | 0:a5e3347bad61 | 61 | I2C i2c(I2C_SDA, I2C_SCL); |
dudmuck | 0:a5e3347bad61 | 62 | DigitalIn i2c_int_pin(PB_4); |
dudmuck | 0:a5e3347bad61 | 63 | MPL3115A2 mpl3115a2(i2c, i2c_int_pin); |
dudmuck | 0:a5e3347bad61 | 64 | AnalogIn bat(PA_0); |
dudmuck | 0:a5e3347bad61 | 65 | |
dudmuck | 0:a5e3347bad61 | 66 | ////////////////////////////////////////////////// |
dudmuck | 0:a5e3347bad61 | 67 | // CONFIGURATION (FOR APPLICATION CALLBACKS BELOW) |
dudmuck | 0:a5e3347bad61 | 68 | ////////////////////////////////////////////////// |
dudmuck | 0:a5e3347bad61 | 69 | #ifdef SENET_F |
dudmuck | 0:a5e3347bad61 | 70 | // application router ID (LSBF) |
dudmuck | 0:a5e3347bad61 | 71 | static const u1_t APPEUI[8] = { 0x01, 0x00, 0x01, 0x00, 0x00, 0x0c, 0x25, 0x00 }; |
dudmuck | 0:a5e3347bad61 | 72 | |
dudmuck | 0:a5e3347bad61 | 73 | // unique device ID (LSBF) |
dudmuck | 0:a5e3347bad61 | 74 | static const u1_t DEVEUI[8] = { 0x0f, 0x00, 0x00, 0x00, 0x01, 0x0c, 0x25, 0x00 }; |
dudmuck | 0:a5e3347bad61 | 75 | |
dudmuck | 0:a5e3347bad61 | 76 | // device-specific AES key (derived from device EUI) |
dudmuck | 0:a5e3347bad61 | 77 | static const u1_t DEVKEY[16] = { 0xe4, 0x72, 0x71, 0xc5, 0xf5, 0x30, 0xa9, 0x9f, 0xcf, 0xc4, 0x0e, 0xab, 0xea, 0xd7, 0x19, 0x42, }; |
dudmuck | 0:a5e3347bad61 | 78 | // E4 -72 -71 -C5 -F5 -30 -A9 -9F -CF -C4 -0E -AB -EA -D7 -19 -42 |
dudmuck | 0:a5e3347bad61 | 79 | #endif /* SENET_F */ |
dudmuck | 0:a5e3347bad61 | 80 | |
dudmuck | 0:a5e3347bad61 | 81 | #ifdef SMTC |
dudmuck | 0:a5e3347bad61 | 82 | // Semtech Activation (v1.x server) |
dudmuck | 0:a5e3347bad61 | 83 | // application router ID (LSBF) |
dudmuck | 0:a5e3347bad61 | 84 | static const u1_t APPEUI[8] = { 0xAA, 0xCC, 0x11, 0x00, 0xCC, 0xEE, 0x77, 0xEE }; |
dudmuck | 0:a5e3347bad61 | 85 | |
dudmuck | 0:a5e3347bad61 | 86 | // unique device ID (LSBF) |
dudmuck | 0:a5e3347bad61 | 87 | static const u1_t DEVEUI[8] = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF }; |
dudmuck | 0:a5e3347bad61 | 88 | |
dudmuck | 0:a5e3347bad61 | 89 | // device-specific AES key (derived from device EUI) |
dudmuck | 0:a5e3347bad61 | 90 | static const u1_t DEVKEY[16] = { 0xAB, 0x89, 0xEF, 0xCD, 0x23, 0x01, 0x67, 0x45, 0x54, 0x76, 0x10, 0x32, 0xDC, 0xFE, 0x98, 0xBA }; |
dudmuck | 0:a5e3347bad61 | 91 | |
dudmuck | 0:a5e3347bad61 | 92 | static uint8_t NwkSKey[] = |
dudmuck | 0:a5e3347bad61 | 93 | { |
dudmuck | 0:a5e3347bad61 | 94 | 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, |
dudmuck | 0:a5e3347bad61 | 95 | 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C |
dudmuck | 0:a5e3347bad61 | 96 | }; |
dudmuck | 0:a5e3347bad61 | 97 | |
dudmuck | 0:a5e3347bad61 | 98 | static uint8_t ArtSKey[] = |
dudmuck | 0:a5e3347bad61 | 99 | { |
dudmuck | 0:a5e3347bad61 | 100 | 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, |
dudmuck | 0:a5e3347bad61 | 101 | 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C |
dudmuck | 0:a5e3347bad61 | 102 | }; |
dudmuck | 0:a5e3347bad61 | 103 | |
dudmuck | 0:a5e3347bad61 | 104 | #endif /* SMTC */ |
dudmuck | 0:a5e3347bad61 | 105 | |
dudmuck | 0:a5e3347bad61 | 106 | ////////////////////////////////////////////////// |
dudmuck | 0:a5e3347bad61 | 107 | // APPLICATION CALLBACKS |
dudmuck | 0:a5e3347bad61 | 108 | ////////////////////////////////////////////////// |
dudmuck | 0:a5e3347bad61 | 109 | |
dudmuck | 0:a5e3347bad61 | 110 | // provide application router ID (8 bytes, LSBF) |
dudmuck | 0:a5e3347bad61 | 111 | void os_getArtEui (u1_t* buf) { |
dudmuck | 0:a5e3347bad61 | 112 | memcpy(buf, APPEUI, 8); |
dudmuck | 0:a5e3347bad61 | 113 | } |
dudmuck | 0:a5e3347bad61 | 114 | |
dudmuck | 0:a5e3347bad61 | 115 | // provide device ID (8 bytes, LSBF) |
dudmuck | 0:a5e3347bad61 | 116 | void os_getDevEui (u1_t* buf) { |
dudmuck | 0:a5e3347bad61 | 117 | memcpy(buf, DEVEUI, 8); |
dudmuck | 0:a5e3347bad61 | 118 | } |
dudmuck | 0:a5e3347bad61 | 119 | |
dudmuck | 0:a5e3347bad61 | 120 | // provide device key (16 bytes) |
dudmuck | 0:a5e3347bad61 | 121 | void os_getDevKey (u1_t* buf) { |
dudmuck | 0:a5e3347bad61 | 122 | memcpy(buf, DEVKEY, 16); |
dudmuck | 0:a5e3347bad61 | 123 | } |
dudmuck | 0:a5e3347bad61 | 124 | |
dudmuck | 0:a5e3347bad61 | 125 | ////////////////////////////////////////////////// |
dudmuck | 0:a5e3347bad61 | 126 | // MAIN - INITIALIZATION AND STARTUP |
dudmuck | 0:a5e3347bad61 | 127 | ////////////////////////////////////////////////// |
dudmuck | 2:a8f00db60fdb | 128 | void get_mote_version() |
dudmuck | 2:a8f00db60fdb | 129 | { |
dudmuck | 2:a8f00db60fdb | 130 | char first; |
dudmuck | 2:a8f00db60fdb | 131 | |
dudmuck | 2:a8f00db60fdb | 132 | /*DigitalOut pc_7(PC_7); |
dudmuck | 2:a8f00db60fdb | 133 | DigitalIn pc_1(PC_1);*/ |
dudmuck | 2:a8f00db60fdb | 134 | |
dudmuck | 2:a8f00db60fdb | 135 | pc_7 = 1; |
dudmuck | 2:a8f00db60fdb | 136 | first = pc_1; |
dudmuck | 2:a8f00db60fdb | 137 | pc_7 = 0; |
dudmuck | 2:a8f00db60fdb | 138 | if (first && !pc_1) { |
dudmuck | 2:a8f00db60fdb | 139 | //printf("v2-mote\r\n"); |
dudmuck | 2:a8f00db60fdb | 140 | mote_version = MOTE_V2; |
dudmuck | 2:a8f00db60fdb | 141 | } else { |
dudmuck | 2:a8f00db60fdb | 142 | //printf("v3-mote\r\n"); |
dudmuck | 2:a8f00db60fdb | 143 | mote_version = MOTE_V3; |
dudmuck | 2:a8f00db60fdb | 144 | } |
dudmuck | 2:a8f00db60fdb | 145 | } |
dudmuck | 0:a5e3347bad61 | 146 | |
dudmuck | 0:a5e3347bad61 | 147 | // initial job |
dudmuck | 0:a5e3347bad61 | 148 | static void initfunc (osjob_t* j) { |
dudmuck | 0:a5e3347bad61 | 149 | debug_str("B: INITFUNC\n"); |
dudmuck | 0:a5e3347bad61 | 150 | // reset MAC state |
dudmuck | 0:a5e3347bad61 | 151 | LMIC_reset(); |
dudmuck | 0:a5e3347bad61 | 152 | // start joining |
dudmuck | 0:a5e3347bad61 | 153 | #if( OVER_THE_AIR_ACTIVATION != 0 ) |
dudmuck | 0:a5e3347bad61 | 154 | LMIC_startJoining(); |
dudmuck | 0:a5e3347bad61 | 155 | #else |
dudmuck | 0:a5e3347bad61 | 156 | devaddr_t *serial_id = (devaddr_t *) 0x1FF800d0; // cat3 device stm32l152rc |
dudmuck | 0:a5e3347bad61 | 157 | LMIC_setSession( 0, *serial_id, NwkSKey, ArtSKey ); |
dudmuck | 0:a5e3347bad61 | 158 | debug_val("SN = ", *serial_id); |
dudmuck | 0:a5e3347bad61 | 159 | #endif |
dudmuck | 0:a5e3347bad61 | 160 | // init done - onEvent() callback will be invoked... |
dudmuck | 0:a5e3347bad61 | 161 | |
dudmuck | 0:a5e3347bad61 | 162 | //DEBUG_STR("E: INITFUNC"); |
dudmuck | 2:a8f00db60fdb | 163 | get_mote_version(); |
dudmuck | 2:a8f00db60fdb | 164 | if (mote_version == MOTE_V3) |
dudmuck | 2:a8f00db60fdb | 165 | gps.en_invert = false; |
dudmuck | 2:a8f00db60fdb | 166 | else |
dudmuck | 2:a8f00db60fdb | 167 | gps.en_invert = true; |
dudmuck | 2:a8f00db60fdb | 168 | |
dudmuck | 0:a5e3347bad61 | 169 | gps.init(); |
dudmuck | 0:a5e3347bad61 | 170 | gps.enable(1); |
dudmuck | 0:a5e3347bad61 | 171 | //gps.verbose = 1; |
dudmuck | 0:a5e3347bad61 | 172 | |
dudmuck | 0:a5e3347bad61 | 173 | mpl3115a2.init(); |
dudmuck | 0:a5e3347bad61 | 174 | } |
dudmuck | 0:a5e3347bad61 | 175 | |
dudmuck | 0:a5e3347bad61 | 176 | int main(void) |
dudmuck | 0:a5e3347bad61 | 177 | { |
dudmuck | 0:a5e3347bad61 | 178 | osjob_t initjob; |
dudmuck | 0:a5e3347bad61 | 179 | |
dudmuck | 0:a5e3347bad61 | 180 | // initialize runtime env |
dudmuck | 0:a5e3347bad61 | 181 | os_init(); |
dudmuck | 0:a5e3347bad61 | 182 | debug_init(); |
dudmuck | 0:a5e3347bad61 | 183 | // setup initial job |
dudmuck | 0:a5e3347bad61 | 184 | os_setCallback(&initjob, initfunc); |
dudmuck | 0:a5e3347bad61 | 185 | // execute scheduled jobs and events |
dudmuck | 0:a5e3347bad61 | 186 | os_runloop(); |
dudmuck | 0:a5e3347bad61 | 187 | // (not reached) |
dudmuck | 0:a5e3347bad61 | 188 | } |
dudmuck | 0:a5e3347bad61 | 189 | |
dudmuck | 0:a5e3347bad61 | 190 | ////////////////////////////////////////////////// |
dudmuck | 0:a5e3347bad61 | 191 | // LMIC EVENT CALLBACK |
dudmuck | 0:a5e3347bad61 | 192 | ////////////////////////////////////////////////// |
dudmuck | 0:a5e3347bad61 | 193 | osjob_t rxLedJob; |
dudmuck | 0:a5e3347bad61 | 194 | osjob_t txLedJob; |
dudmuck | 0:a5e3347bad61 | 195 | osjob_t sendFrameJob; |
dudmuck | 0:a5e3347bad61 | 196 | |
dudmuck | 0:a5e3347bad61 | 197 | static void onRxLed (osjob_t* j) { |
dudmuck | 0:a5e3347bad61 | 198 | debug_val("LED2 = ", 1 ); |
dudmuck | 0:a5e3347bad61 | 199 | led2 = 1; |
dudmuck | 0:a5e3347bad61 | 200 | } |
dudmuck | 0:a5e3347bad61 | 201 | |
dudmuck | 0:a5e3347bad61 | 202 | static void onTxLed (osjob_t* j) { |
dudmuck | 0:a5e3347bad61 | 203 | debug_val("LED1 = ", 1 ); |
dudmuck | 0:a5e3347bad61 | 204 | led1 = 1; |
dudmuck | 0:a5e3347bad61 | 205 | } |
dudmuck | 0:a5e3347bad61 | 206 | |
dudmuck | 0:a5e3347bad61 | 207 | static bool AppLedStateOn = false; |
dudmuck | 0:a5e3347bad61 | 208 | |
dudmuck | 0:a5e3347bad61 | 209 | static void PrepareDataFrame( void ) |
dudmuck | 0:a5e3347bad61 | 210 | { |
dudmuck | 0:a5e3347bad61 | 211 | uint16_t altitudeGps; |
dudmuck | 0:a5e3347bad61 | 212 | //int i; |
dudmuck | 0:a5e3347bad61 | 213 | |
dudmuck | 0:a5e3347bad61 | 214 | gps.service(); |
dudmuck | 0:a5e3347bad61 | 215 | printf("lat:%f long:%f\r\n", gps.Latitude, gps.Longitude); |
dudmuck | 0:a5e3347bad61 | 216 | // printf("lat:%d long:%d\r\n", gps.LatitudeBinary, gps.LongitudeBinary); |
dudmuck | 0:a5e3347bad61 | 217 | mpl3115a2.ReadTemperature(); |
dudmuck | 0:a5e3347bad61 | 218 | //printf("temp:%d\r\n", (int)mpl3115a2.Temperature); |
dudmuck | 0:a5e3347bad61 | 219 | |
dudmuck | 0:a5e3347bad61 | 220 | // immediately prepare next transmission |
dudmuck | 0:a5e3347bad61 | 221 | //LMIC.frame[0] = LMIC.rxq.snr; |
dudmuck | 0:a5e3347bad61 | 222 | LMIC.frame[0] = AppLedStateOn; // (bit 0 == 1) => LED on |
dudmuck | 0:a5e3347bad61 | 223 | LMIC.frame[1] = (int)mpl3115a2.Temperature; // Signed degrees Celcius in half degree units. So, +/-63 C |
dudmuck | 0:a5e3347bad61 | 224 | LMIC.frame[2] = (bat.read_u16() >> 8) + (bat.read_u16() >> 9) ; // per LoRaMAC spec; 0=Charging; 1...254 = level, 255 = N/A |
dudmuck | 0:a5e3347bad61 | 225 | LMIC.frame[3] = ( gps.LatitudeBinary >> 16 ) & 0xFF; |
dudmuck | 0:a5e3347bad61 | 226 | LMIC.frame[4] = ( gps.LatitudeBinary >> 8 ) & 0xFF; |
dudmuck | 0:a5e3347bad61 | 227 | LMIC.frame[5] = gps.LatitudeBinary & 0xFF; |
dudmuck | 0:a5e3347bad61 | 228 | LMIC.frame[6] = ( gps.LongitudeBinary >> 16 ) & 0xFF; |
dudmuck | 0:a5e3347bad61 | 229 | LMIC.frame[7] = ( gps.LongitudeBinary >> 8 ) & 0xFF; |
dudmuck | 0:a5e3347bad61 | 230 | LMIC.frame[8] = gps.LongitudeBinary & 0xFF; |
dudmuck | 0:a5e3347bad61 | 231 | |
dudmuck | 0:a5e3347bad61 | 232 | altitudeGps = atoi(gps.NmeaGpsData.NmeaAltitude); |
dudmuck | 0:a5e3347bad61 | 233 | printf("alt:%d\r\n", altitudeGps); |
dudmuck | 0:a5e3347bad61 | 234 | LMIC.frame[9] = ( altitudeGps >> 8 ) & 0xFF; |
dudmuck | 0:a5e3347bad61 | 235 | LMIC.frame[10] = altitudeGps & 0xFF; |
dudmuck | 0:a5e3347bad61 | 236 | } |
dudmuck | 0:a5e3347bad61 | 237 | |
dudmuck | 0:a5e3347bad61 | 238 | static void onSendFrame (osjob_t* j) { |
dudmuck | 0:a5e3347bad61 | 239 | PrepareDataFrame( ); |
dudmuck | 0:a5e3347bad61 | 240 | // schedule transmission (port 1, data[], datalen 1, ACK requested) |
dudmuck | 0:a5e3347bad61 | 241 | // (will be sent as soon as duty cycle permits) |
dudmuck | 0:a5e3347bad61 | 242 | LMIC_setTxData2(5, LMIC.frame, APP_DATA_SIZE, APP_ACK); |
dudmuck | 0:a5e3347bad61 | 243 | } |
dudmuck | 0:a5e3347bad61 | 244 | |
dudmuck | 0:a5e3347bad61 | 245 | void onEvent (ev_t ev) { |
dudmuck | 0:a5e3347bad61 | 246 | |
dudmuck | 0:a5e3347bad61 | 247 | debug_event(ev); |
dudmuck | 0:a5e3347bad61 | 248 | |
dudmuck | 0:a5e3347bad61 | 249 | gps.service(); |
dudmuck | 0:a5e3347bad61 | 250 | |
dudmuck | 0:a5e3347bad61 | 251 | switch(ev) |
dudmuck | 0:a5e3347bad61 | 252 | { |
dudmuck | 0:a5e3347bad61 | 253 | // network joined, session established |
dudmuck | 0:a5e3347bad61 | 254 | case EV_JOINED: |
dudmuck | 0:a5e3347bad61 | 255 | debug_val("Net ID = ", LMIC.netid); |
dudmuck | 0:a5e3347bad61 | 256 | goto tx; |
dudmuck | 0:a5e3347bad61 | 257 | // scheduled data sent (optionally data received) |
dudmuck | 0:a5e3347bad61 | 258 | case EV_TXCOMPLETE: |
dudmuck | 0:a5e3347bad61 | 259 | if(LMIC.dataLen) |
dudmuck | 0:a5e3347bad61 | 260 | { // data received in rx slot after tx |
dudmuck | 0:a5e3347bad61 | 261 | debug_buf(LMIC.frame+LMIC.dataBeg, LMIC.dataLen); |
dudmuck | 0:a5e3347bad61 | 262 | if(LMIC.dataLen == 1) { // set LED state if exactly one byte is received |
dudmuck | 0:a5e3347bad61 | 263 | AppLedStateOn = LMIC.frame[LMIC.dataBeg] & 0x01; |
dudmuck | 0:a5e3347bad61 | 264 | debug_val("LED3 = ", AppLedStateOn ? 0 : 1 ); |
dudmuck | 0:a5e3347bad61 | 265 | } |
dudmuck | 0:a5e3347bad61 | 266 | } |
dudmuck | 0:a5e3347bad61 | 267 | if((LMIC.txrxFlags & (TXRX_DNW1|TXRX_DNW2) )!= 0 ) |
dudmuck | 0:a5e3347bad61 | 268 | { |
dudmuck | 0:a5e3347bad61 | 269 | debug_val("LED2 = ", 0 ); |
dudmuck | 0:a5e3347bad61 | 270 | led2 = 0; |
dudmuck | 0:a5e3347bad61 | 271 | os_setTimedCallback( &rxLedJob, os_getTime() + ms2osticks(15), onRxLed ); |
dudmuck | 0:a5e3347bad61 | 272 | } |
dudmuck | 0:a5e3347bad61 | 273 | tx: |
dudmuck | 0:a5e3347bad61 | 274 | os_setTimedCallback( &sendFrameJob, os_getTime() + sec2osticks(DELAY_NEXT_TX), onSendFrame ); // Change the Tx periodicity |
dudmuck | 0:a5e3347bad61 | 275 | //onSendFrame(NULL); |
dudmuck | 0:a5e3347bad61 | 276 | |
dudmuck | 0:a5e3347bad61 | 277 | // Blink Tx LED |
dudmuck | 0:a5e3347bad61 | 278 | debug_val("LED1 = ", 0 ); |
dudmuck | 0:a5e3347bad61 | 279 | led1 = 0; |
dudmuck | 0:a5e3347bad61 | 280 | |
dudmuck | 0:a5e3347bad61 | 281 | os_setTimedCallback( &txLedJob, os_getTime() + ms2osticks(25), onTxLed ); |
dudmuck | 0:a5e3347bad61 | 282 | break; |
dudmuck | 0:a5e3347bad61 | 283 | default: |
dudmuck | 0:a5e3347bad61 | 284 | break; |
dudmuck | 0:a5e3347bad61 | 285 | } |
dudmuck | 0:a5e3347bad61 | 286 | } |