example using mbed loramac with GPS in application layer

Dependencies:   lib_gps

This repository can work on NAmote72.

This main.cpp generates Cayenne LPP GPS payload.

See mbed documentation for provisioning instructions.

Committer:
Wayne Roberts
Date:
Thu Jan 03 16:18:09 2019 -0800
Revision:
0:2e040cc7f7b8
initial commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Wayne Roberts 0:2e040cc7f7b8 1 /**
Wayne Roberts 0:2e040cc7f7b8 2 * Copyright (c) 2017, Arm Limited and affiliates.
Wayne Roberts 0:2e040cc7f7b8 3 * SPDX-License-Identifier: Apache-2.0
Wayne Roberts 0:2e040cc7f7b8 4 *
Wayne Roberts 0:2e040cc7f7b8 5 * Licensed under the Apache License, Version 2.0 (the "License");
Wayne Roberts 0:2e040cc7f7b8 6 * you may not use this file except in compliance with the License.
Wayne Roberts 0:2e040cc7f7b8 7 * You may obtain a copy of the License at
Wayne Roberts 0:2e040cc7f7b8 8 *
Wayne Roberts 0:2e040cc7f7b8 9 * http://www.apache.org/licenses/LICENSE-2.0
Wayne Roberts 0:2e040cc7f7b8 10 *
Wayne Roberts 0:2e040cc7f7b8 11 * Unless required by applicable law or agreed to in writing, software
Wayne Roberts 0:2e040cc7f7b8 12 * distributed under the License is distributed on an "AS IS" BASIS,
Wayne Roberts 0:2e040cc7f7b8 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Wayne Roberts 0:2e040cc7f7b8 14 * See the License for the specific language governing permissions and
Wayne Roberts 0:2e040cc7f7b8 15 * limitations under the License.
Wayne Roberts 0:2e040cc7f7b8 16 */
Wayne Roberts 0:2e040cc7f7b8 17 #include <stdio.h>
Wayne Roberts 0:2e040cc7f7b8 18
Wayne Roberts 0:2e040cc7f7b8 19 #include "lorawan/LoRaWANInterface.h"
Wayne Roberts 0:2e040cc7f7b8 20 #include "lorawan/system/lorawan_data_structures.h"
Wayne Roberts 0:2e040cc7f7b8 21 #include "events/EventQueue.h"
Wayne Roberts 0:2e040cc7f7b8 22
Wayne Roberts 0:2e040cc7f7b8 23 #include "mbed.h"
Wayne Roberts 0:2e040cc7f7b8 24 // Application helpers
Wayne Roberts 0:2e040cc7f7b8 25 #include "gps.h"
Wayne Roberts 0:2e040cc7f7b8 26 #include "trace_helper.h"
Wayne Roberts 0:2e040cc7f7b8 27 #include "lora_radio_helper.h"
Wayne Roberts 0:2e040cc7f7b8 28
Wayne Roberts 0:2e040cc7f7b8 29 using namespace events;
Wayne Roberts 0:2e040cc7f7b8 30
Wayne Roberts 0:2e040cc7f7b8 31 // Max payload size can be LORAMAC_PHY_MAXPAYLOAD.
Wayne Roberts 0:2e040cc7f7b8 32 // This example only communicates with much shorter messages (<30 bytes).
Wayne Roberts 0:2e040cc7f7b8 33 // If longer messages are used, these buffers must be changed accordingly.
Wayne Roberts 0:2e040cc7f7b8 34 uint8_t tx_buffer[30];
Wayne Roberts 0:2e040cc7f7b8 35 uint8_t rx_buffer[30];
Wayne Roberts 0:2e040cc7f7b8 36
Wayne Roberts 0:2e040cc7f7b8 37 /*
Wayne Roberts 0:2e040cc7f7b8 38 * Sets up an application dependent transmission timer in ms. Used only when Duty Cycling is off for testing
Wayne Roberts 0:2e040cc7f7b8 39 */
Wayne Roberts 0:2e040cc7f7b8 40 #define TX_TIMER 10000
Wayne Roberts 0:2e040cc7f7b8 41
Wayne Roberts 0:2e040cc7f7b8 42 /**
Wayne Roberts 0:2e040cc7f7b8 43 * Maximum number of events for the event queue.
Wayne Roberts 0:2e040cc7f7b8 44 * 10 is the safe number for the stack events, however, if application
Wayne Roberts 0:2e040cc7f7b8 45 * also uses the queue for whatever purposes, this number should be increased.
Wayne Roberts 0:2e040cc7f7b8 46 */
Wayne Roberts 0:2e040cc7f7b8 47 #define MAX_NUMBER_OF_EVENTS 10
Wayne Roberts 0:2e040cc7f7b8 48
Wayne Roberts 0:2e040cc7f7b8 49 /**
Wayne Roberts 0:2e040cc7f7b8 50 * Maximum number of retries for CONFIRMED messages before giving up
Wayne Roberts 0:2e040cc7f7b8 51 */
Wayne Roberts 0:2e040cc7f7b8 52 #define CONFIRMED_MSG_RETRY_COUNTER 3
Wayne Roberts 0:2e040cc7f7b8 53
Wayne Roberts 0:2e040cc7f7b8 54 /**
Wayne Roberts 0:2e040cc7f7b8 55 * Dummy pin for dummy sensor
Wayne Roberts 0:2e040cc7f7b8 56 */
Wayne Roberts 0:2e040cc7f7b8 57 #define PC_9 0
Wayne Roberts 0:2e040cc7f7b8 58
Wayne Roberts 0:2e040cc7f7b8 59 /**
Wayne Roberts 0:2e040cc7f7b8 60 * Dummy sensor class object
Wayne Roberts 0:2e040cc7f7b8 61 */
Wayne Roberts 0:2e040cc7f7b8 62 //DS1820 ds1820(PC_9);
Wayne Roberts 0:2e040cc7f7b8 63
Wayne Roberts 0:2e040cc7f7b8 64 /**
Wayne Roberts 0:2e040cc7f7b8 65 * This event queue is the global event queue for both the
Wayne Roberts 0:2e040cc7f7b8 66 * application and stack. To conserve memory, the stack is designed to run
Wayne Roberts 0:2e040cc7f7b8 67 * in the same thread as the application and the application is responsible for
Wayne Roberts 0:2e040cc7f7b8 68 * providing an event queue to the stack that will be used for ISR deferment as
Wayne Roberts 0:2e040cc7f7b8 69 * well as application information event queuing.
Wayne Roberts 0:2e040cc7f7b8 70 */
Wayne Roberts 0:2e040cc7f7b8 71 static EventQueue ev_queue(MAX_NUMBER_OF_EVENTS * EVENTS_EVENT_SIZE);
Wayne Roberts 0:2e040cc7f7b8 72
Wayne Roberts 0:2e040cc7f7b8 73 /**
Wayne Roberts 0:2e040cc7f7b8 74 * Event handler.
Wayne Roberts 0:2e040cc7f7b8 75 *
Wayne Roberts 0:2e040cc7f7b8 76 * This will be passed to the LoRaWAN stack to queue events for the
Wayne Roberts 0:2e040cc7f7b8 77 * application which in turn drive the application.
Wayne Roberts 0:2e040cc7f7b8 78 */
Wayne Roberts 0:2e040cc7f7b8 79 static void lora_event_handler(lorawan_event_t event);
Wayne Roberts 0:2e040cc7f7b8 80
Wayne Roberts 0:2e040cc7f7b8 81 /**
Wayne Roberts 0:2e040cc7f7b8 82 * Constructing Mbed LoRaWANInterface and passing it down the radio object.
Wayne Roberts 0:2e040cc7f7b8 83 */
Wayne Roberts 0:2e040cc7f7b8 84 static LoRaWANInterface lorawan(radio);
Wayne Roberts 0:2e040cc7f7b8 85
Wayne Roberts 0:2e040cc7f7b8 86 /**
Wayne Roberts 0:2e040cc7f7b8 87 * Application specific callbacks
Wayne Roberts 0:2e040cc7f7b8 88 */
Wayne Roberts 0:2e040cc7f7b8 89 static lorawan_app_callbacks_t callbacks;
Wayne Roberts 0:2e040cc7f7b8 90
Wayne Roberts 0:2e040cc7f7b8 91 #ifdef TARGET_MOTE_L152RC
Wayne Roberts 0:2e040cc7f7b8 92 GPS gps(PB_6, PB_7, PB_11); // on-board GPS pins (tx, rx, en)
Wayne Roberts 0:2e040cc7f7b8 93 #elif defined(TARGET_FF_MORPHO)
Wayne Roberts 0:2e040cc7f7b8 94 /* https://www.sparkfun.com/products/13740 */
Wayne Roberts 0:2e040cc7f7b8 95 #ifdef TARGET_DISCO_L072CZ_LRWAN1
Wayne Roberts 0:2e040cc7f7b8 96 GPS gps(PA_9, PA_10, NC);
Wayne Roberts 0:2e040cc7f7b8 97 #else
Wayne Roberts 0:2e040cc7f7b8 98 GPS gps(PC_10, PC_11, NC);
Wayne Roberts 0:2e040cc7f7b8 99 #endif
Wayne Roberts 0:2e040cc7f7b8 100 #endif
Wayne Roberts 0:2e040cc7f7b8 101
Wayne Roberts 0:2e040cc7f7b8 102 void gps_service()
Wayne Roberts 0:2e040cc7f7b8 103 {
Wayne Roberts 0:2e040cc7f7b8 104 //int alt;
Wayne Roberts 0:2e040cc7f7b8 105
Wayne Roberts 0:2e040cc7f7b8 106 gps.service();
Wayne Roberts 0:2e040cc7f7b8 107
Wayne Roberts 0:2e040cc7f7b8 108 //alt = atoi( gps.NmeaGpsData.NmeaAltitude );
Wayne Roberts 0:2e040cc7f7b8 109 //printf("lat:%f lon:%f alt:%d\r\n", gps.Latitude, gps.Longitude, alt);
Wayne Roberts 0:2e040cc7f7b8 110 }
Wayne Roberts 0:2e040cc7f7b8 111
Wayne Roberts 0:2e040cc7f7b8 112 #ifdef TARGET_MOTE_L152RC
Wayne Roberts 0:2e040cc7f7b8 113 typedef enum
Wayne Roberts 0:2e040cc7f7b8 114 {
Wayne Roberts 0:2e040cc7f7b8 115 BOARD_VERSION_NONE = 0,
Wayne Roberts 0:2e040cc7f7b8 116 BOARD_VERSION_2,
Wayne Roberts 0:2e040cc7f7b8 117 BOARD_VERSION_3,
Wayne Roberts 0:2e040cc7f7b8 118 }BoardVersion_t;
Wayne Roberts 0:2e040cc7f7b8 119
Wayne Roberts 0:2e040cc7f7b8 120 DigitalOut Pc7( PC_7 );
Wayne Roberts 0:2e040cc7f7b8 121 DigitalIn Pc1( PC_1 );
Wayne Roberts 0:2e040cc7f7b8 122 BoardVersion_t BoardGetVersion( void )
Wayne Roberts 0:2e040cc7f7b8 123 {
Wayne Roberts 0:2e040cc7f7b8 124 Pc7 = 1;
Wayne Roberts 0:2e040cc7f7b8 125 char first = Pc1;
Wayne Roberts 0:2e040cc7f7b8 126 Pc7 = 0;
Wayne Roberts 0:2e040cc7f7b8 127
Wayne Roberts 0:2e040cc7f7b8 128 if( first && !Pc1 )
Wayne Roberts 0:2e040cc7f7b8 129 {
Wayne Roberts 0:2e040cc7f7b8 130 return BOARD_VERSION_2;
Wayne Roberts 0:2e040cc7f7b8 131 }
Wayne Roberts 0:2e040cc7f7b8 132 else
Wayne Roberts 0:2e040cc7f7b8 133 {
Wayne Roberts 0:2e040cc7f7b8 134 return BOARD_VERSION_3;
Wayne Roberts 0:2e040cc7f7b8 135 }
Wayne Roberts 0:2e040cc7f7b8 136 }
Wayne Roberts 0:2e040cc7f7b8 137 AnalogIn *Battery;
Wayne Roberts 0:2e040cc7f7b8 138 #endif /* TARGET_MOTE_L152RC */
Wayne Roberts 0:2e040cc7f7b8 139
Wayne Roberts 0:2e040cc7f7b8 140 /**
Wayne Roberts 0:2e040cc7f7b8 141 * Entry point for application
Wayne Roberts 0:2e040cc7f7b8 142 */
Wayne Roberts 0:2e040cc7f7b8 143 int main (void)
Wayne Roberts 0:2e040cc7f7b8 144 {
Wayne Roberts 0:2e040cc7f7b8 145 // setup tracing
Wayne Roberts 0:2e040cc7f7b8 146 setup_trace();
Wayne Roberts 0:2e040cc7f7b8 147
Wayne Roberts 0:2e040cc7f7b8 148 // stores the status of a call to LoRaWAN protocol
Wayne Roberts 0:2e040cc7f7b8 149 lorawan_status_t retcode;
Wayne Roberts 0:2e040cc7f7b8 150
Wayne Roberts 0:2e040cc7f7b8 151 #ifdef TARGET_MOTE_L152RC
Wayne Roberts 0:2e040cc7f7b8 152 switch( BoardGetVersion( ) )
Wayne Roberts 0:2e040cc7f7b8 153 {
Wayne Roberts 0:2e040cc7f7b8 154 case BOARD_VERSION_2:
Wayne Roberts 0:2e040cc7f7b8 155 Battery = new AnalogIn( PA_0 );
Wayne Roberts 0:2e040cc7f7b8 156 gps.en_invert = true;
Wayne Roberts 0:2e040cc7f7b8 157 printf("v2-mote\r\n");
Wayne Roberts 0:2e040cc7f7b8 158 break;
Wayne Roberts 0:2e040cc7f7b8 159 case BOARD_VERSION_3:
Wayne Roberts 0:2e040cc7f7b8 160 Battery = new AnalogIn( PA_1 );
Wayne Roberts 0:2e040cc7f7b8 161 gps.en_invert = false;
Wayne Roberts 0:2e040cc7f7b8 162 printf("v3-mote\r\n");
Wayne Roberts 0:2e040cc7f7b8 163 break;
Wayne Roberts 0:2e040cc7f7b8 164 default:
Wayne Roberts 0:2e040cc7f7b8 165 break;
Wayne Roberts 0:2e040cc7f7b8 166 }
Wayne Roberts 0:2e040cc7f7b8 167 #endif /* TARGET_MOTE_L152RC */
Wayne Roberts 0:2e040cc7f7b8 168 gps.init();
Wayne Roberts 0:2e040cc7f7b8 169 gps.enable(1);
Wayne Roberts 0:2e040cc7f7b8 170 gps.m_uart.baud(9600); // override platform serial baud rate
Wayne Roberts 0:2e040cc7f7b8 171
Wayne Roberts 0:2e040cc7f7b8 172 // Initialize LoRaWAN stack
Wayne Roberts 0:2e040cc7f7b8 173 if (lorawan.initialize(&ev_queue) != LORAWAN_STATUS_OK) {
Wayne Roberts 0:2e040cc7f7b8 174 printf("\r\n LoRa initialization failed! \r\n");
Wayne Roberts 0:2e040cc7f7b8 175 return -1;
Wayne Roberts 0:2e040cc7f7b8 176 }
Wayne Roberts 0:2e040cc7f7b8 177
Wayne Roberts 0:2e040cc7f7b8 178 printf("\r\n Mbed LoRaWANStack initialized \r\n");
Wayne Roberts 0:2e040cc7f7b8 179
Wayne Roberts 0:2e040cc7f7b8 180 // prepare application callbacks
Wayne Roberts 0:2e040cc7f7b8 181 callbacks.events = mbed::callback(lora_event_handler);
Wayne Roberts 0:2e040cc7f7b8 182 lorawan.add_app_callbacks(&callbacks);
Wayne Roberts 0:2e040cc7f7b8 183
Wayne Roberts 0:2e040cc7f7b8 184 // Set number of retries in case of CONFIRMED messages
Wayne Roberts 0:2e040cc7f7b8 185 if (lorawan.set_confirmed_msg_retries(CONFIRMED_MSG_RETRY_COUNTER)
Wayne Roberts 0:2e040cc7f7b8 186 != LORAWAN_STATUS_OK) {
Wayne Roberts 0:2e040cc7f7b8 187 printf("\r\n set_confirmed_msg_retries failed! \r\n\r\n");
Wayne Roberts 0:2e040cc7f7b8 188 return -1;
Wayne Roberts 0:2e040cc7f7b8 189 }
Wayne Roberts 0:2e040cc7f7b8 190
Wayne Roberts 0:2e040cc7f7b8 191 printf("\r\n CONFIRMED message retries : %d \r\n",
Wayne Roberts 0:2e040cc7f7b8 192 CONFIRMED_MSG_RETRY_COUNTER);
Wayne Roberts 0:2e040cc7f7b8 193
Wayne Roberts 0:2e040cc7f7b8 194 // Enable adaptive data rate
Wayne Roberts 0:2e040cc7f7b8 195 if (lorawan.enable_adaptive_datarate() != LORAWAN_STATUS_OK) {
Wayne Roberts 0:2e040cc7f7b8 196 printf("\r\n enable_adaptive_datarate failed! \r\n");
Wayne Roberts 0:2e040cc7f7b8 197 return -1;
Wayne Roberts 0:2e040cc7f7b8 198 }
Wayne Roberts 0:2e040cc7f7b8 199
Wayne Roberts 0:2e040cc7f7b8 200 printf("\r\n Adaptive data rate (ADR) - Enabled \r\n");
Wayne Roberts 0:2e040cc7f7b8 201
Wayne Roberts 0:2e040cc7f7b8 202 retcode = lorawan.connect();
Wayne Roberts 0:2e040cc7f7b8 203
Wayne Roberts 0:2e040cc7f7b8 204 if (retcode == LORAWAN_STATUS_OK ||
Wayne Roberts 0:2e040cc7f7b8 205 retcode == LORAWAN_STATUS_CONNECT_IN_PROGRESS) {
Wayne Roberts 0:2e040cc7f7b8 206 } else {
Wayne Roberts 0:2e040cc7f7b8 207 printf("\r\n Connection error, code = %d \r\n", retcode);
Wayne Roberts 0:2e040cc7f7b8 208 return -1;
Wayne Roberts 0:2e040cc7f7b8 209 }
Wayne Roberts 0:2e040cc7f7b8 210
Wayne Roberts 0:2e040cc7f7b8 211 printf("\r\n Connection - In Progress ...\r\n");
Wayne Roberts 0:2e040cc7f7b8 212
Wayne Roberts 0:2e040cc7f7b8 213 // make your event queue dispatching events forever
Wayne Roberts 0:2e040cc7f7b8 214 ev_queue.dispatch_forever();
Wayne Roberts 0:2e040cc7f7b8 215
Wayne Roberts 0:2e040cc7f7b8 216 return 0;
Wayne Roberts 0:2e040cc7f7b8 217 }
Wayne Roberts 0:2e040cc7f7b8 218
Wayne Roberts 0:2e040cc7f7b8 219 #define LPP_DIGITAL_INPUT 0 // 1 byte
Wayne Roberts 0:2e040cc7f7b8 220 #define LPP_DIGITAL_OUTPUT 1 // 1 byte
Wayne Roberts 0:2e040cc7f7b8 221 #define LPP_ANALOG_INPUT 2 // 2 bytes, 0.01 signed
Wayne Roberts 0:2e040cc7f7b8 222 #define LPP_ANALOG_OUTPUT 3 // 2 bytes, 0.01 signed
Wayne Roberts 0:2e040cc7f7b8 223 #define LPP_LUMINOSITY 101 // 2 bytes, 1 lux unsigned
Wayne Roberts 0:2e040cc7f7b8 224 #define LPP_PRESENCE 102 // 1 byte, 1
Wayne Roberts 0:2e040cc7f7b8 225 #define LPP_TEMPERATURE 103 // 2 bytes, 0.1°C signed
Wayne Roberts 0:2e040cc7f7b8 226 #define LPP_RELATIVE_HUMIDITY 104 // 1 byte, 0.5% unsigned
Wayne Roberts 0:2e040cc7f7b8 227 #define LPP_ACCELEROMETER 113 // 2 bytes per axis, 0.001G
Wayne Roberts 0:2e040cc7f7b8 228 #define LPP_BAROMETRIC_PRESSURE 115 // 2 bytes 0.1 hPa Unsigned
Wayne Roberts 0:2e040cc7f7b8 229 #define LPP_GYROMETER 134 // 2 bytes per axis, 0.01 °/s
Wayne Roberts 0:2e040cc7f7b8 230 #define LPP_GPS 136 // 3 byte lon/lat 0.0001 °, 3 bytes alt 0.01m
Wayne Roberts 0:2e040cc7f7b8 231
Wayne Roberts 0:2e040cc7f7b8 232
Wayne Roberts 0:2e040cc7f7b8 233 // Data ID + Data Type + Data Size
Wayne Roberts 0:2e040cc7f7b8 234 #define LPP_DIGITAL_INPUT_SIZE 3
Wayne Roberts 0:2e040cc7f7b8 235 #define LPP_DIGITAL_OUTPUT_SIZE 3
Wayne Roberts 0:2e040cc7f7b8 236 #define LPP_ANALOG_INPUT_SIZE 4
Wayne Roberts 0:2e040cc7f7b8 237 #define LPP_ANALOG_OUTPUT_SIZE 4
Wayne Roberts 0:2e040cc7f7b8 238 #define LPP_LUMINOSITY_SIZE 4
Wayne Roberts 0:2e040cc7f7b8 239 #define LPP_PRESENCE_SIZE 3
Wayne Roberts 0:2e040cc7f7b8 240 #define LPP_TEMPERATURE_SIZE 4
Wayne Roberts 0:2e040cc7f7b8 241 #define LPP_RELATIVE_HUMIDITY_SIZE 3
Wayne Roberts 0:2e040cc7f7b8 242 #define LPP_ACCELEROMETER_SIZE 8
Wayne Roberts 0:2e040cc7f7b8 243 #define LPP_BAROMETRIC_PRESSURE_SIZE 4
Wayne Roberts 0:2e040cc7f7b8 244 #define LPP_GYROMETER_SIZE 8
Wayne Roberts 0:2e040cc7f7b8 245 #define LPP_GPS_SIZE 11
Wayne Roberts 0:2e040cc7f7b8 246
Wayne Roberts 0:2e040cc7f7b8 247 #define CAYENNE_CH_GPS 5
Wayne Roberts 0:2e040cc7f7b8 248
Wayne Roberts 0:2e040cc7f7b8 249
Wayne Roberts 0:2e040cc7f7b8 250 /**
Wayne Roberts 0:2e040cc7f7b8 251 * Sends a message to the Network Server
Wayne Roberts 0:2e040cc7f7b8 252 */
Wayne Roberts 0:2e040cc7f7b8 253 static void send_message()
Wayne Roberts 0:2e040cc7f7b8 254 {
Wayne Roberts 0:2e040cc7f7b8 255 int32_t lat, lon, alt;
Wayne Roberts 0:2e040cc7f7b8 256 uint16_t packet_len;
Wayne Roberts 0:2e040cc7f7b8 257 int16_t retcode;
Wayne Roberts 0:2e040cc7f7b8 258
Wayne Roberts 0:2e040cc7f7b8 259 lat = gps.Latitude * 10000;
Wayne Roberts 0:2e040cc7f7b8 260 lon = gps.Longitude * 10000;
Wayne Roberts 0:2e040cc7f7b8 261 alt = atoi(gps.NmeaGpsData.NmeaAltitude) * 100;
Wayne Roberts 0:2e040cc7f7b8 262
Wayne Roberts 0:2e040cc7f7b8 263 packet_len = 0;
Wayne Roberts 0:2e040cc7f7b8 264 tx_buffer[packet_len++] = CAYENNE_CH_GPS;
Wayne Roberts 0:2e040cc7f7b8 265 tx_buffer[packet_len++] = LPP_GPS;
Wayne Roberts 0:2e040cc7f7b8 266 tx_buffer[packet_len++] = lat >> 16;
Wayne Roberts 0:2e040cc7f7b8 267 tx_buffer[packet_len++] = lat >> 8;
Wayne Roberts 0:2e040cc7f7b8 268 tx_buffer[packet_len++] = lat;
Wayne Roberts 0:2e040cc7f7b8 269 tx_buffer[packet_len++] = lon >> 16;
Wayne Roberts 0:2e040cc7f7b8 270 tx_buffer[packet_len++] = lon >> 8;
Wayne Roberts 0:2e040cc7f7b8 271 tx_buffer[packet_len++] = lon;
Wayne Roberts 0:2e040cc7f7b8 272 tx_buffer[packet_len++] = alt >> 16;
Wayne Roberts 0:2e040cc7f7b8 273 tx_buffer[packet_len++] = alt >> 8;
Wayne Roberts 0:2e040cc7f7b8 274 tx_buffer[packet_len++] = alt;
Wayne Roberts 0:2e040cc7f7b8 275
Wayne Roberts 0:2e040cc7f7b8 276 retcode = lorawan.send(MBED_CONF_LORA_APP_PORT, tx_buffer, packet_len,
Wayne Roberts 0:2e040cc7f7b8 277 MSG_CONFIRMED_FLAG);
Wayne Roberts 0:2e040cc7f7b8 278
Wayne Roberts 0:2e040cc7f7b8 279 if (retcode < 0) {
Wayne Roberts 0:2e040cc7f7b8 280 retcode == LORAWAN_STATUS_WOULD_BLOCK ? printf("send - WOULD BLOCK\r\n")
Wayne Roberts 0:2e040cc7f7b8 281 : printf("\r\n send() - Error code %d \r\n", retcode);
Wayne Roberts 0:2e040cc7f7b8 282
Wayne Roberts 0:2e040cc7f7b8 283 if (retcode == LORAWAN_STATUS_WOULD_BLOCK) {
Wayne Roberts 0:2e040cc7f7b8 284 //retry in 3 seconds
Wayne Roberts 0:2e040cc7f7b8 285 if (MBED_CONF_LORA_DUTY_CYCLE_ON) {
Wayne Roberts 0:2e040cc7f7b8 286 ev_queue.call_in(3000, send_message);
Wayne Roberts 0:2e040cc7f7b8 287 }
Wayne Roberts 0:2e040cc7f7b8 288 }
Wayne Roberts 0:2e040cc7f7b8 289 return;
Wayne Roberts 0:2e040cc7f7b8 290 }
Wayne Roberts 0:2e040cc7f7b8 291 for (alt = 0; alt < packet_len; alt++) {
Wayne Roberts 0:2e040cc7f7b8 292 printf("%02x", tx_buffer[alt]);
Wayne Roberts 0:2e040cc7f7b8 293 }
Wayne Roberts 0:2e040cc7f7b8 294
Wayne Roberts 0:2e040cc7f7b8 295 alt = atoi( gps.NmeaGpsData.NmeaAltitude );
Wayne Roberts 0:2e040cc7f7b8 296 printf("\r\n %d bytes scheduled for tx\tlat:%f lon:%f alt:%d\r\n", retcode, gps.Latitude, gps.Longitude, (int)alt);
Wayne Roberts 0:2e040cc7f7b8 297 memset(tx_buffer, 0, sizeof(tx_buffer));
Wayne Roberts 0:2e040cc7f7b8 298 }
Wayne Roberts 0:2e040cc7f7b8 299
Wayne Roberts 0:2e040cc7f7b8 300 /**
Wayne Roberts 0:2e040cc7f7b8 301 * Receive a message from the Network Server
Wayne Roberts 0:2e040cc7f7b8 302 */
Wayne Roberts 0:2e040cc7f7b8 303 static void receive_message()
Wayne Roberts 0:2e040cc7f7b8 304 {
Wayne Roberts 0:2e040cc7f7b8 305 int16_t retcode;
Wayne Roberts 0:2e040cc7f7b8 306 retcode = lorawan.receive(MBED_CONF_LORA_APP_PORT, rx_buffer,
Wayne Roberts 0:2e040cc7f7b8 307 sizeof(rx_buffer),
Wayne Roberts 0:2e040cc7f7b8 308 MSG_CONFIRMED_FLAG|MSG_UNCONFIRMED_FLAG);
Wayne Roberts 0:2e040cc7f7b8 309
Wayne Roberts 0:2e040cc7f7b8 310 if (retcode < 0) {
Wayne Roberts 0:2e040cc7f7b8 311 printf("\r\n receive() - Error code %d \r\n", retcode);
Wayne Roberts 0:2e040cc7f7b8 312 return;
Wayne Roberts 0:2e040cc7f7b8 313 }
Wayne Roberts 0:2e040cc7f7b8 314
Wayne Roberts 0:2e040cc7f7b8 315 printf(" Data:");
Wayne Roberts 0:2e040cc7f7b8 316
Wayne Roberts 0:2e040cc7f7b8 317 for (uint8_t i = 0; i < retcode; i++) {
Wayne Roberts 0:2e040cc7f7b8 318 printf("%x", rx_buffer[i]);
Wayne Roberts 0:2e040cc7f7b8 319 }
Wayne Roberts 0:2e040cc7f7b8 320
Wayne Roberts 0:2e040cc7f7b8 321 printf("\r\n Data Length: %d\r\n", retcode);
Wayne Roberts 0:2e040cc7f7b8 322
Wayne Roberts 0:2e040cc7f7b8 323 memset(rx_buffer, 0, sizeof(rx_buffer));
Wayne Roberts 0:2e040cc7f7b8 324 }
Wayne Roberts 0:2e040cc7f7b8 325
Wayne Roberts 0:2e040cc7f7b8 326 /**
Wayne Roberts 0:2e040cc7f7b8 327 * Event handler
Wayne Roberts 0:2e040cc7f7b8 328 */
Wayne Roberts 0:2e040cc7f7b8 329 static void lora_event_handler(lorawan_event_t event)
Wayne Roberts 0:2e040cc7f7b8 330 {
Wayne Roberts 0:2e040cc7f7b8 331
Wayne Roberts 0:2e040cc7f7b8 332 switch (event) {
Wayne Roberts 0:2e040cc7f7b8 333 case CONNECTED:
Wayne Roberts 0:2e040cc7f7b8 334 printf("\r\n Connection - Successful ");
Wayne Roberts 0:2e040cc7f7b8 335 ev_queue.call_every(1000, gps_service);
Wayne Roberts 0:2e040cc7f7b8 336 if (MBED_CONF_LORA_DUTY_CYCLE_ON) {
Wayne Roberts 0:2e040cc7f7b8 337 printf("DUTY_ON\r\n");
Wayne Roberts 0:2e040cc7f7b8 338 send_message();
Wayne Roberts 0:2e040cc7f7b8 339 } else {
Wayne Roberts 0:2e040cc7f7b8 340 printf("(duty off)\r\n");
Wayne Roberts 0:2e040cc7f7b8 341 ev_queue.call_every(TX_TIMER, send_message);
Wayne Roberts 0:2e040cc7f7b8 342 }
Wayne Roberts 0:2e040cc7f7b8 343
Wayne Roberts 0:2e040cc7f7b8 344 break;
Wayne Roberts 0:2e040cc7f7b8 345 case DISCONNECTED:
Wayne Roberts 0:2e040cc7f7b8 346 ev_queue.break_dispatch();
Wayne Roberts 0:2e040cc7f7b8 347 printf("\r\n Disconnected Successfully \r\n");
Wayne Roberts 0:2e040cc7f7b8 348 break;
Wayne Roberts 0:2e040cc7f7b8 349 case TX_DONE:
Wayne Roberts 0:2e040cc7f7b8 350 printf("\r\n Message Sent to Network Server \r\n");
Wayne Roberts 0:2e040cc7f7b8 351 /*if (MBED_CONF_LORA_DUTY_CYCLE_ON) {
Wayne Roberts 0:2e040cc7f7b8 352 send_message();
Wayne Roberts 0:2e040cc7f7b8 353 }*/
Wayne Roberts 0:2e040cc7f7b8 354 break;
Wayne Roberts 0:2e040cc7f7b8 355 case TX_TIMEOUT:
Wayne Roberts 0:2e040cc7f7b8 356 printf("\r\nTX_TIMEOUT\r\n");
Wayne Roberts 0:2e040cc7f7b8 357 // try again
Wayne Roberts 0:2e040cc7f7b8 358 /*if (MBED_CONF_LORA_DUTY_CYCLE_ON) {
Wayne Roberts 0:2e040cc7f7b8 359 send_message();
Wayne Roberts 0:2e040cc7f7b8 360 }*/
Wayne Roberts 0:2e040cc7f7b8 361 break;
Wayne Roberts 0:2e040cc7f7b8 362 case TX_ERROR:
Wayne Roberts 0:2e040cc7f7b8 363 // no ack was received after enough retries
Wayne Roberts 0:2e040cc7f7b8 364 printf("\r\nTX_ERROR\r\n");
Wayne Roberts 0:2e040cc7f7b8 365 // try again
Wayne Roberts 0:2e040cc7f7b8 366 /*if (MBED_CONF_LORA_DUTY_CYCLE_ON) {
Wayne Roberts 0:2e040cc7f7b8 367 send_message();
Wayne Roberts 0:2e040cc7f7b8 368 }*/
Wayne Roberts 0:2e040cc7f7b8 369 break;
Wayne Roberts 0:2e040cc7f7b8 370 case TX_CRYPTO_ERROR:
Wayne Roberts 0:2e040cc7f7b8 371 printf("\r\nTX_CRYPTO_ERROR\r\n");
Wayne Roberts 0:2e040cc7f7b8 372 // try again
Wayne Roberts 0:2e040cc7f7b8 373 /*if (MBED_CONF_LORA_DUTY_CYCLE_ON) {
Wayne Roberts 0:2e040cc7f7b8 374 send_message();
Wayne Roberts 0:2e040cc7f7b8 375 }*/
Wayne Roberts 0:2e040cc7f7b8 376 break;
Wayne Roberts 0:2e040cc7f7b8 377 case TX_SCHEDULING_ERROR:
Wayne Roberts 0:2e040cc7f7b8 378 printf("\r\nTX_SCHEDULING_ERROR\r\n");
Wayne Roberts 0:2e040cc7f7b8 379 // try again
Wayne Roberts 0:2e040cc7f7b8 380 /*if (MBED_CONF_LORA_DUTY_CYCLE_ON) {
Wayne Roberts 0:2e040cc7f7b8 381 send_message();
Wayne Roberts 0:2e040cc7f7b8 382 }*/
Wayne Roberts 0:2e040cc7f7b8 383 break;
Wayne Roberts 0:2e040cc7f7b8 384 case RX_DONE:
Wayne Roberts 0:2e040cc7f7b8 385 printf("\r\n Received message from Network Server \r\n");
Wayne Roberts 0:2e040cc7f7b8 386 receive_message();
Wayne Roberts 0:2e040cc7f7b8 387 break;
Wayne Roberts 0:2e040cc7f7b8 388 case RX_TIMEOUT:
Wayne Roberts 0:2e040cc7f7b8 389 case RX_ERROR:
Wayne Roberts 0:2e040cc7f7b8 390 printf("\r\n Error in reception - Code = %d \r\n", event);
Wayne Roberts 0:2e040cc7f7b8 391 break;
Wayne Roberts 0:2e040cc7f7b8 392 case JOIN_FAILURE:
Wayne Roberts 0:2e040cc7f7b8 393 printf("\r\n OTAA Failed - Check Keys \r\n");
Wayne Roberts 0:2e040cc7f7b8 394 break;
Wayne Roberts 0:2e040cc7f7b8 395 case UPLINK_REQUIRED:
Wayne Roberts 0:2e040cc7f7b8 396 printf("\r\n Uplink required by NS \r\n");
Wayne Roberts 0:2e040cc7f7b8 397 if (MBED_CONF_LORA_DUTY_CYCLE_ON) {
Wayne Roberts 0:2e040cc7f7b8 398 send_message();
Wayne Roberts 0:2e040cc7f7b8 399 }
Wayne Roberts 0:2e040cc7f7b8 400 break;
Wayne Roberts 0:2e040cc7f7b8 401 default:
Wayne Roberts 0:2e040cc7f7b8 402 MBED_ASSERT("Unknown Event");
Wayne Roberts 0:2e040cc7f7b8 403 }
Wayne Roberts 0:2e040cc7f7b8 404 }
Wayne Roberts 0:2e040cc7f7b8 405
Wayne Roberts 0:2e040cc7f7b8 406 // EOF