Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: DOGS102 GpsParser ISL29011 MMA845x MPL3115A2 MTS-Serial NCP5623B mDot_X_NUCLEO_IKS01A1 libmDot-mbed5
Revision 0:5a7579045f49, committed 2017-05-16
- 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
--- /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