NuMaker mbed OS v6.x LoRaWAN

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 /**
00002  * Copyright (c) 2017, Arm Limited and affiliates.
00003  * SPDX-License-Identifier: Apache-2.0
00004  *
00005  * Licensed under the Apache License, Version 2.0 (the "License");
00006  * you may not use this file except in compliance with the License.
00007  * You may obtain a copy of the License at
00008  *
00009  *     http://www.apache.org/licenses/LICENSE-2.0
00010  *
00011  * Unless required by applicable law or agreed to in writing, software
00012  * distributed under the License is distributed on an "AS IS" BASIS,
00013  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00014  * See the License for the specific language governing permissions and
00015  * limitations under the License.
00016  */
00017 #include <stdio.h>
00018 
00019 #include "lorawan/LoRaWANInterface.h"
00020 #include "lorawan/system/lorawan_data_structures.h"
00021 #include "events/EventQueue.h"
00022 
00023 // Application helpers
00024 #include "DummySensor.h"
00025 #include "trace_helper.h"
00026 #include "lora_radio_helper.h"
00027 
00028 using namespace events;
00029 
00030 // Max payload size can be LORAMAC_PHY_MAXPAYLOAD.
00031 // This example only communicates with much shorter messages (<30 bytes).
00032 // If longer messages are used, these buffers must be changed accordingly.
00033 uint8_t tx_buffer[30];
00034 uint8_t rx_buffer[30];
00035 
00036 /*
00037  * Sets up an application dependent transmission timer in ms. Used only when Duty Cycling is off for testing
00038  */
00039 #define TX_TIMER                        10000
00040 
00041 /**
00042  * Maximum number of events for the event queue.
00043  * 10 is the safe number for the stack events, however, if application
00044  * also uses the queue for whatever purposes, this number should be increased.
00045  */
00046 #define MAX_NUMBER_OF_EVENTS            10
00047 
00048 /**
00049  * Maximum number of retries for CONFIRMED messages before giving up
00050  */
00051 #define CONFIRMED_MSG_RETRY_COUNTER     3
00052 
00053 /**
00054  * Dummy pin for dummy sensor
00055  */
00056 #define PC_9                            0
00057 
00058 /**
00059  * Dummy sensor class object
00060  */
00061 DS1820  ds1820(PC_9);
00062 
00063 /**
00064 * This event queue is the global event queue for both the
00065 * application and stack. To conserve memory, the stack is designed to run
00066 * in the same thread as the application and the application is responsible for
00067 * providing an event queue to the stack that will be used for ISR deferment as
00068 * well as application information event queuing.
00069 */
00070 static EventQueue ev_queue(MAX_NUMBER_OF_EVENTS *EVENTS_EVENT_SIZE);
00071 
00072 /**
00073  * Event handler.
00074  *
00075  * This will be passed to the LoRaWAN stack to queue events for the
00076  * application which in turn drive the application.
00077  */
00078 static void lora_event_handler(lorawan_event_t event);
00079 
00080 /**
00081  * Constructing Mbed LoRaWANInterface and passing it the radio object from lora_radio_helper.
00082  */
00083 static LoRaWANInterface lorawan(radio);
00084 
00085 /**
00086  * Application specific callbacks
00087  */
00088 static lorawan_app_callbacks_t callbacks;
00089 
00090 /**
00091  * Entry point for application
00092  */
00093 int main(void)
00094 {
00095 #ifdef MBED_MAJOR_VERSION
00096     printf("Mbed OS version %d.%d.%d\r\n\n", MBED_MAJOR_VERSION, MBED_MINOR_VERSION, MBED_PATCH_VERSION);
00097 #endif
00098     printf("\n\n Start LoRa testing \r\n");
00099     // setup tracing
00100     setup_trace();
00101 
00102     // stores the status of a call to LoRaWAN protocol
00103     lorawan_status_t retcode;
00104 
00105     // Initialize LoRaWAN stack
00106     if (lorawan.initialize(&ev_queue) != LORAWAN_STATUS_OK) {
00107         printf("\r\n LoRa initialization failed! \r\n");
00108         return -1;
00109     }
00110 
00111     printf("\r\n Mbed LoRaWANStack initialized \r\n");
00112 
00113     // prepare application callbacks
00114     callbacks.events = mbed::callback(lora_event_handler);
00115     lorawan.add_app_callbacks(&callbacks);
00116 
00117     // Set number of retries in case of CONFIRMED messages
00118     if (lorawan.set_confirmed_msg_retries(CONFIRMED_MSG_RETRY_COUNTER)
00119             != LORAWAN_STATUS_OK) {
00120         printf("\r\n set_confirmed_msg_retries failed! \r\n\r\n");
00121         return -1;
00122     }
00123 
00124     printf("\r\n CONFIRMED message retries : %d \r\n",
00125            CONFIRMED_MSG_RETRY_COUNTER);
00126 
00127     // Enable adaptive data rate
00128     if (lorawan.enable_adaptive_datarate() != LORAWAN_STATUS_OK) {
00129         printf("\r\n enable_adaptive_datarate failed! \r\n");
00130         return -1;
00131     }
00132 
00133     printf("\r\n Adaptive data  rate (ADR) - Enabled \r\n");
00134 
00135     retcode = lorawan.connect();
00136 
00137     if (retcode == LORAWAN_STATUS_OK ||
00138             retcode == LORAWAN_STATUS_CONNECT_IN_PROGRESS) {
00139     } else {
00140         printf("\r\n Connection error, code = %d \r\n", retcode);
00141         return -1;
00142     }
00143 
00144     printf("\r\n Connection - In Progress ...\r\n");
00145 
00146     // make your event queue dispatching events forever
00147     ev_queue.dispatch_forever();
00148 
00149     return 0;
00150 }
00151 
00152 /**
00153  * Sends a message to the Network Server
00154  */
00155 static void send_message()
00156 {
00157     uint16_t packet_len;
00158     int16_t retcode;
00159     int32_t sensor_value;
00160 
00161     if (ds1820.begin()) {
00162         ds1820.startConversion();
00163         sensor_value = ds1820.read();
00164         printf("\r\n Dummy Sensor Value = %d \r\n", sensor_value);
00165         ds1820.startConversion();
00166     } else {
00167         printf("\r\n No sensor found \r\n");
00168         return;
00169     }
00170 
00171     packet_len = sprintf((char *) tx_buffer, "Val: %d",
00172                          sensor_value);
00173 
00174     retcode = lorawan.send(MBED_CONF_LORA_APP_PORT, tx_buffer, packet_len,
00175                            MSG_UNCONFIRMED_FLAG);
00176 
00177     if (retcode < 0) {
00178         retcode == LORAWAN_STATUS_WOULD_BLOCK ? printf("send - WOULD BLOCK\r\n")
00179         : printf("\r\n send() - Error code %d \r\n", retcode);
00180 
00181         if (retcode == LORAWAN_STATUS_WOULD_BLOCK) {
00182             //retry in 3 seconds
00183             if (MBED_CONF_LORA_DUTY_CYCLE_ON) {
00184                 ev_queue.call_in(3000, send_message);
00185             }
00186         }
00187         return;
00188     }
00189 
00190     printf("\r\n %d bytes scheduled for transmission \r\n", retcode);
00191     memset(tx_buffer, 0, sizeof(tx_buffer));
00192 }
00193 
00194 /**
00195  * Receive a message from the Network Server
00196  */
00197 static void receive_message()
00198 {
00199     uint8_t port;
00200     int flags;
00201     int16_t retcode = lorawan.receive(rx_buffer, sizeof(rx_buffer), port, flags);
00202 
00203     if (retcode < 0) {
00204         printf("\r\n receive() - Error code %d \r\n", retcode);
00205         return;
00206     }
00207 
00208     printf(" RX Data on port %u (%d bytes): ", port, retcode);
00209     for (uint8_t i = 0; i < retcode; i++) {
00210         printf("%02x ", rx_buffer[i]);
00211     }
00212     printf("\r\n");
00213     
00214     memset(rx_buffer, 0, sizeof(rx_buffer));
00215 }
00216 
00217 /**
00218  * Event handler
00219  */
00220 static void lora_event_handler(lorawan_event_t event)
00221 {
00222     switch (event) {
00223         case CONNECTED:
00224             printf("\r\n Connection - Successful \r\n");
00225             if (MBED_CONF_LORA_DUTY_CYCLE_ON) {
00226                 send_message();
00227             } else {
00228                 ev_queue.call_every(TX_TIMER, send_message);
00229             }
00230 
00231             break;
00232         case DISCONNECTED:
00233             ev_queue.break_dispatch();
00234             printf("\r\n Disconnected Successfully \r\n");
00235             break;
00236         case TX_DONE:
00237             printf("\r\n Message Sent to Network Server \r\n");
00238             if (MBED_CONF_LORA_DUTY_CYCLE_ON) {
00239                 send_message();
00240             }
00241             break;
00242         case TX_TIMEOUT:
00243         case TX_ERROR:
00244         case TX_CRYPTO_ERROR:
00245         case TX_SCHEDULING_ERROR:
00246             printf("\r\n Transmission Error - EventCode = %d \r\n", event);
00247             // try again
00248             if (MBED_CONF_LORA_DUTY_CYCLE_ON) {
00249                 send_message();
00250             }
00251             break;
00252         case RX_DONE:
00253             printf("\r\n Received message from Network Server \r\n");
00254             receive_message();
00255             break;
00256         case RX_TIMEOUT:
00257         case RX_ERROR:
00258             printf("\r\n Error in reception - Code = %d \r\n", event);
00259             break;
00260         case JOIN_FAILURE:
00261             printf("\r\n OTAA Failed - Check Keys \r\n");
00262             break;
00263         case UPLINK_REQUIRED:
00264             printf("\r\n Uplink required by NS \r\n");
00265             if (MBED_CONF_LORA_DUTY_CYCLE_ON) {
00266                 send_message();
00267             }
00268             break;
00269         default:
00270             MBED_ASSERT("Unknown Event");
00271     }
00272 }
00273 
00274 // EOF