LoRaWAN_FAE_Training

Dependencies:   X_NUCLEO_IKS01A2

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 // sensor boards IKS01A2
00029 #include "XNucleoIKS01A2.h"
00030 
00031 
00032 /* Instantiate the expansion board */
00033 static XNucleoIKS01A2 *mems_expansion_board = XNucleoIKS01A2::instance(D14, D15, D4, D5);
00034 
00035 /* Retrieve the composing elements of the expansion board */
00036 /*
00037 static LSM303AGRMagSensor *magnetometer = mems_expansion_board->magnetometer;
00038 static HTS221Sensor *hum_temp = mems_expansion_board->ht_sensor;
00039 static LPS22HBSensor *press_temp = mems_expansion_board->pt_sensor;
00040 static LSM6DSLSensor *acc_gyro = mems_expansion_board->acc_gyro;
00041 static LSM303AGRAccSensor *accelerometer = mems_expansion_board->accelerometer;
00042 */
00043 
00044 using namespace events;
00045 
00046 // Max payload size can be LORAMAC_PHY_MAXPAYLOAD.
00047 // This example only communicates with much shorter messages (<30 bytes).
00048 // If longer messages are used, these buffers must be changed accordingly.
00049 uint8_t tx_buffer[30];
00050 uint8_t rx_buffer[30];
00051 
00052 /*
00053  * Sets up an application dependent transmission timer in ms. Used only when Duty Cycling is off for testing
00054  */
00055 #define TX_TIMER                        10000
00056 
00057 /**
00058  * Maximum number of events for the event queue.
00059  * 10 is the safe number for the stack events, however, if application
00060  * also uses the queue for whatever purposes, this number should be increased.
00061  */
00062 #define MAX_NUMBER_OF_EVENTS            10
00063 
00064 /**
00065  * Maximum number of retries for CONFIRMED messages before giving up
00066  */
00067 #define CONFIRMED_MSG_RETRY_COUNTER     3
00068 
00069 /**
00070  * Dummy pin for dummy sensor
00071  */
00072 #define PC_9                            0
00073 
00074 /**
00075  * Dummy sensor class object
00076  */
00077 DS1820  ds1820(PC_9);
00078 
00079 /**
00080 * This event queue is the global event queue for both the
00081 * application and stack. To conserve memory, the stack is designed to run
00082 * in the same thread as the application and the application is responsible for
00083 * providing an event queue to the stack that will be used for ISR deferment as
00084 * well as application information event queuing.
00085 */
00086 static EventQueue ev_queue(MAX_NUMBER_OF_EVENTS * EVENTS_EVENT_SIZE);
00087 
00088 /**
00089  * Event handler.
00090  *
00091  * This will be passed to the LoRaWAN stack to queue events for the
00092  * application which in turn drive the application.
00093  */
00094 static void lora_event_handler(lorawan_event_t event);
00095 
00096 /**
00097  * Constructing Mbed LoRaWANInterface and passing it down the radio object.
00098  */
00099 static LoRaWANInterface lorawan(radio);
00100 
00101 /**
00102  * Application specific callbacks
00103  */
00104 static lorawan_app_callbacks_t callbacks;
00105 
00106 /**
00107  * Entry point for application
00108  */
00109 int main (void)
00110 {
00111     //uint8_t id;
00112       
00113     // setup tracing
00114     setup_trace();
00115     
00116     // Init IKS01A2 Board
00117     /*    
00118     printf("\r\n--- IKS01A2 conf start ---\r\n");
00119   
00120     // Enable all sensors 
00121     hum_temp->enable();
00122     press_temp->enable();
00123     magnetometer->enable();
00124     accelerometer->enable();
00125     acc_gyro->enable_x();
00126     acc_gyro->enable_g();
00127 
00128     hum_temp->read_id(&id);
00129     printf("HTS221  humidity & temperature    = 0x%X\r\n", id);
00130     press_temp->read_id(&id);
00131     printf("LPS22HB  pressure & temperature   = 0x%X\r\n", id);
00132     magnetometer->read_id(&id);
00133     printf("LSM303AGR magnetometer            = 0x%X\r\n", id);
00134     accelerometer->read_id(&id);
00135     printf("LSM303AGR accelerometer           = 0x%X\r\n", id);
00136     acc_gyro->read_id(&id);
00137     printf("LSM6DSL accelerometer & gyroscope = 0x%X\r\n", id); 
00138     */
00139     
00140     // stores the status of a call to LoRaWAN protocol
00141     lorawan_status_t retcode;
00142 
00143     // Initialize LoRaWAN stack
00144     if (lorawan.initialize(&ev_queue) != LORAWAN_STATUS_OK) {
00145         printf("\r\n LoRa initialization failed! \r\n");
00146         return -1;
00147     }
00148 
00149     printf("\r\n Mbed LoRaWANStack initialized \r\n");
00150 
00151     // prepare application callbacks
00152     callbacks.events = mbed::callback(lora_event_handler);
00153     lorawan.add_app_callbacks(&callbacks);
00154 
00155     // Set number of retries in case of CONFIRMED messages
00156     if (lorawan.set_confirmed_msg_retries(CONFIRMED_MSG_RETRY_COUNTER)
00157                                           != LORAWAN_STATUS_OK) {
00158         printf("\r\n set_confirmed_msg_retries failed! \r\n\r\n");
00159         return -1;
00160     }
00161 
00162     printf("\r\n CONFIRMED message retries : %d \r\n",
00163            CONFIRMED_MSG_RETRY_COUNTER);
00164 
00165     // Enable adaptive data rate
00166     if (lorawan.enable_adaptive_datarate() != LORAWAN_STATUS_OK) {
00167         printf("\r\n enable_adaptive_datarate failed! \r\n");
00168         return -1;
00169     }
00170 
00171     printf("\r\n Adaptive data  rate (ADR) - Enabled \r\n");
00172 
00173     retcode = lorawan.connect();
00174 
00175     if (retcode == LORAWAN_STATUS_OK ||
00176         retcode == LORAWAN_STATUS_CONNECT_IN_PROGRESS) {
00177     } else {
00178         printf("\r\n Connection error, code = %d \r\n", retcode);
00179         return -1;
00180     }
00181 
00182     printf("\r\n Connection - In Progress ...\r\n");
00183 
00184     // make your event queue dispatching events forever
00185     ev_queue.dispatch_forever();
00186 
00187     return 0;
00188 }
00189 
00190 /**
00191  * Sends a message to the Network Server
00192  */
00193 static void send_message()
00194 {
00195     int16_t retcode;
00196     uint16_t packet_len;
00197     /*
00198     uint16_t Temperature, Index=1;
00199     uint32_t Pressure, Humidity;
00200     
00201     float value1, value2;
00202     int32_t axes[3];
00203     
00204     hum_temp->get_temperature(&value1);
00205     hum_temp->get_humidity(&value2);
00206     printf("HTS221: [temp] %2.2f C,   [hum] %2.2f \r\n", value1, value2);
00207     Humidity = value2 * 100;
00208 
00209     //Add Humidity
00210     tx_buffer[0]+=1;                                            // Add 1 Nbelment 
00211     tx_buffer[Index]=0x03;                                      // Humidity
00212     tx_buffer[Index+1]=0x03;                                    // Len
00213     tx_buffer[Index+2]=(uint8_t)(Humidity & 0xFF);              // Press LSB
00214     tx_buffer[Index+3]=(uint8_t)((Humidity >> 8) & 0xFF);       // Press MID
00215     tx_buffer[Index+4]=(uint8_t)((Humidity >> 16) & 0xFF);      // Press MSB
00216     Index+=5; 
00217     
00218     press_temp->get_temperature(&value1);
00219     press_temp->get_pressure(&value2);
00220     printf("LPS22HB: [temp] %2.2f C, [press] %4.2f mbar\r\n", value1, value2);
00221     
00222     
00223     Temperature = value1 * 100; // Convert for transmit
00224     Pressure = value2 * 100; // Convert for transmit
00225     
00226     //Add Tempertaure
00227     tx_buffer[0]+=1;                                            // Add 1 Nbelment 
00228     tx_buffer[Index]=0x01;                                      // Temperature
00229     tx_buffer[Index+1]=0x02;                                    // Len
00230     tx_buffer[Index+2]=(uint8_t)(Temperature & 0xFF);           // Temp LSB
00231     tx_buffer[Index+3]=(uint8_t)((Temperature >> 8) & 0xFF);    // Temp MSB 
00232     Index+=4;                                                   // Update the Index
00233     
00234     //Add Pressure
00235     tx_buffer[0]+=1;
00236     tx_buffer[Index]=0x02;                                      // Pressure
00237     tx_buffer[Index+1]=0x03;                                    // Len
00238     tx_buffer[Index+2]=(uint8_t)(Pressure & 0xFF);              // Press LSB
00239     tx_buffer[Index+3]=(uint8_t)((Pressure >> 8) & 0xFF);       // Press MID
00240     tx_buffer[Index+4]=(uint8_t)((Pressure >> 16) & 0xFF);      // Press MSB
00241     Index+=5; 
00242 
00243     printf("---\r\n");
00244 
00245     magnetometer->get_m_axes(axes);
00246     printf("LSM303AGR [mag/mgauss]:  %6ld, %6ld, %6ld\r\n", axes[0], axes[1], axes[2]);
00247     
00248     accelerometer->get_x_axes(axes);
00249     printf("LSM303AGR [acc/mg]:  %6ld, %6ld, %6ld\r\n", axes[0], axes[1], axes[2]);
00250     
00251     //Add Accelerometer
00252     tx_buffer[0]+=1;
00253     tx_buffer[Index]=0x04;                                      // Accelerometer
00254     tx_buffer[Index+1]=0x03;                                    // Len
00255     // x 
00256     tx_buffer[Index+2]=(uint8_t)(axes[0] & 0xFF);               // Press LSB
00257     tx_buffer[Index+3]=(uint8_t)((axes[0] >> 8) & 0xFF);        // Press MID
00258     tx_buffer[Index+4]=(uint8_t)((axes[0] >> 16) & 0xFF);       // Press MID
00259     tx_buffer[Index+5]=(uint8_t)((axes[0] >> 24) & 0xFF);       // Press MSB
00260     
00261     // y 
00262     tx_buffer[Index+6]=(uint8_t)(axes[1] & 0xFF);               // Press LSB
00263     tx_buffer[Index+7]=(uint8_t)((axes[1] >> 8) & 0xFF);        // Press MID
00264     tx_buffer[Index+8]=(uint8_t)((axes[1] >> 16) & 0xFF);       // Press MID
00265     tx_buffer[Index+9]=(uint8_t)((axes[1] >> 24) & 0xFF);       // Press MSB
00266     
00267     // z 
00268     tx_buffer[Index+10]=(uint8_t)(axes[2] & 0xFF);               // Press LSB
00269     tx_buffer[Index+11]=(uint8_t)((axes[2] >> 8) & 0xFF);        // Press MID
00270     tx_buffer[Index+12]=(uint8_t)((axes[2] >> 16) & 0xFF);       // Press MID
00271     tx_buffer[Index+13]=(uint8_t)((axes[2] >> 24) & 0xFF);       // Press MSB
00272     Index+=14; 
00273 
00274     acc_gyro->get_x_axes(axes);
00275     printf("LSM6DSL [acc/mg]:      %6ld, %6ld, %6ld\r\n", axes[0], axes[1], axes[2]);
00276 
00277     acc_gyro->get_g_axes(axes);
00278     printf("LSM6DSL [gyro/mdps]:   %6ld, %6ld, %6ld\r\n", axes[0], axes[1], axes[2]); 
00279     
00280     packet_len = Index + 1; // Compute the final payload size  
00281     
00282     */
00283 
00284     retcode = lorawan.send(MBED_CONF_LORA_APP_PORT, tx_buffer, packet_len,
00285                            MSG_UNCONFIRMED_FLAG);
00286 
00287     if (retcode < 0) {
00288         retcode == LORAWAN_STATUS_WOULD_BLOCK ? printf("send - WOULD BLOCK\r\n")
00289                 : printf("\r\n send() - Error code %d \r\n", retcode);
00290 
00291         if (retcode == LORAWAN_STATUS_WOULD_BLOCK) {
00292             //retry in 3 seconds
00293             if (MBED_CONF_LORA_DUTY_CYCLE_ON) {
00294                 ev_queue.call_in(3000, send_message);
00295             }
00296         }
00297         return;
00298     }
00299 
00300     printf("\r\n %d bytes scheduled for transmission \r\n", retcode);
00301     memset(tx_buffer, 0, sizeof(tx_buffer));
00302 }
00303 
00304 /**
00305  * Receive a message from the Network Server
00306  */
00307 static void receive_message()
00308 {
00309     int16_t retcode;
00310     retcode = lorawan.receive(MBED_CONF_LORA_APP_PORT, rx_buffer,
00311                               sizeof(rx_buffer),
00312                               MSG_CONFIRMED_FLAG|MSG_UNCONFIRMED_FLAG);
00313 
00314     if (retcode < 0) {
00315         printf("\r\n receive() - Error code %d \r\n", retcode);
00316         return;
00317     }
00318 
00319     printf(" Data:");
00320 
00321     for (uint8_t i = 0; i < retcode; i++) {
00322         printf("%x", rx_buffer[i]);
00323     }
00324 
00325     printf("\r\n Data Length: %d\r\n", retcode);
00326     
00327     /*
00328     if(rx_buffer[0] & 0x01 == 1)
00329     {
00330         printf("\r\n Board is in Wrong side !!!!! \r\n\r\n");    
00331     }
00332     if(((rx_buffer[0] & 0x02) >> 1) == 1)
00333     {
00334         printf("\r\n It's hot here !!!!! \r\n\r\n");    
00335     }
00336     if(((rx_buffer[0] & 0x04) >> 2) == 1)
00337     {
00338         printf("\r\n It's humid here !!!!! \r\n\r\n");   
00339     }
00340     */
00341 
00342     memset(rx_buffer, 0, sizeof(rx_buffer));
00343 }
00344 
00345 /**
00346  * Event handler
00347  */
00348 static void lora_event_handler(lorawan_event_t event)
00349 {
00350     switch (event) {
00351         case CONNECTED:
00352             printf("\r\n Connection - Successful \r\n");
00353             if (MBED_CONF_LORA_DUTY_CYCLE_ON) {
00354                 send_message();
00355             } else {
00356                 ev_queue.call_every(TX_TIMER, send_message);
00357             }
00358 
00359             break;
00360         case DISCONNECTED:
00361             ev_queue.break_dispatch();
00362             printf("\r\n Disconnected Successfully \r\n");
00363             break;
00364         case TX_DONE:
00365             printf("\r\n Message Sent to Network Server \r\n");
00366             if (MBED_CONF_LORA_DUTY_CYCLE_ON) {
00367                 send_message();
00368             }
00369             break;
00370         case TX_TIMEOUT:
00371         case TX_ERROR:
00372         case TX_CRYPTO_ERROR:
00373         case TX_SCHEDULING_ERROR:
00374             printf("\r\n Transmission Error - EventCode = %d \r\n", event);
00375             // try again
00376             if (MBED_CONF_LORA_DUTY_CYCLE_ON) {
00377                 send_message();
00378             }
00379             break;
00380         case RX_DONE:
00381             printf("\r\n Received message from Network Server \r\n");
00382             receive_message();
00383             break;
00384         case RX_TIMEOUT:
00385         case RX_ERROR:
00386             printf("\r\n Error in reception - Code = %d \r\n", event);
00387             break;
00388         case JOIN_FAILURE:
00389             printf("\r\n OTAA Failed - Check Keys \r\n");
00390             break;
00391         case UPLINK_REQUIRED:
00392             printf("\r\n Uplink required by NS \r\n");
00393             if (MBED_CONF_LORA_DUTY_CYCLE_ON) {
00394                 send_message();
00395             }
00396             break;
00397         default:
00398             MBED_ASSERT("Unknown Event");
00399     }
00400 }
00401 
00402 // EOF