Peter Ferland / Mbed OS TelitSensorToCloud

Dependencies:   DOGS102 GpsParser ISL29011 MMA845x MPL3115A2 MTS-Serial NCP5623B mDot_X_NUCLEO_IKS01A1 libmDot-mbed5

Files at this revision

API Documentation at this revision

Comitter:
pferland
Date:
Tue May 16 05:14:46 2017 +0000
Child:
1:de9172a990bd
Commit message:
Initial commit for Santa Clara demo

Changed in this revision

.hgignore Show annotated file Show diff for this revision Revisions of this file
DOGS102.lib Show annotated file Show diff for this revision Revisions of this file
GpsParser.lib Show annotated file Show diff for this revision Revisions of this file
ISL29011.lib Show annotated file Show diff for this revision Revisions of this file
MMA845x.lib Show annotated file Show diff for this revision Revisions of this file
MPL3115A2.lib Show annotated file Show diff for this revision Revisions of this file
MTS-Serial.lib Show annotated file Show diff for this revision Revisions of this file
NCP5623B.lib Show annotated file Show diff for this revision Revisions of this file
X_NUCLEO_IKS01A1.lib Show annotated file Show diff for this revision Revisions of this file
libmDot-mbed5.lib Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed-os.lib Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.hgignore	Tue May 16 05:14:46 2017 +0000
@@ -0,0 +1,4 @@
+mbed-os
+.build
+/mdot/
+/mdot-library/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DOGS102.lib	Tue May 16 05:14:46 2017 +0000
@@ -0,0 +1,1 @@
+https://developer.mbed.org/teams/Multi-Hackers/code/DOGS102/#e66152f036d9
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/GpsParser.lib	Tue May 16 05:14:46 2017 +0000
@@ -0,0 +1,1 @@
+https://developer.mbed.org/teams/Multi-Hackers/code/GpsParser/#465f9db415ea
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ISL29011.lib	Tue May 16 05:14:46 2017 +0000
@@ -0,0 +1,1 @@
+https://developer.mbed.org/teams/Multi-Hackers/code/ISL29011/#c1d5f4999b9e
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MMA845x.lib	Tue May 16 05:14:46 2017 +0000
@@ -0,0 +1,1 @@
+https://developer.mbed.org/teams/Multi-Hackers/code/MMA845x/#4ff1650da84c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MPL3115A2.lib	Tue May 16 05:14:46 2017 +0000
@@ -0,0 +1,1 @@
+https://developer.mbed.org/teams/Multi-Hackers/code/MPL3115A2/#c41ffe71300f
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MTS-Serial.lib	Tue May 16 05:14:46 2017 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/teams/MultiTech/code/MTS-Serial/#4afbbafcd6b3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/NCP5623B.lib	Tue May 16 05:14:46 2017 +0000
@@ -0,0 +1,1 @@
+https://developer.mbed.org/teams/Multi-Hackers/code/NCP5623B/#ae3ff403404a
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/X_NUCLEO_IKS01A1.lib	Tue May 16 05:14:46 2017 +0000
@@ -0,0 +1,1 @@
+https://developer.mbed.org/users/pferland/code/mDot_X_NUCLEO_IKS01A1/#83ba1f916d99
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libmDot-mbed5.lib	Tue May 16 05:14:46 2017 +0000
@@ -0,0 +1,1 @@
+http://developer.mbed.org/teams/MultiTech/code/libmDot-mbed5/#0c4b59488f41
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Tue May 16 05:14:46 2017 +0000
@@ -0,0 +1,1281 @@
+/*================================================================================
+ *
+ * CLASIFICATION:     **** PUBLIC RELEASE AS-IS APPLICATION EXAMPLE ****
+ *
+ * SOURCE FILE NAME:  main.cpp
+ *
+ * DESCRIPTIVE NAME:  MBED Source for MultiTech mDot, EVB, and MDOT-BOX Devices
+ *
+ * COPYRIGHT:         Copyright 2014-2017, Telit
+ *
+ *                    LICENSED MATERIAL - PROGRAM PROPERTY OF TELIT
+ *                    REFER TO TELIT COPYRIGHT INSTRUCTION
+ *
+** WEB SITE:          www.telit.com
+ *
+ * WRITTEN BY:        Eliott Fersko and John Keever
+ *
+ * DATE:              April 17, 2017
+ *
+ * VERSION:           1.02
+ *
+ * FUNCTION:          Provide working example for LoRa 'Sensor-to-Cloud'
+ *                    Demonstration using MultiTech LoRa Starter Kit and
+ *                    Telit Data and Cloud Platform Services Offerings
+ *
+ * SOURCE FILE TYPE:  MBED C++
+ *
+ * FUNCTIONS/ENTRY POINTS:  main
+ *
+ * INPUT  = None.
+ * OUTPUT = None.
+ *
+ * EXIT-NORMAL = N/A
+ * EXIT-ERROR  = N/A
+ *
+ * EXTERNAL REFERENCES = None.
+ *
+ * EXTERNAL FUNCTIONS = None.
+ *
+ * CONTROL BLOCKS = None.
+ *
+ *================================================================================*/
+/*                              LEGAL DISCLAIMER                                  */
+/*================================================================================
+
+  Redistribution and use in source and binary forms, with or without
+  modification, are permitted provided that the following conditions
+  are met:
+
+    Neither the name of ILS Technology nor Telit nor the names of its
+    contributors may be used to endorse or promote products derived
+    from this software without specific prior written permission.
+
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ *================================================================================*/
+/*                                 CHANGE LOG                                     */
+/*================================================================================*/
+/*          |Changed |          |                                                 */
+/*  Date    |   by   |Version ID| Comments                                        */
+/*----------+--------+----------+-------------------------------------------------*/
+/*04-12-2017|JEK     |V1.00     |Original Version - mDot, EVB, MDOT-BOX           */
+/*04-14-2017|JEK     |V1.01     |Added IRQ Handlers - SW1/SW2 (Threads?)          */
+/*04-17-2017|JEK     |V1.02     |Added Binary LoRa Payload Message Framing Type   */
+/*04-24-2017|EMF     |V1.03     |Updated Libraries                                */
+/*05-10-2017|EMF     |V1.04     |Added support for ST-Micro MEMS Sensor Shield    */
+/*================================================================================*/
+/*NOTE:  Please keep the change log up to date!!!                                 */
+/*================================================================================*/
+
+#include "mbed.h"
+#include "MMA845x.h"
+#include "MPL3115A2.h"
+#include "ISL29011.h"
+#include "NCP5623B.h"
+#include "DOGS102.h"
+#include "font_6x8.h"
+#include "MultiTech_Logo.h"
+#include "mDot.h"
+#include "rtos.h"
+#include "GPSPARSER.h"
+#include "MTSSerial.h"
+#include "x_nucleo_iks01a1.h"
+
+#include <cmath>
+#include <string>
+#include <vector>
+#include <ctime>
+#include <Ticker.h>
+
+#define CALL_METH(obj, meth, param, ret) ((obj == NULL) ?       \
+                      ((*(param) = (ret)), 0) : \
+                      ((obj)->meth(param))      \
+                      )
+
+
+enum LED1_COLOR {
+    RED = 0,
+    GREEN = 1
+};
+
+namespace {
+    const int MS_INTERVALS = 1000;
+}
+
+/*
+ * union for converting from 32-bit to 4 8-bit values
+ */
+union convert32 {
+    int32_t f_s;        // convert from signed 32 bit int
+    uint32_t f_u;       // convert from unsigned 32 bit int
+    uint8_t t_u[4];     // convert to 8 bit unsigned array
+};
+
+typedef struct {
+    int32_t AXIS_X;
+    int32_t AXIS_Y;
+    int32_t AXIS_Z;
+} AxesRaw_TypeDef;
+
+
+/*
+ * union for converting from 16- bit to 2 8-bit values
+ */
+union convert16 {
+    int16_t f_s;        // convert from signed 16 bit int
+    uint16_t f_u;       // convert from unsigned 16 bit int
+    uint8_t t_u[2];     // convert to 8 bit unsigned array
+};
+
+//DigitalIn mDot02(PA_2);                       //  GPIO/UART_TX
+//DigitalOut mDot03(PA_3);                      //  GPIO/UART_RX
+//DigitalIn mDot04(PA_6);                       //  GPIO/SPI_MISO
+//DigitalIn mDot06(PA_8);                       //  GPIO/I2C_SCL
+//DigitalIn mDot07(PC_9);                       //  GPIO/I2C_SDA
+
+InterruptIn mDot08(PA_12);                      //  GPIO/USB       PB S1 on EVB
+InterruptIn mDot09(PA_11);                      //  GPIO/USB       PB S2 on EVB
+
+//DigitalIn mDot11(PA_7);                       //  GPIO/SPI_MOSI
+
+InterruptIn mDot12(PA_0);                       //  GPIO/UART_CTS  PRESSURE_INT2 on EVB
+DigitalOut mDot13(PC_13,1);                     //  GPIO           LCD_C/D
+InterruptIn mDot15(PC_1);                       //  GPIO           LIGHT_PROX_INT on EVB
+InterruptIn mDot16(PA_1);                       //  GPIO/UART_RTS  ACCEL_INT2 on EVB
+DigitalOut mDot17(PA_4,1);                      //  GPIO/SPI_NCS   LCD_CS on EVB
+
+// DigitalIn mDot18(PA_5);                          //  GPIO/SPI_SCK
+// DigitalInOut mDot19(PB_0,PIN_INPUT,PullNone,0);  //  GPIO         PushPull LED Low=Red High=Green set MODE=INPUT to turn off
+// AnalogIn mDot20(PB_1);                           //  GPIO         Current Sense Analog in on EVB
+
+Serial debugUART(PA_9, PA_10);                  // mDot debug UART
+MTSSerial mDotUART(PA_2,PA_3);                  // mDot external UART mDot02 and mDot03
+I2C mDoti2c(PC_9,PA_8);                         // mDot External I2C mDot6 and mDot7
+SPI mDotspi(PA_7,PA_6,PA_5);                    // mDot external SPI mDot11, mDot4, and mDot18
+AnalogIn current_sensor(PB_1);                  // EVB - GPIO - Current Sensor Analog Input
+
+/* **** replace these values with the proper public or private network settings ****
+ * config_network_nameand config_network_pass are for private networks.
+ */
+
+//static std::string config_network_name = "telitlora";
+//static std::string config_network_pass = "telitpass";
+//static uint8_t config_frequency_sub_band = 7;
+
+
+
+static volatile bool timer_irq_triggered = false;
+static volatile bool ff_irq_triggered = false;
+
+static std::string config_network_name = "MTCDT-19020718";
+static std::string config_network_pass = "MTCDT-19020718";
+static uint8_t config_frequency_sub_band = 1;
+
+/*  config_app_id and config_app_key are for public networks.
+static uint8_t app_id[8] = {0x00,0x01,0x02,0x03,0x0A,0x0B,0x0C,0x0D};
+std::vector<uint8_t> config_app_id;
+static uint8_t app_key[16] = {0x00,0x01,0x02,0x03,0x0A,0x0B,0x0C,0x0D};
+std::vector<uint8_t> config_app_key;
+*/
+
+uint8_t result;
+uint8_t data;
+uint8_t sf_val = mDot::SF_7;
+uint8_t pwr_val = 11; // dBm
+uint8_t swp_pwr;
+uint8_t swp_sf;
+
+// max size of text string for 6x8 font. Set to 12 if using 8x8 font
+char txtstr[17];
+
+int32_t mdot_ret;
+int32_t join_delay;
+
+osThreadId mainThreadID;
+
+// flags for push button debounce code
+bool pb1_low = false;
+bool pb2_low = false;
+bool toggle_text = false;
+bool sw1_state = false;
+bool sw2_state = false;
+
+uint32_t num_whole;
+uint16_t num_frac;
+
+uint32_t pressure;
+double current;
+
+bool exit_program = false;
+
+//EVB sensor variables
+MMA845x_DATA accel_data;
+MPL3115A2_DATA baro_data;
+uint16_t  lux_data;
+MMA845x* evbAccel;
+MPL3115A2* evbBaro;
+ISL29011* evbAmbLight;
+NCP5623B* evbBackLight;
+DOGS102* evbLCD;
+
+//MEMS sensor variables
+float TEMPERATURE_Value;
+float HUMIDITY_Value;
+float PRESSURE_Value;
+float PRESSURE_Temp_Value;
+AxesRaw_TypeDef MAG_Value;
+AxesRaw_TypeDef ACC_Value;
+AxesRaw_TypeDef GYR_Value;
+char buffer1[32];
+char buffer2[32];
+char buffer3[32];
+char buffer4[32];
+unsigned int ret = 0;
+
+mDot* mdot_radio;
+Mutex mdot_mutex;
+
+//MEMS shield sensor variables
+//static X_NUCLEO_IKS01A1 *mems_expansion_board = X_NUCLEO_IKS01A1::Instance();
+X_NUCLEO_IKS01A1 *mems_expansion_board = X_NUCLEO_IKS01A1::Instance(I2C_SDA, I2C_SCL, PC_1);
+static Ticker ticker;
+
+
+GyroSensor *memsGyro;
+MotionSensor *memsAccel;
+MagneticSensor *memsMag;
+HumiditySensor *memsHumidity;
+PressureSensor *memsPressure;
+TempSensor *memsTemp1;
+TempSensor *memsTemp2;
+
+
+GPSPARSER* mdot_gps;
+
+convert32 convertl;
+convert16 converts;
+
+void pb1ISR(void);
+void pb2ISR(void);
+void pb1_debounce(void const *args);
+void pb2_debounce(void const *args);
+
+MPL3115A2* resetBaro(const MPL3115A2* oldBaro);
+void log_error(mDot* dot, const char* msg, int32_t retval);
+int32_t sendString(const std::string text);
+bool writeValueOrError();
+
+const int FAIL_MAX=15;
+int failtime=FAIL_MAX;
+int cycle_cnt = 0;
+
+char sensor_text[64];
+char lora_temp_string[16];
+char lora_alt_string[16];
+char lora_press_string[16];
+char lora_light_string[16];
+char lora_current_string[16];
+char lora_humid_string[16];
+
+bool bHasGPS = false;
+bool bHasACC = false;
+bool bHasLCD = false;
+
+/*** Helper Functions ------------------------------------------------------------ ***/
+/* print floats & doubles */
+static char *printDouble(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;
+}
+/*===================================================================================
+Main Program Logic - Entry
+===================================================================================*/
+int main()
+{
+    std::vector<uint8_t> mdot_data;
+    std::vector<uint8_t> mdot_EUI;
+    uint16_t i = 0;
+    uint8_t id1 = 0;
+
+    debugUART.baud(9600);
+
+    printf ("Starting Application...\r\n");
+
+    mainThreadID = osThreadGetId();
+
+    printf("Begin I2C/SPI Device Initialization...\r\n");
+
+
+    // Use Magnetometer As MEMS sensor shield Enumeration...
+
+    memsMag = mems_expansion_board->magnetometer;
+    CALL_METH(memsMag, ReadID, &id1, 0x0);
+    printf("Magnetometer ID value = %i \n\r", id1);
+
+    //chcek for default magnetomter ID 61...
+    if(id1 == 61)
+    {
+        printf("Magnetometer Found - MEMS sensor shield detected...\r\n");
+        bHasACC = true;
+
+        // Initialize Integrated Sensors...
+        printf("Instantiate Magnetometer...\r\n");
+        memsMag = mems_expansion_board->magnetometer;
+
+        printf("Instantiate Accelerometer...\r\n");
+        memsAccel = mems_expansion_board->GetAccelerometer();
+
+        printf("Instantiate Gyroscope...\r\n");
+        memsGyro = mems_expansion_board->GetGyroscope();
+
+        printf("Instantiate Barometric Pressure Sensor...\r\n");
+        memsPressure = mems_expansion_board->pt_sensor;
+
+        printf("Instantiate Temperature Pressure Sensor...\r\n");
+        //memsTemp1 = mems_expansion_board->ht_sensor;
+        memsTemp2 = mems_expansion_board->pt_sensor;
+
+        printf("Instantiate Humidity Sensor...\r\n");
+        memsHumidity = mems_expansion_board->ht_sensor;
+
+    }
+
+
+    else
+    {
+        printf("No Magnetometer Found...\r\n");
+        // Use Accelerometer As MDOT-BOX/EVB Enumeration...
+        printf("Instantiate Accelerometer...\r\n");
+        evbAccel = new MMA845x(mDoti2c,MMA845x::SA0_VSS);
+
+        printf("Accelerometer Status = %d\r\n", evbAccel->getStatus());
+        printf("Accelerometer who_am_i value = %x \n\r", evbAccel->getWhoAmI());
+
+        if( (evbAccel->getStatus() == 1) && (evbAccel->getWhoAmI() == 0) )
+        {
+            printf("No Accelerometer Found - Basic mDot, Not MDOT-BOX or EVB...\r\n");
+        }
+
+        else
+        {
+            printf("Accelerometer Found - Either MDOT-BOX or EVB...\r\n");
+            bHasACC = true;
+
+        // Initialize Integrated Sensors...
+            printf("Instantiate Barometric Pressure Sensor...\r\n");
+            evbBaro = new MPL3115A2(mDoti2c);       // Setup Barometric Sensor
+            printf("Barometric Sensor Status = %d\r\n", evbBaro->getStatus());
+            printf("Barometer who_am_i check = %d\r\n", evbBaro->testWhoAmI());
+            printf("Barometer who_am_i check = %s\r\n", evbBaro->testWhoAmI() ? "TRUE" : "FALSE");
+
+            if( evbBaro->getStatus() == 0 ) printf("No Barometric Sensor...\r\n");
+
+            printf("Instantiate Ambient Light Sensor...\r\n");
+            evbAmbLight = new ISL29011(mDoti2c);    // Setup Ambient Light Sensor
+
+            // Setup the Accelerometer for 8g range, 14 bit resolution, Noise reduction off, sample rate 1.56 Hz
+            // Normal oversample mode, High pass filter off
+            evbAccel->setCommonParameters(MMA845x::RANGE_8g,MMA845x::RES_MAX,MMA845x::LN_OFF, MMA845x::DR_1_56,MMA845x::OS_NORMAL,MMA845x::HPF_OFF );
+
+            // Setup the Barometric sensor for post processed Ambient pressure, 4 samples per data acquisition.
+            // and a sample taken every second when in active mode
+            evbBaro->setParameters(MPL3115A2::DATA_NORMAL, MPL3115A2::DM_BAROMETER, MPL3115A2::OR_16, MPL3115A2::AT_1);
+
+            // Setup the Ambient Light Sensor for continuous Ambient Light Sensing, 16 bit resolution, and 16000 lux range
+            evbAmbLight->setMode(ISL29011::ALS_CONT);
+            evbAmbLight->setResolution(ISL29011::ADC_16BIT);
+            evbAmbLight->setRange(ISL29011::RNG_16000);
+
+            // Set the accelerometer for active mode
+            evbAccel->activeMode();
+
+            // Clear the min-max registers in the Barometric Sensor
+            evbBaro->clearMinMaxRegs();
+
+            // Support Integrated LCD Display
+            bHasLCD = true;
+
+            printf("Instantiate BackLight and LCD Display...\r\n");
+            evbBackLight = new NCP5623B(mDoti2c);               // setup backlight and LED 2 driver chip
+
+            evbLCD = new DOGS102(mDotspi, mDot17, mDot13);      // setup LCD Display
+
+            printf("Font Table Address:  %p\r\n",&font_6x8);
+            printf("Bitmap Logo Address:  %p\r\n",&MultiTech_Logo);
+
+            // Setup and display logo on LCD
+            evbLCD->startUpdate();
+            evbLCD->writeBitmap(0,0,MultiTech_Logo);
+
+            sprintf(txtstr,"MTDOT-EVB");
+            evbLCD->writeText(24,3,font_6x8,txtstr,strlen(txtstr));
+            sprintf(txtstr,"Sensor Demo");
+            evbLCD->writeText(18,4,font_6x8,txtstr,strlen(txtstr));
+
+            evbLCD->endUpdate();
+
+            printf("Setup PushButton Interface Handlers...\r\n");
+
+            printf("Launching Debounce Threads...\r\n");
+            Thread thread_1(pb1_debounce);
+            Thread thread_2(pb2_debounce);
+            printf("Debounce Threads Launched...\r\n");
+
+            printf("Set SW1/SW2 IRQs...\r\n");
+            // Setup SW1 as Data rate and power out select
+            mDot08.disable_irq();
+            mDot08.fall(&pb1ISR);
+
+            // need to call this function after rise or fall because rise/fall sets mode to PullNone
+            mDot08.mode(PullUp);
+            mDot08.enable_irq();
+
+            // Setup SW2 as send PING
+            mDot09.disable_irq();
+            mDot09.fall(&pb2ISR);
+
+            // need to call this function after rise or fall because rise/fall sets mode to PullNone
+            mDot09.mode(PullUp);
+            mDot09.enable_irq();
+
+            // Setting other InterruptIn pins with Pull Ups
+            mDot12.mode(PullUp);
+            mDot15.mode(PullUp);
+            mDot16.mode(PullUp);
+
+            printf("SW1/SW2 IRQs Set...\r\n");
+        }
+    }
+
+    printf("I2C/SPI Device Initialization Complete...\r\n");
+
+    printf("\r\nSetup mDot Radio Communications...\r\n");
+
+    // get a mDot handle
+    mdot_radio = mDot::getInstance();
+
+    if (mdot_radio)
+    {
+        // reset to default config so we know what state we're in
+        mdot_mutex.lock();  // lock mdot before setting configuration
+        mdot_radio->resetConfig();
+
+        // Setting up LED1 as activity LED
+        mdot_radio->setActivityLedPin(PB_0);
+        mdot_radio->setActivityLedEnable(true);
+
+        // Read node ID
+        mdot_EUI = mdot_radio->getDeviceId();
+        printf("mDot EUI = ");
+
+        for(i=0; i<mdot_EUI.size(); i++) {
+            printf("%02x ", mdot_EUI[i]);
+        }
+        printf("\r\n");
+
+        // Setting up the mDot with network information.
+
+        // This call sets up private or public mode on the MTDOT. Set the function to true if
+        // connecting to a public network
+        printf("Setting Private Network Mode...\r\n");
+        if ((mdot_ret = mdot_radio->setPublicNetwork(false)) != mDot::MDOT_OK) {
+            log_error(mdot_radio, "ERROR: Failed to set Public Network Mode", mdot_ret);
+        }
+
+        // Frequency sub-band is valid for NAM only and for Private networks should be set to a value
+        // between 1-8 that matches the the LoRa gateway setting. Public networks use sub-band 0 only.
+        // This function can be commented out for EU networks
+        printf("Setting Frequency Sub-Band...\r\n");
+        if ((mdot_ret = mdot_radio->setFrequencySubBand(config_frequency_sub_band)) != mDot::MDOT_OK) {
+            log_error(mdot_radio, "ERROR: Failed to set Frequency Sub-Band", mdot_ret);
+        }
+
+        // Setting TX power for radio. Max allowed is +14dBm for EU and +20 dBm for NAM. Default is +11 dBm
+        printf("Setting TX Power Level to %2d dBm...\r\n", pwr_val);
+        if ((mdot_ret = mdot_radio->setTxPower(pwr_val)) != mDot::MDOT_OK) {
+            log_error(mdot_radio, "ERROR: Failed to set TX Power Level", mdot_ret);
+        }
+
+        // Setting TX data rate for radio. Max allowed is SF_12 for EU and SF10 dBm for NAM. Default is SF_10
+        printf("Setting TX data rate to SF_7...\r\n");
+        if ((mdot_ret = mdot_radio->setTxDataRate(sf_val)) != mDot::MDOT_OK) {
+            log_error(mdot_radio, "ERROR: Failed to set TX Data Rate", mdot_ret);
+        }
+
+        // Configure Pushbutton Display Labels...
+        sprintf(txtstr,"SF=%2d PWR=%2d",sf_val,pwr_val);
+        if( bHasLCD ) evbLCD->writeText(0,7,font_6x8,txtstr,strlen(txtstr));
+        printf("%s\r\n",txtstr);
+
+
+        // Setting Packet ACK to 1 try.
+
+        printf("Setting Packet Retry to 1...\r\n");
+        if ((mdot_ret = mdot_radio->setAck(1)) != mDot::MDOT_OK) {
+            log_error(mdot_radio, "ERROR: Failed to set Packet Retry\r\n", mdot_ret);
+        }
+
+
+        // setNetworkName is used for private networks.
+        // Use setNetworkID(AppID) for public networks
+
+        // config_app_id.assign(app_id,app_id+7);
+
+        printf("Setting Network Name...\r\n");
+        if ((mdot_ret = mdot_radio->setNetworkName(config_network_name)) != mDot::MDOT_OK) {
+        // if ((mdot_ret = mdot_radio->setNetworkID(config_app_id)) != mDot::MDOT_OK) {
+            log_error(mdot_radio, "ERROR: Failed to set Network Name", mdot_ret);
+        }
+
+        // setNetworkPassphrase is used for private networks
+        // Use setNetworkKey for public networks
+
+        // config_app_key.assign(app_key,app_key+15);
+
+        printf("Setting Network Password...\r\n");
+        if ((mdot_ret = mdot_radio->setNetworkPassphrase(config_network_pass)) != mDot::MDOT_OK) {
+        // if ((mdot_ret = mdot_radio->setNetworkKey(config_app_key)) != mDot::MDOT_OK) {
+            log_error(mdot_radio, "ERROR: Failed to set Network Password", mdot_ret);
+        }
+
+        mdot_mutex.unlock();        // unlock mdot mutex before join attempt so SW1 can work
+
+        // attempt to join the network
+        printf("Joining LoRa Network...\r\n");
+        do {
+            mdot_mutex.lock();      // lock mdot mutex before join attempt
+            mdot_ret = mdot_radio->joinNetwork();
+            mdot_mutex.unlock();        // unlock mdot mutex after join attempt so SW1 can work
+
+            if (mdot_ret != mDot::MDOT_OK)
+            {
+                log_error(mdot_radio,"ERROR: Failed to Join Network:", mdot_ret);
+
+                if (toggle_text)
+                    sprintf(txtstr," > Join Failed <");
+                else
+                    sprintf(txtstr," < Join Failed >");
+
+                if( bHasLCD ) evbLCD->writeText(0,5,font_6x8,txtstr,strlen(txtstr));
+
+                if (mdot_radio->getFrequencyBand() == mDot::FB_868)
+                {
+                    join_delay = mdot_radio->getNextTxMs();
+                }
+                else
+                {
+                    join_delay = 10;
+                }
+                printf("Join Delay = %lu\r\n",join_delay);
+                osDelay(join_delay + 1);
+                toggle_text = !toggle_text;
+            }
+
+            /*
+             * Setting TX power and Data Rate for radio just in case user requested by SW2
+             */
+            mdot_mutex.lock();      // lock mdot mutex before setting change
+            mdot_radio->setTxPower(pwr_val);
+            mdot_radio->setTxDataRate(sf_val);
+            mdot_mutex.unlock();        // unlock mdot mutex after settings change so SW1 can work
+
+        } while (mdot_ret != mDot::MDOT_OK);
+
+        printf("Successfully Joined LoRa Network...\r\n");
+
+        sprintf(txtstr,"*Network Joined*");
+        if( bHasLCD ) evbLCD->writeText(0,5,font_6x8,txtstr,strlen(txtstr));
+
+    }
+    else
+    {
+        printf("ERROR:  Unable to Join LoRa Network...\r\n");
+        sprintf(txtstr,"Radio Init Failed!");
+        if( bHasLCD ) evbLCD->writeText(0,5,font_6x8,txtstr,strlen(txtstr));
+        printf("%s\r\n",txtstr);
+        exit(1);
+    }
+
+    // Check for MDOT-BOX Configuration (GPS)
+
+    if( bHasACC && bHasLCD )
+    {
+        printf("Instantiate GPS...\r\n");
+        mdot_gps = new GPSPARSER(&mDotUART);
+
+        if(!mdot_gps->gpsDetected())
+        {
+            printf(">>>> No GPS Detected... Not an MDOT-BOX, EVB Identified\r\n");
+
+            sprintf(txtstr,"*No GPS Detected*");
+            if( bHasLCD ) evbLCD->writeText(0,6,font_6x8,txtstr,strlen(txtstr));
+        }
+        else
+        {
+            // main_single = main_sweep = false;
+            do
+            {
+                // osSignalWait(0x10, 2000);
+                if (mdot_gps->getLockStatus())
+                {
+                    sprintf(txtstr,"!!GPS locked!!");
+                    if( bHasLCD ) evbLCD->writeText(0,6,font_6x8,txtstr,strlen(txtstr));
+                    printf("%s \r\n",txtstr);
+                }
+                else
+                {
+                    if (toggle_text)
+                        sprintf(txtstr," > no GPS lock <");
+                    else
+                        sprintf(txtstr," < no GPS lock >");
+
+                    if( bHasLCD ) evbLCD->writeText(0,6,font_6x8,txtstr,strlen(txtstr));
+                    printf("%s \r\n",txtstr);
+                    toggle_text = !toggle_text;
+                }
+            } while ( !(mdot_gps->getLockStatus()) );
+        }
+    }
+
+    printf("Initialization/Configuration Completed...\r\n");
+
+    osDelay(1500);
+    if( bHasLCD ) evbBackLight->setPWM(NCP5623B::LED_3,16); // enable LED2 on EVB and set to 50% PWM
+
+    // sets LED2 to 50% max current
+    if( bHasLCD ) evbBackLight->setLEDCurrent(16);
+
+
+    // Check for PB1 press during network join attempt
+    /*
+    if (exit_program)
+    {
+        printf("PB1 Pressed, Exiting Program...\r\n");
+        if( bHasLCD ) evbLCD->clearBuffer();
+        sprintf(txtstr,"Exiting Program");
+        if( bHasLCD ) evbLCD->writeText(0,4,font_6x8,txtstr,strlen(txtstr));
+        exit(1);
+    }
+    */
+
+    // Enter Main Data Acquisition Loop...
+    printf("Processing Data Acquisition Scan Loop...\r\n");
+
+    i = 0;
+    cycle_cnt = 100;
+
+    if( bHasLCD ) evbLCD->clearBuffer();
+
+    do
+    {
+        //EVB
+        if( bHasACC && bHasLCD )
+        {
+            // Check Accelerometer XYZ data ready bit to see if acquisition complete
+            failtime = FAIL_MAX;
+            do
+            {
+                osDelay(100);           // allows other threads to process
+                result = evbAccel->getStatus();
+                failtime--;
+            } while ((result & MMA845x::XYZDR) == 0 && failtime > 0);
+
+            if (failtime==0)
+            {
+                evbBaro=resetBaro(evbBaro);
+                continue;
+            }
+
+            // Retrieve and print out accelerometer data
+            accel_data = evbAccel->getXYZ();
+            sprintf(txtstr, "Accel-X = %d", accel_data._x);
+            evbLCD->writeText(0,0,font_6x8,txtstr,strlen(txtstr));
+            sprintf(txtstr, "Accel-Y = %d", accel_data._y);
+            evbLCD->writeText(0,1,font_6x8,txtstr,strlen(txtstr));
+            sprintf(txtstr, "Accel-Z = %d", accel_data._z );
+            evbLCD->writeText(0,2,font_6x8,txtstr,strlen(txtstr));
+
+            // Trigger a Barometric Pressure Reading
+            evbBaro->setParameters(MPL3115A2::DATA_NORMAL, MPL3115A2::DM_BAROMETER, MPL3115A2::OR_16, MPL3115A2::AT_1);
+            evbBaro->triggerOneShot();
+
+            // Test Barometer Device, Check to see if acquisition is complete
+            failtime=FAIL_MAX;
+            do
+            {
+                osDelay(100);           // allows other threads to process
+                result = evbBaro->getStatus();
+                failtime--;
+            } while ((result & MPL3115A2::PTDR) == 0 && failtime > 0 );
+
+            if(failtime==0)
+            {
+                evbBaro=resetBaro(evbBaro);
+                continue;
+            }
+
+            // Retrieve and Display Barometric Pressure
+            pressure = evbBaro->getBaroData() >> 12;    // convert 32 bit signed to 20 bit unsigned value
+            num_whole = pressure >> 2;                  // 18 bit integer significant
+            num_frac = (pressure & 0x3) * 25;           // 2 bit fractional  0.25 per bit
+
+            // If failtime reached 0 , indicates that the result might be junk.
+            sprintf(txtstr,"Press=%ld.%01d Pa", num_whole, num_frac/10);
+
+            pressure = evbBaro->getBaroData() >> 12;    // convert 32 bit signed to 20 bit unsigned value
+            num_whole = pressure >> 2;                  // 18 bit integer significant
+            num_frac = (pressure & 0x3) * 25;           // 2 bit fractional  0.25 per bit
+
+            writeValueOrError();                        // will write to  lorapresstring and txtstr
+
+            // Trigger a Altitude reading
+            // evbBaro->setAltitudeCalib(101);
+            evbBaro->setParameters(MPL3115A2::DATA_NORMAL, MPL3115A2::DM_ALTIMETER, MPL3115A2::OR_16, MPL3115A2::AT_1);
+            // evbBaro->setAltitudeCalib(101);
+            evbBaro->triggerOneShot();
+
+            // Test barometer device status to see if acquisition is complete
+            failtime=FAIL_MAX;
+            do
+            {
+                osDelay(100);           // allows other threads to process
+                result = evbBaro->getStatus();
+                failtime--;
+            } while ((result & MPL3115A2::PTDR) == 0 && failtime > 0 );
+
+            if (failtime==0)
+            {
+                evbBaro=resetBaro(evbBaro);
+                continue;
+            }
+
+            // Retrieve and Display Altimeter Reading
+            baro_data = evbBaro->getAllData(false);
+            baro_data._baro /= 4096;                                    // convert 32 bit signed to 20 bit signed value
+            num_whole = baro_data._baro / 16;                           // 18 bit signed significant integer (JEK Added 60 as SWAG Offset for Boca)
+            num_frac = (baro_data._baro & 0xF) * 625 / 100;             // 4 bit fractional .0625 per bit
+            sprintf(txtstr,"Alti=%ld.%03d m", num_whole, num_frac);
+            sprintf(lora_alt_string,"%ld.%03d", num_whole, num_frac);
+            evbLCD->writeText(0,4,font_6x8,txtstr,strlen(txtstr));
+
+            // Retrieve and Display Temperature Reading
+            num_whole = baro_data._temp / 16;                           // 8 bit signed significant integer
+            num_frac = (baro_data._temp & 0x0F) * 625 / 100;            // 4 bit fractional .0625 per bit
+            sprintf(txtstr,"Temp=%ld.%03d C", num_whole, num_frac);
+            sprintf(lora_temp_string,"%ld.%03d", num_whole, num_frac);
+            evbLCD->writeText(0,5,font_6x8,txtstr,strlen(txtstr));
+
+            // Retrieve and Display Ambient Light Level
+            lux_data = evbAmbLight->getData();
+            num_whole = lux_data * 24 / 100;        // 16000 lux full scale .24 lux per bit
+            num_frac = lux_data * 24 % 100;
+            sprintf(txtstr, "Light=%ld.%02d lux", num_whole, num_frac );
+            sprintf(lora_light_string, "%ld.%02d", num_whole, num_frac );
+            evbLCD->writeText(0,6,font_6x8,txtstr,strlen(txtstr));
+
+            // Retrieve and Display Current Sensor Level (EVB Analog Input)
+            current = (double) current_sensor * 65535.0;
+            sprintf(lora_current_string, "%d", (int) current);
+
+            // Handle Pushbutton #1 (SW1) - This should be handled by the 'pb1_debounce' thread.
+            if( pb1_low )
+            {
+                sw1_state = !sw1_state;
+                if( bHasLCD ) evbBackLight->setPWM(NCP5623B::LED_3,0);  // enable LED2 on EVB and set to 0% PWM
+
+                sprintf(txtstr,"PB1 Press-SW1: %d", sw1_state);
+                if( bHasLCD ) evbLCD->writeText(0,7,font_6x8,txtstr,strlen(txtstr));
+                printf("%s \r\n",txtstr);
+
+                pb1_low = false;
+            }
+
+            // Handle Pushbutton #2 (SW2) - This should be handled by the 'pb2_debounce' thread.
+             if( pb2_low )
+            {
+                sw2_state = !sw2_state;
+                if( bHasLCD ) evbBackLight->setPWM(NCP5623B::LED_3,16); // enable LED2 on EVB and set to 50% PWM
+
+                sprintf(txtstr,"PB2 Press-SW2: %d", sw2_state);
+                if( bHasLCD ) evbLCD->writeText(0,7,font_6x8,txtstr,strlen(txtstr));
+                printf("%s \r\n",txtstr);
+
+                pb2_low = false;
+            }
+        }
+        //MEMS
+        else if(!bHasLCD && bHasACC)
+        {
+
+            std::vector<uint8_t> tx_data;
+
+
+            // Payload structure for mydevices cayenne:
+            // 1 byte Data1 ID
+            // 1 Byte Data1 Type
+            // N Bytes Data1
+            // 1 byte data 2 ID
+            // 1 byte data 2 type
+            // n Bytes data 2
+            // ...
+
+            // formats:
+            // Temperature sensor:
+            /*
+             * IPSO: 3303
+             * LPP 103
+             * HEX: 67
+             * Data size: 2
+             * Resolution: 0.1 degres C
+
+             * Humidity sensor
+             * IPSO: 3304
+             * LPP: 104
+             * Hex: 68
+             * Datasize: 1
+             * Resolution: 0.5% unsigned
+
+             * Barometer/pressure sensor
+             * IPSO: 3315
+             * LPP: 115
+             * Hex: 73
+             * Datasize: 2
+             * Resolution 0.1hPa unsigned MSB
+
+             * Accelerometer
+             * IPSO: 3313
+             * LPP: 113
+             * Hex: 71
+             * Data size: 6
+             * Resolution: 0.001G signed MSB per axis
+
+             * Gyrometer
+             * IPSO: 3334
+             * LPP: 134
+             * Hex: 86
+             * Data size: 6
+             * Resolution: 0.01 degrees/s signed msb per axis
+            */
+
+            //temp floats
+            float temp_value, humid_value, pressure_value;
+            int16_t int_temp_value, int_humid_value, int_pressure_value;
+
+            // HTS221 Humidity sensor
+
+            ret |= (!CALL_METH(memsTemp1, GetTemperature, &temp_value, 0.0f) ? 0x0 : 0x1);
+            ret |= (!CALL_METH(memsHumidity, GetHumidity, &humid_value, 0.0f) ? 0x0 : 0x2);;
+
+            /*
+            //serialize data and append to packet
+            // Cayenne data: temperature; tag is 0x67, 2 bytes signed, 0.1 C/bit
+            tx_data.push_back(uint8_t(1)); // data id
+            tx_data.push_back(uint8_t(0x67)); // data type - temp
+            int_temp_value = floor(temp_value*10 + 0.5f);
+            tx_data.push_back(uint8_t( 0xFF & (int_temp_value >> 8)));
+            tx_data.push_back(uint8_t(0xFF & int_temp_value));
+
+
+            tx_data.push_back(uint8_t(2)); // data id
+            tx_data.push_back(uint8_t(0x68)); // data type - humidity
+            int_humid_value = floor(humid_value * 2.0f + 0.5f);
+            tx_data.push_back(uint8_t(0xFF & int_humid_value ));
+            */
+
+            ret |= (!CALL_METH(memsPressure, GetPressure, &pressure_value, 0.0f) ? 0x0 : 0x4);;
+
+            /*
+            // pressure is reported in mbar, cayenne wants it in 0.1 hPa
+            // 1mbar = 1 hPa
+            int_pressure_value = floor(pressure_value * 100.0f + 0.5f);
+
+            tx_data.push_back(uint8_t(3)); // data id
+            tx_data.push_back(uint8_t(0x73)); // data type - pressure
+            int_pressure_value = floor(pressure_value / 0.1f + 0.5f);
+            tx_data.push_back(uint8_t(0xFF & (int_pressure_value >> 8)));
+            tx_data.push_back(uint8_t(0xFF & int_pressure_value));
+            */
+
+            // Get accelerometer data
+            int32_t accel_vector[3];
+            // returns in mG
+            memsAccel->Get_X_Axes(accel_vector);
+
+            /*
+            tx_data.push_back(uint8_t(4)); // data id
+            tx_data.push_back(uint8_t(0x71)); // data type - accelerometer
+            for(int i=0; i<3; i++) {
+                tx_data.push_back(uint8_t(0xFF & accel_vector[i]) >> 8);
+                tx_data.push_back(uint8_t(0xFF & accel_vector[i]));
+            }
+            */
+
+            // Get gyro data
+            int32_t gyro_vector[3];
+            memsGyro->Get_G_Axes(gyro_vector);
+
+            /*
+            // gyro reports in milidegrees/sec, cayenne wants centidegrees/sec
+            tx_data.push_back(uint8_t(5)); //data id
+            tx_data.push_back(uint8_t(0x86)); // data type - gyrometer
+            for(int i=0; i<3; i++) {
+                gyro_vector[i] /= 10;
+                tx_data.push_back(uint8_t(0xFF & (gyro_vector[i] >> 8)));
+                tx_data.push_back(uint8_t(0xFF & gyro_vector[i]));
+            }
+            */
+
+            // Get magnetometer data
+            int32_t mag_vector[3];
+            memsMag->Get_M_Axes(mag_vector);
+            // gyro reports in milidegrees/sec, cayenne wants centidegrees/sec
+
+           /*
+            tx_data.push_back(uint8_t(5)); //data id
+            tx_data.push_back(uint8_t(0x99)); // data type - mangetometer
+            for(int i=0; i<3; i++) {
+                mag_vector[i] /= 10;
+                tx_data.push_back(uint8_t(0xFF & (mag_vector[i] >> 8)));
+                tx_data.push_back(uint8_t(0xFF & mag_vector[i]));
+            }
+            */
+
+
+            //send_data(tx_data);
+
+            //---------------------------------------------------------------------------
+            // Verbose Text Format:  Least Data Payload, Most Human Readible
+            //---------------------------------------------------------------------------
+
+            /*
+            if(!bHasLCD && bHasACC)
+            {
+
+                sprintf(sensor_text, "accel-x:%d|accel-y:%d|accel-z:%d|gyro-x:%d|gyro-y:%d|gyro-z:%d|mag-x:%d|mag-y:%d|mag-x:%d|press:%s|temp:%s|humid:%s",
+                    accel_vector[0],
+                    accel_vector[1],
+                    accel_vector[2],
+                    gyro_vector[0],
+                    gyro_vector[1],
+                    gyro_vector[2],
+                    mag_vector[0],
+                    mag_vector[1],
+                    mag_vector[2],
+                    printDouble(buffer3, pressure_value),
+                    printDouble(buffer1, temp_value),
+                    printDouble(buffer2, humid_value));
+            }
+            else
+            {
+                sprintf(sensor_text, "accel-x:%d|accel-y:%d|accel-z:%d|press:%s|alti:%s|temp:%s|light:%s|moist:%s",
+                    accel_data._x,
+                    accel_data._y,
+                    accel_data._z,
+                    lora_press_string,
+                    lora_alt_string,
+                    lora_temp_string,
+                    lora_light_string,
+                    lora_current_string);
+
+            }
+
+
+             if ((mdot_ret = sendString((const std::string)sensor_text)) != mDot::MDOT_OK) {
+                log_error(mdot_radio, "ERROR: Failed to Send Data", mdot_ret);
+            } else {
+                printf("Ok, Successfully Sent Data to Gateway...\r\n");
+            }
+            */
+
+            //---------------------------------------------------------------------------
+            // Byte Vector Format:  More Data Payload, Less Human Readible
+            //---------------------------------------------------------------------------
+
+            if(!bHasLCD && bHasACC)
+            {
+
+                sprintf(sensor_text, "ax:%d,ay:%d,az:%d,gx:%d,gy:%d,gz:%d,mx:%d,my:%d,mz:%d,p:%s,t:%s,h:%s",
+                    accel_vector[0],
+                    accel_vector[1],
+                    accel_vector[2],
+                    gyro_vector[0],
+                    gyro_vector[1],
+                    gyro_vector[2],
+                    mag_vector[0],
+                    mag_vector[1],
+                    mag_vector[2],
+                    printDouble(buffer3, pressure_value),
+                    printDouble(buffer1, temp_value),
+                    printDouble(buffer2, humid_value));
+            }
+
+            else
+            {
+                sprintf(sensor_text, "x:%d,y:%d,z:%d,p:%s,al:%s,t:%s,l:%s,c:%s",
+                    accel_data._x,
+                    accel_data._y,
+                    accel_data._z,
+                    lora_press_string,
+                    lora_alt_string,
+                    lora_temp_string,
+                    lora_light_string,
+                    lora_current_string);
+            }
+
+            if ((mdot_ret = sendString((const std::string)sensor_text)) != mDot::MDOT_OK) {
+                log_error(mdot_radio, "ERROR: Failed to Send Data", mdot_ret);
+            } else {
+                printf("Ok, Successfully Sent Data to Gateway...\r\n");
+            }
+
+            /*
+            //---------------------------------------------------------------------------
+            // Binary Encoded Format:  Most Data Payload, Not Human Readible
+            //---------------------------------------------------------------------------
+            mdot_data.clear();
+            mdot_data.push_back(0x0E);              // key for Current Acceleration 3-Axis Value
+            converts.f_s = accel_data._x *4;        // shift data 2 bits while retaining sign
+            mdot_data.push_back(converts.t_u[1]);   // get 8 MSB of 14 bit value
+            converts.f_s = accel_data._y * 4;       // shift data 2 bits while retaining sign
+            mdot_data.push_back(converts.t_u[1]);   // get 8 MSB of 14 bit value
+            converts.f_s = accel_data._z * 4;       // shift data 2 bits while retaining sign
+            mdot_data.push_back(converts.t_u[1]);   // get 8 MSB of 14 bit value
+            mdot_data.push_back(0x08);              // key for Current Pressure Value
+            convertl.f_u = pressure;                // pressure data is 20 bits unsigned
+            mdot_data.push_back(convertl.t_u[2]);
+            mdot_data.push_back(convertl.t_u[1]);
+            mdot_data.push_back(convertl.t_u[0]);
+            mdot_data.push_back(0x05);              // key for Current Ambient Light Value
+            converts.f_u = lux_data;                // data is 16 bits unsigned
+            mdot_data.push_back(converts.t_u[1]);
+            mdot_data.push_back(converts.t_u[0]);
+            mdot_data.push_back(0x0B);              // key for Current Temperature Value
+            converts.f_s = baro_data._temp;         // temperature is signed 12 bit
+            mdot_data.push_back(converts.t_u[1]);
+            mdot_data.push_back(converts.t_u[0]);
+
+            if ((mdot_ret = mdot_radio->send(mdot_data)) != mDot::MDOT_OK) {
+                log_error(mdot_radio, "ERROR: Failed to Send Data", mdot_ret);
+            } else {
+                printf("Ok, Successfully Sent Data to Gateway...\r\n");
+            }
+
+            */
+
+            osDelay(500);
+            sprintf(txtstr,"Scanning...     ");
+            if( bHasLCD ) evbLCD->writeText(0,7,font_6x8,txtstr,strlen(txtstr));
+            cycle_cnt = 0;
+        }
+
+        osDelay(1000);
+        cycle_cnt++;
+
+        // Put Thread to Sleep for 30 Seconds...
+        // osDelay(30000);
+
+    } while(i < 86400);
+
+    printf("End of Data Collection Cycle (24 Hours) - Ending Application, GoodBye...\r\n");
+
+    if( bHasLCD ) evbLCD->clearBuffer();
+    sprintf(txtstr,"Exiting Program");
+    if( bHasLCD ) evbLCD->writeText(0,7,font_6x8,txtstr,strlen(txtstr));
+}
+
+/*** Interrupt Handler Top-Halves ------------------------------------------------------ ***/
+/* Called in interrupt context, therefore just set a trigger variable */
+static void timer_irq(void) {
+    timer_irq_triggered = true;
+}
+
+/* Called in interrupt context, therefore just set a trigger variable */
+static void ff_irq(void) {
+    ff_irq_triggered = true;
+
+    /* Disable IRQ until handled */
+    mems_expansion_board->gyro_lsm6ds3->Disable_Free_Fall_Detection_IRQ();
+}
+
+
+/*** Interrupt Handler Bottom-Halves ------------------------------------------------- ***/
+/* Handle Free Fall Interrupt
+   (here we are in "normal" context, i.e. not in IRQ context)
+*/
+static void handle_ff_irq(void) {
+    printf("\nFree Fall Detected!\n\n");
+
+    /* Re-enable IRQ */
+    mems_expansion_board->gyro_lsm6ds3->Enable_Free_Fall_Detection_IRQ();
+}
+
+/*===================================================================================
+Send String Payload to Conduit Gateway
+===================================================================================*/
+int32_t sendString(const std::string text)
+{
+    int32_t ret;
+    if (mdot_radio->getNextTxMs() != 0)
+    {
+        printf("Sending in %lu ms...\r\n", mdot_radio->getNextTxMs());
+        return false;
+    }
+
+    printf("Sending: '%s'\r\n", text.c_str());
+    std::vector<uint8_t> data(text.begin(), text.end());
+    if ((ret = mdot_radio->send(data, 1)) != mDot::MDOT_OK)
+    {
+        log_error(mdot_radio, "ERROR: Failed to Send Data", ret);
+    }
+
+    return ret;
+}
+
+/*===================================================================================
+Interrupt Service Request Handler - Sets pb1_low flag. Flag is cleared in pb1_debounce thread
+===================================================================================*/
+void pb1ISR(void)
+{
+    pb1_low = true;
+}
+
+/*===================================================================================
+Pushbutton Debounce - Debounces pb1 PB1 changes SW1 State Value (Sets LED Off)
+===================================================================================*/
+void pb1_debounce(void const *args)
+{
+    printf("Thread pb1_debounce started...\r\n");
+
+    while(true)
+    {
+        // if( pb1_low && (mDot08 == 0))
+        if( pb1_low )
+        {
+            sprintf(txtstr,"PB1 Pressed...");
+            if( bHasLCD ) evbLCD->writeText(0,7,font_6x8,txtstr,strlen(txtstr));
+            printf("%s\r\n",txtstr);
+
+            pb1_low = false;
+        }
+
+        Thread::wait(50);
+    }
+}
+
+/*===================================================================================
+Interrupt Service Request Handler - Sets pb1_low flag. Flag is cleared in pb1_debounce thread
+===================================================================================*/
+void pb2ISR(void)
+{
+    pb2_low = true;
+}
+
+/*===================================================================================
+Pushbutton Debounce - Debounces pb2 PB2 changes SW2 State Value (Sets LED On)
+===================================================================================*/
+void pb2_debounce(void const *args)
+{
+    printf("Thread pb2_debounce started...\r\n");
+
+    while(true)
+    {
+        // if( pb2_low && (mDot09 == 1))
+        if( pb2_low )
+        {
+            sprintf(txtstr,"PB2 Pressed...");
+            if( bHasLCD ) evbLCD->writeText(0,7,font_6x8,txtstr,strlen(txtstr));
+            printf("%s \r\n",txtstr);
+
+            pb2_low = false;
+        }
+
+        Thread::wait(50);
+    }
+}
+
+/*===================================================================================
+Display Value/Error String of Barometric Pressure Sensor
+===================================================================================*/
+bool writeValueOrError()
+{
+    bool res;
+
+    if (failtime==0)
+    {
+        sprintf(lora_press_string, "%s", "--.--");
+        sprintf(txtstr, "%s", "--.--");
+        if( bHasLCD ) evbLCD->writeText(0,4,font_6x8,txtstr, strlen(txtstr));
+        res=false;
+    }
+    else
+    {
+        sprintf(lora_press_string, "%ld.%02d", num_whole, num_frac);
+        if( bHasLCD ) evbLCD->writeText(0,3,font_6x8,txtstr,strlen(txtstr));
+        res=true;
+    }
+
+    return res;
+}
+
+/*===================================================================================
+Resets Barometric Pressure Sensor
+===================================================================================*/
+MPL3115A2* resetBaro(const MPL3115A2* oldBaro)
+{
+    delete oldBaro;
+    MPL3115A2* baro = new MPL3115A2(mDoti2c);
+    baro->testWhoAmI();
+
+    printf("Resetting barometer.. %x \n\r", baro->getStatus() );
+    baro->setParameters(MPL3115A2::DATA_NORMAL, MPL3115A2::DM_BAROMETER, MPL3115A2::OR_16, MPL3115A2::AT_1);
+    evbBaro->clearMinMaxRegs();
+
+    return baro;
+}
+
+/*===================================================================================
+Print clear text verion of mDot/EVB errors
+===================================================================================*/
+void log_error(mDot* dot, const char* msg, int32_t retval)
+{
+    printf("%s - %ld:%s, %s\r\n", msg, retval, mDot::getReturnCodeString(retval).c_str(), dot->getLastError().c_str());
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed-os.lib	Tue May 16 05:14:46 2017 +0000
@@ -0,0 +1,1 @@
+https://github.com/ARMmbed/mbed-os/#50b3418e45484ebf442b88cd935a2d5355402d7d