Forest fire prediction using sensors and LoRa communications

Dependencies:   X_NUCLEO_IKS01A2

Revision:
51:925c07d0d7cf
Parent:
50:6e615eea1e6f
--- a/main.cpp	Wed Mar 13 17:30:20 2019 +0000
+++ b/main.cpp	Mon Jun 03 10:26:44 2019 +0000
@@ -20,22 +20,42 @@
 #include "lorawan/system/lorawan_data_structures.h"
 #include "events/EventQueue.h"
 
+// Sensor headers
+#include "mbed.h"
+#include "XNucleoIKS01A2.h"
+
 // Application helpers
 #include "trace_helper.h"
 #include "lora_radio_helper.h"
 
 using namespace events;
 
+//#define WITH_SENSORS
+
+#ifdef WITH_SENSORS
+// Instantiate the expansion board
+static XNucleoIKS01A2 *mems_expansion_board = XNucleoIKS01A2::instance(D14, D15, D4, D5);
+
+// Retrieve the composing elements of the expansion board
+static HTS221Sensor *hum_temp = mems_expansion_board->ht_sensor;
+static LPS22HBSensor *press_temp = mems_expansion_board->pt_sensor;
+#endif
+
 // Max payload size can be LORAMAC_PHY_MAXPAYLOAD.
 // This example only communicates with much shorter messages (<30 bytes).
 // If longer messages are used, these buffers must be changed accordingly.
-uint8_t tx_buffer[30];
-uint8_t rx_buffer[30];
+uint8_t tx_buffer[100];
+uint8_t rx_buffer[100];
+
+// Buffers needed to read values from the sensors
+float value_temp, value_hum;
+#define SENSOR_BUFFER_SIZE 32
+char buffer_temp[SENSOR_BUFFER_SIZE], buffer_hum[SENSOR_BUFFER_SIZE];
 
 /*
  * Sets up an application dependent transmission timer in ms. Used only when Duty Cycling is off for testing
  */
-#define TX_TIMER                        10000
+#define TX_TIMER                        11000
 
 /**
  * Maximum number of events for the event queue.
@@ -77,11 +97,27 @@
  */
 static lorawan_app_callbacks_t callbacks;
 
+
+static char *print_double(char* str, double v);
+
 /**
  * Entry point for application
  */
 int main(void)
 {
+    printf("\r\n Hello, starting...");
+    
+    #ifdef WITH_SENSORS
+    // setup sensor stack
+    hum_temp->enable();
+    press_temp->enable();
+    
+    // testing sensors
+    hum_temp->get_temperature(&value_temp);
+    hum_temp->get_humidity(&value_hum);
+    printf("\r\n Sensors test:\r\n HTS221: [temp] %7s C,   [hum] %s%%\r\n", print_double(buffer_temp, value_temp), print_double(buffer_hum, value_hum));
+    #endif
+    
     // setup tracing
     setup_trace();
 
@@ -135,26 +171,31 @@
     return 0;
 }
 
-/**
+#ifndef WITH_SENSORS
+
+/*
  * Sends a message to the Network Server
  */
 static void send_message()
 {
     uint16_t packet_len;
     int16_t retcode;
-    printf("\n\rHello world");    
+    printf("\n\rSending message");    
 
-    packet_len = sprintf((char *) tx_buffer, "Hello world");
+    packet_len = sprintf((char *) tx_buffer, "This is a test. LoRa Works! <3");
 
     retcode = lorawan.send(MBED_CONF_LORA_APP_PORT, tx_buffer, packet_len,
                            MSG_UNCONFIRMED_FLAG);
 
     if (retcode < 0) {
+        printf("retcode < 0 in send\r\n");
+        
         retcode == LORAWAN_STATUS_WOULD_BLOCK ? printf("send - WOULD BLOCK\r\n")
         : printf("\r\n send() - Error code %d \r\n", retcode);
 
         if (retcode == LORAWAN_STATUS_WOULD_BLOCK) {
             //retry in 3 seconds
+            printf("LORAWAN_STATUS_WOULD_BLOCK verified, retrying");
             if (MBED_CONF_LORA_DUTY_CYCLE_ON) {
                 ev_queue.call_in(3000, send_message);
             }
@@ -166,6 +207,97 @@
     memset(tx_buffer, 0, sizeof(tx_buffer));
 }
 
+#else
+
+
+static void send_message()
+{
+    printf("\n\rSending message");
+    uint16_t packet_len;
+    int16_t retcode;
+    
+    // reading from sensors
+    memset(buffer_temp, 0, sizeof(buffer_temp));
+    memset(buffer_hum, 0, sizeof(buffer_hum));
+    hum_temp->get_temperature(&value_temp);
+    hum_temp->get_humidity(&value_hum);
+    printf("\r\nSensors reading: [temp] %7s C, [hum] %s%%\r\n", 
+        print_double(buffer_temp, value_temp), print_double(buffer_hum, value_hum));
+
+    // format data
+    uint16_t temp_len = sprintf((char *) tx_buffer, buffer_temp);
+    tx_buffer[temp_len] = ':';
+    uint16_t hum_len = sprintf((char *) &tx_buffer[temp_len+1], buffer_hum);
+    
+    // set final payload and send
+    packet_len = temp_len + hum_len + 1;    
+    
+    printf("\r\n Sending to server %s", tx_buffer);
+    
+    retcode = lorawan.send(MBED_CONF_LORA_APP_PORT, tx_buffer, packet_len,
+                           MSG_UNCONFIRMED_FLAG);
+                           
+    
+
+    if (retcode < 0) {
+        printf("retcode < 0 in send\r\n");
+        
+        retcode == LORAWAN_STATUS_WOULD_BLOCK ? printf("send - WOULD BLOCK\r\n")
+        : printf("\r\n send() - Error code %d \r\n", retcode);
+
+        if (retcode == LORAWAN_STATUS_WOULD_BLOCK) {
+            //retry in 3 seconds
+            printf("LORAWAN_STATUS_WOULD_BLOCK verified, retrying");
+            if (MBED_CONF_LORA_DUTY_CYCLE_ON) {
+                ev_queue.call_in(3000, send_message);
+            }
+        }
+        return;
+    }
+
+    printf("\r\n %d bytes scheduled for transmission \r\n", retcode);
+    memset(tx_buffer, 0, sizeof(tx_buffer));
+}
+
+#endif
+
+/* Helper function for printing floats & doubles */
+static char *print_double(char* str, double v)
+{
+  int decimalDigits=2;
+  int i = 1;
+  int intPart, fractPart;
+  int len;
+  char *ptr;
+
+  /* prepare decimal digits multiplicator */
+  for (;decimalDigits!=0; i*=10, decimalDigits--);
+
+  /* calculate integer & fractinal parts */
+  intPart = (int)v;
+  fractPart = (int)((v-(double)(int)v)*i);
+
+  /* fill in integer part */
+  sprintf(str, "%i.", intPart);
+
+  /* prepare fill in of fractional part */
+  len = strlen(str);
+  ptr = &str[len];
+
+  /* fill in leading fractional zeros */
+  for (i/=10;i>1; i/=10, ptr++) {
+    if (fractPart >= i) {
+      break;
+    }
+    *ptr = '0';
+  }
+
+  /* fill in (rest of) fractional part */
+  sprintf(ptr, "%i", fractPart);
+
+  return str;
+}
+
 /**
  * Event handler
  */