mDot EVB to M2X demo.

Dependencies:   DOGS102 ISL29011 MMA845x MPL3115A2 NCP5623B libmDot mbed-rtos mbed-src

Fork of MTDOT-EVBDemo by Multi-Hackers

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

Go to the documentation of this file.
00001 /**
00002  * @file    main.cpp
00003  * @brief   Main application for mDot-EVB demo
00004  * @author  Tim Barr  MultiTech Systems Inc.
00005  * @version 1.03
00006  * @see
00007  *
00008  * Copyright (c) 2015
00009  *
00010  * Licensed under the Apache License, Version 2.0 (the "License");
00011  * you may not use this file except in compliance with the License.
00012  * You may obtain a copy of the License at
00013  *
00014  *     http://www.apache.org/licenses/LICENSE-2.0
00015  *
00016  * Unless required by applicable law or agreed to in writing, software
00017  * distributed under the License is distributed on an "AS IS" BASIS,
00018  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00019  * See the License for the specific language governing permissions and
00020  * limitations under the License.
00021  *
00022  * 1.01 TAB 7/6/15 Removed NULL pointer from evbAmbientLight creation call.
00023  *
00024  * 1.02 TAB 7/8/15 Send logo to LCD before attempting connection to LoRa network. Added
00025  *                 information on setting up for public LoRa network. Moved SW setup to
00026  *                 beginning of main. Removed printf call from ISR functions. Added
00027  *                 additional checks for exit_program.
00028  *
00029  * 1.03 TAB 7/15/15 Added threads for push button switch debounce.
00030  *
00031  * 1.04 JCM 7/16/15 Updated application for AT&T M2X Demo
00032  *
00033  * 1.05 JCM 7/20/15 Integrate Senet Public network demo
00034  *
00035  * 1.06 JCM 7/20/15 Clean up code, send message using clock
00036  *
00037  */
00038 
00039 #include "mbed.h"
00040 #include "MMA845x.h"
00041 #include "MPL3115A2.h"
00042 #include "ISL29011.h"
00043 #include "NCP5623B.h"
00044 #include "DOGS102.h"
00045 #include "font_6x8.h"
00046 #include "MultiTech_Logo.h"
00047 #include "mDot.h"
00048 #include "rtos.h"
00049 #include <string>
00050 #include <vector>
00051 
00052 /*
00053  * General settings
00054  */
00055 const bool public_net = false;
00056 const bool senet_demo = false;
00057 static uint8_t config_frequency_sub_band = 5;
00058 
00059 /*
00060  * Conduit AEP settings
00061  *
00062  * AEP settings can be found at: https://<ip-address>/lora_network.html
00063  */
00064 static std::string config_network_name = "testtest";
00065 static std::string config_network_pass = "memememe";
00066 
00067 /*
00068  * Public Network settings
00069  */
00070 static uint8_t app_id[8] = {0x00,0x25,0x0C,0x00,0x00,0x01,0x00,0x01};
00071 std::vector<uint8_t> config_app_id(app_id, app_id + sizeof(app_id)/sizeof(uint8_t));
00072 static uint8_t app_key[16] = {0xB4,0xAD,0x1A,0x25,0x69,0x7F,0xF6,0x8E,0xD3,0x4B,0x83,0xC4,0xB6,0xC0,0xF2,0x3C};
00073 std::vector<uint8_t> config_app_key(app_key, app_key + sizeof(app_key)/sizeof(uint8_t));
00074 
00075 /*
00076  * M2X settings
00077  *
00078  * M2X settings can be found at: https://m2x.att.com/devices
00079  * Once a device is added you will see DEVICE ID and PRIMARY API KEY fields
00080  * for the device.
00081  */
00082 const char *m2x_device = "f397d9c6c74cb1e2a1be5ef7731dc8af";
00083 const char *m2x_key = "5899c8b045531d3634efa65096ee3ede";
00084 
00085 
00086 enum LED1_COLOR {
00087     RED = 0,
00088     GREEN = 1
00089 };
00090 
00091 /*
00092  * union for converting from 32-bit to 4 8-bit values
00093  */
00094 union convert32 {
00095     int32_t f_s;        // convert from signed 32 bit int
00096     uint32_t f_u;       // convert from unsigned 32 bit int
00097     uint8_t t_u[4];     // convert to 8 bit unsigned array
00098 };
00099 
00100 /*
00101  * union for converting from 16- bit to 2 8-bit values
00102  */
00103 union convert16 {
00104     int16_t f_s;        // convert from signed 16 bit int
00105     uint16_t f_u;       // convert from unsigned 16 bit int
00106     uint8_t t_u[2];     // convert to 8 bit unsigned array
00107 };
00108 
00109 //DigitalIn mDot02(PA_2);          //  GPIO/UART_TX
00110 //DigitalOut mDot03(PA_3);         //  GPIO/UART_RX
00111 //DigitalIn mDot04(PA_6);          //  GPIO/SPI_MISO
00112 //DigitalIn mDot06(PA_8);          //  GPIO/I2C_SCL
00113 //DigitalIn mDot07(PC_9);          //  GPIO/I2C_SDA
00114 
00115 InterruptIn mDot08(PA_12);         //  GPIO/USB       PB S1 on EVB
00116 InterruptIn mDot09(PA_11);         //  GPIO/USB       PB S2 on EVB
00117 
00118 //DigitalIn mDot11(PA_7);          //  GPIO/SPI_MOSI
00119 
00120 InterruptIn mDot12(PA_0);          //  GPIO/UART_CTS  PRESSURE_INT2 on EVB
00121 DigitalOut mDot13(PC_13,1);        //  GPIO           LCD_C/D
00122 InterruptIn mDot15(PC_1);          //  GPIO           LIGHT_PROX_INT on EVB
00123 InterruptIn mDot16(PA_1);          //  GPIO/UART_RTS  ACCEL_INT2 on EVB
00124 DigitalOut mDot17(PA_4,1);         //  GPIO/SPI_NCS   LCD_CS on EVB
00125 
00126 //DigitalIn mDot18(PA_5);          //  GPIO/SPI_SCK
00127 
00128 //DigitalInOut mDot19(PB_0,PIN_INPUT,PullNone,0); // GPIO         PushPull LED Low=Red High=Green set MODE=INPUT to turn off
00129 AnalogIn mDot20(PB_1);             //  GPIO          Current Sense Analog in on EVB
00130 
00131 Serial debugUART(PA_9, PA_10); // mDot debug UART
00132 
00133 //Serial mDotUART(PA_2, PA_3); // mDot external UART mDot02 and mDot03
00134 
00135 I2C mDoti2c(PC_9,PA_8); // mDot External I2C mDot6 and mDot7
00136 
00137 SPI mDotspi(PA_7,PA_6,PA_5); // mDot external SPI mDot11, mDot4, and mDot18
00138 
00139 
00140 uint8_t result;
00141 uint8_t tx_interval = 30;
00142 char data;
00143 unsigned char test;
00144 char txtstr[64];
00145 int32_t num_whole;
00146 int32_t mdot_ret;
00147 uint32_t pressure;
00148 int16_t num_frac;
00149 
00150 uint8_t position_value; // 00 unknown, 01 is flat, 02 is vertical
00151 
00152 bool exit_program = false;
00153 
00154 MMA845x_DATA accel_data;
00155 MPL3115A2_DATA baro_data;
00156 uint16_t  lux_data;
00157 MMA845x *evbAccel;
00158 MPL3115A2 *evbBaro;
00159 ISL29011 *evbAmbLight;
00160 NCP5623B *evbBackLight;
00161 DOGS102 *evbLCD;
00162 mDot *mdot_radio;
00163 
00164 convert32 convertl;
00165 convert16 converts;
00166 
00167 // flags for pushbutton debounce code
00168 bool pb1_low = false;
00169 bool pb2_low = false;
00170 
00171 void pb1ISR(void);
00172 void pb2ISR(void);
00173 void pb1_debounce(void const *args);
00174 void pb2_debounce(void const *args);
00175 Thread* thread_3;
00176 
00177 void log_error(mDot *dot, const char *msg, int32_t retval);
00178 
00179 void config_pkt_xmit(void const *args);
00180 
00181 int main()
00182 {
00183     std::vector<uint8_t> lora_pl;
00184     std::vector<uint8_t> mdot_EUI;
00185     int count;
00186     int loops;
00187     int i;
00188 
00189     debugUART.baud(115200);
00190 //  mDotUART.baud(9600);    // mdot UART unused but available on external connector
00191 
00192     Thread thread_1(pb1_debounce); // threads for de-bouncing pushbutton switches
00193     Thread thread_2(pb2_debounce);
00194 
00195     thread_3 = new Thread(config_pkt_xmit); // start thread that sends LoRa packet when SW2 pressed
00196 
00197     evbAccel = new MMA845x(mDoti2c, MMA845x::SA0_VSS); // setup Accelerometer
00198     evbBaro = new MPL3115A2(mDoti2c);                 // setup Barometric sensor
00199     evbAmbLight = new ISL29011(mDoti2c);              // Setup Ambient Light Sensor
00200     evbBackLight = new NCP5623B(mDoti2c);             // setup backlight and LED 2 driver chip
00201     evbLCD = new DOGS102(mDotspi, mDot17, mDot13);    // setup LCD
00202 
00203     /*
00204      *  Setup SW1 as program stop function
00205      */
00206     mDot08.disable_irq();
00207     mDot08.fall(&pb1ISR);
00208 
00209     /*
00210      *  need to call this function after rise or fall because rise/fall sets
00211      *  mode to PullNone
00212      */
00213     mDot08.mode(PullUp);
00214 
00215     mDot08.enable_irq();
00216 
00217     /*
00218      *  Setup SW2 as packet time change
00219      */
00220     mDot09.disable_irq();
00221     mDot09.fall(&pb2ISR);
00222 
00223     /*
00224      *  need to call this function after rise or fall because rise/fall sets
00225      *  mode to PullNone
00226      */
00227     mDot09.mode(PullUp);
00228 
00229     mDot09.enable_irq();
00230 
00231     /*
00232     * Setting other InterruptIn pins with Pull Ups
00233     */
00234     mDot12.mode(PullUp);
00235     mDot15.mode(PullUp);
00236     mDot16.mode(PullUp);
00237 
00238     printf("font table address %p\r\n", &font_6x8);
00239     printf("bitmap address %p\r\n", &MultiTech_Logo);
00240 
00241     // Setup and display logo on LCD
00242     evbLCD->startUpdate();
00243 
00244     evbLCD->writeBitmap(0, 0, MultiTech_Logo);
00245 
00246     sprintf(txtstr,"MTDOT");
00247     evbLCD->writeText(24, 3, font_6x8, txtstr, strlen(txtstr));
00248     sprintf(txtstr,"Evaluation");
00249     evbLCD->writeText(24, 4, font_6x8, txtstr, strlen(txtstr));
00250     sprintf(txtstr,"Board");
00251     evbLCD->writeText(24, 5, font_6x8, txtstr, strlen(txtstr));
00252 
00253     evbLCD->endUpdate();
00254 
00255     printf("\r\n setup mdot\r\n");
00256 
00257     // get a mDot handle
00258     mdot_radio = mDot::getInstance();
00259 
00260     if (mdot_radio) {
00261         // reset to default config so we know what state we're in
00262         mdot_radio->resetConfig();
00263 
00264         // Setting up LED1 as activity LED
00265         mdot_radio->setActivityLedPin(PB_0);
00266         mdot_radio->setActivityLedEnable(true);
00267 
00268         // Read node ID
00269         mdot_EUI = mdot_radio->getDeviceId();
00270         printf("mDot EUI = ");
00271         for (i = 0; i < mdot_EUI.size(); i++) {
00272             printf("%02x ", mdot_EUI[i]);
00273         }
00274         printf("\r\n");
00275 
00276         printf("setting Network Mode to %s\r\n", public_net ? "public" : "private");
00277         if ((mdot_ret = mdot_radio->setPublicNetwork(public_net)) != mDot::MDOT_OK) {
00278             log_error(mdot_radio, "failed to set Network Mode", mdot_ret);
00279         }
00280 
00281         /*
00282          * Frequency sub-band is valid for NAM only and for Private networks should be set to a value
00283          * between 1-8 that matches the the LoRa gateway setting. Public networks use sub-band 0 only.
00284          * This function can be commented out for EU networks
00285          */
00286         printf("setting frequency sub band\r\n");
00287         if ((mdot_ret = mdot_radio->setFrequencySubBand(config_frequency_sub_band)) != mDot::MDOT_OK) {
00288             log_error(mdot_radio, "failed to set frequency sub band", mdot_ret);
00289         }
00290 
00291         printf("setting network name\r\n");
00292         if (public_net) {
00293             if ((mdot_ret = mdot_radio->setNetworkId(config_app_id)) != mDot::MDOT_OK) {
00294                 log_error(mdot_radio, "failed to set network name", mdot_ret);
00295             }
00296         } else {
00297             if ((mdot_ret = mdot_radio->setNetworkName(config_network_name)) != mDot::MDOT_OK) {
00298                 log_error(mdot_radio, "failed to set network name", mdot_ret);
00299             }
00300         }
00301 
00302         printf("setting network password\r\n");
00303         if (public_net) {
00304             if ((mdot_ret = mdot_radio->setNetworkKey(config_app_key)) != mDot::MDOT_OK) {
00305                 log_error(mdot_radio, "failed to set network key", mdot_ret);
00306             }
00307         } else {
00308             if ((mdot_ret = mdot_radio->setNetworkPassphrase(config_network_pass)) != mDot::MDOT_OK) {
00309                 log_error(mdot_radio, "failed to set network pass phrase", mdot_ret);
00310             }
00311         }
00312 
00313         // attempt to join the network
00314         printf("joining network\r\n");
00315         while (((mdot_ret = mdot_radio->joinNetwork()) != mDot::MDOT_OK) && (!exit_program)) {
00316             log_error(mdot_radio,"failed to join network:", mdot_ret);
00317             if (mdot_radio->getFrequencyBand() == mDot::FB_868) {
00318                 mdot_ret = mdot_radio->getNextTxMs();
00319             } else {
00320                 mdot_ret = 0;
00321             }
00322             printf("delay = %lu\r\n", mdot_ret);
00323             osDelay(mdot_ret + 1);
00324         }
00325 
00326         /*
00327          * Check for PB1 press during network join attempt
00328          */
00329         if (exit_program) {
00330             printf("Exiting program\r\n");
00331             evbLCD->clearBuffer();
00332             sprintf(txtstr,"Exiting Program");
00333             evbLCD->writeText(0, 4, font_6x8,txtstr,strlen(txtstr));
00334             exit(1);
00335         }
00336     } else {
00337         printf("radio setup failed\r\n");
00338         //exit(1);
00339     }
00340 
00341     osDelay(200);
00342     evbBackLight->setPWM(NCP5623B::LED_3, 16); // enable LED2 on EVB and set to 50% PWM
00343 
00344     // sets LED2 to 50% max current
00345     evbBackLight->setLEDCurrent(16);
00346 
00347     printf("Start of Test\r\n");
00348 
00349     osDelay (500); // allows other threads to process
00350     printf("shutdown LED:\r\n");
00351     evbBackLight->shutdown();
00352 
00353     osDelay (500); // allows other threads to process
00354     printf("Turn on LED2\r\n");
00355     evbBackLight->setLEDCurrent(16);
00356 
00357     data = evbAccel->getWhoAmI();
00358     printf("Accelerometer who_am_i value = %x \r\n", data);
00359 
00360     result = evbAccel->getStatus();
00361     printf("status byte = %x \r\n", result);
00362 
00363     printf("Barometer who_am_i check = %s \r\n", evbBaro->testWhoAmI() ? "TRUE" : "FALSE");
00364 
00365     result = evbBaro->getStatus();
00366     printf("status byte = %x \r\n", result);
00367 
00368     /*
00369      *  Setup the Accelerometer for 8g range, 14 bit resolution, Noise reduction off, sample rate 1.56 Hz
00370      *  normal oversample mode, High pass filter off
00371      */
00372     evbAccel->setCommonParameters(MMA845x::RANGE_8g, MMA845x::RES_MAX,MMA845x::LN_OFF,
00373                                   MMA845x::DR_1_56,MMA845x::OS_NORMAL,MMA845x::HPF_OFF);
00374 
00375     /*
00376      * Setup the Barometric sensor for post processed Ambient pressure, 4 samples per data acquisition.
00377      * and a sample taken every second when in active mode
00378      */
00379     evbBaro->setParameters(MPL3115A2::DATA_NORMAL, MPL3115A2::DM_BAROMETER, MPL3115A2::OR_16,
00380                            MPL3115A2::AT_1);
00381     /*
00382      * Setup the Ambient Light Sensor for continuous Ambient Light Sensing, 16 bit resolution,
00383      * and 16000 lux range
00384      */
00385 
00386     evbAmbLight->setMode(ISL29011::ALS_CONT);
00387     evbAmbLight->setResolution(ISL29011::ADC_16BIT);
00388     evbAmbLight->setRange(ISL29011::RNG_16000);
00389 
00390     /*
00391      * Set the accelerometer for active mode
00392      */
00393     evbAccel->activeMode();
00394 
00395     /*
00396      * Clear the min-max registers in the Barometric Sensor
00397      */
00398     evbBaro->clearMinMaxRegs();
00399 
00400     evbBackLight->setLEDCurrent(0);
00401 
00402     /*
00403      * Check for PB1 press during network join attempt
00404      */
00405     if (exit_program) {
00406         printf("Exiting program\r\n");
00407         evbLCD->clearBuffer();
00408         sprintf(txtstr,"Exiting Program");
00409         evbLCD->writeText(0, 4, font_6x8, txtstr, strlen(txtstr));
00410         exit(1);
00411     }
00412 
00413     if (!senet_demo) {
00414         lora_pl.clear();
00415         lora_pl.push_back(19);
00416         lora_pl.push_back(strlen(m2x_device));
00417         lora_pl.insert(lora_pl.end(), m2x_device, m2x_device + strlen(m2x_device));
00418         while ((mdot_ret = mdot_radio->send(lora_pl)) != mDot::MDOT_OK) {
00419             log_error(mdot_radio, "Failed to register m2x_device", mdot_ret);
00420             osDelay(2000);
00421         }
00422 
00423         lora_pl.clear();
00424         lora_pl.push_back(20);
00425         lora_pl.push_back(strlen(m2x_key));
00426         lora_pl.insert(lora_pl.end(), m2x_key, m2x_key + strlen(m2x_key));
00427         while ((mdot_ret = mdot_radio->send(lora_pl)) != mDot::MDOT_OK) {
00428             log_error(mdot_radio, "Failed to register m2x_key", mdot_ret);
00429             osDelay(2000);
00430         }
00431     }
00432 
00433     loops = 0;
00434     time_t tx_next = time(NULL) + tx_interval;
00435 
00436     /*
00437      * Main data acquisition loop
00438      */
00439     while (!exit_program) {
00440         osDelay(200);
00441 
00442         evbLCD->startUpdate();
00443         evbLCD->clearBuffer();
00444 
00445         /*
00446          * Test Accelerometer XYZ data ready bit to see if acquisition complete
00447          */
00448         count = 1;
00449         do {
00450             osDelay(100); // allows other threads to process
00451             result = evbAccel->getStatus();
00452             if ((count++ % 10) == 0) {
00453                 printf("waiting on accelerometer reading\r\n");
00454             }
00455         } while ((result & MMA845x::XYZDR) == 0);
00456 
00457         /*
00458          * Retrieve and print out accelerometer data
00459          */
00460         accel_data = evbAccel->getXYZ();
00461 
00462         sprintf(txtstr,"Accelerometer");
00463         evbLCD->writeText(0, 0, font_6x8, txtstr, strlen(txtstr));
00464         sprintf(txtstr, "x = %d", accel_data._x);
00465         evbLCD->writeText(20, 1, font_6x8, txtstr, strlen(txtstr));
00466         sprintf(txtstr, "y = %d", accel_data._y);
00467         evbLCD->writeText(20, 2, font_6x8, txtstr, strlen(txtstr));
00468         sprintf(txtstr, "z = %d", accel_data._z );
00469         evbLCD->writeText(20, 3, font_6x8, txtstr, strlen(txtstr));
00470 
00471         // convert to simple position value for use in send/recv
00472         if (accel_data._x > 500 && accel_data._z < 500) {
00473             position_value = 0x02;
00474         } else if (accel_data._x < 500 && accel_data._z > 500) {
00475             position_value = 0x01;
00476         } else {
00477             position_value= 0x00;
00478         }
00479 
00480         /*
00481          * Trigger a Pressure reading
00482          */
00483         evbBaro->setParameters(MPL3115A2::DATA_NORMAL, MPL3115A2::DM_BAROMETER, MPL3115A2::OR_16,
00484                                MPL3115A2::AT_1);
00485         evbBaro->triggerOneShot();
00486 
00487         /*
00488          * Test barometer device status to see if acquisition is complete
00489          */
00490         count = 1;
00491         do {
00492             osDelay(100); // allows other threads to process
00493             result = evbBaro->getStatus();
00494             if ((count++ % 10) == 0) {
00495                 printf("waiting on barometer reading\r\n");
00496             }
00497         } while ((result & MPL3115A2::PTDR) == 0);
00498 
00499         /*
00500          * Retrieve and print out barometric pressure
00501          */
00502         pressure = evbBaro->getBaroData() >> 12; // convert 32 bit signed to 20 bit unsigned value
00503         num_whole = pressure >> 2; // 18 bit integer significant
00504         num_frac = (pressure & 0x3) * 25; // 2 bit fractional  0.25 per bit
00505         sprintf(txtstr,"Press=%ld.%02d Pa", num_whole, num_frac);
00506         evbLCD->writeText(0, 4, font_6x8, txtstr, strlen(txtstr));
00507 
00508         /*
00509          * Trigger an Altitude reading
00510          */
00511         evbBaro->setParameters(MPL3115A2::DATA_NORMAL, MPL3115A2::DM_ALTIMETER, MPL3115A2::OR_16,
00512                                MPL3115A2::AT_1);
00513         evbBaro->triggerOneShot();
00514 
00515         /*
00516          * Test barometer device status to see if acquisition is complete
00517          */
00518         count = 1;
00519         do {
00520             osDelay(100); // allows other threads to process
00521             result = evbBaro->getStatus();
00522             if ((count++ % 10) == 0) {
00523                 printf("waiting on temperature reading\r\n");
00524             }
00525         } while ((result & MPL3115A2::PTDR) == 0);
00526 
00527         /*
00528          * Retrieve and print out altitude and temperature
00529          */
00530         baro_data = evbBaro->getAllData(false);
00531         baro_data._baro /= 4096; // convert 32 bit signed to 20 bit signed value
00532         num_whole = baro_data._baro / 16; // 18 bit signed significant integer
00533         num_frac = (baro_data._baro & 0xF) * 625 / 100; // 4 bit fractional .0625 per bit
00534         sprintf(txtstr, "Alti=%ld.%03d m", num_whole, num_frac);
00535         evbLCD->writeText(0,5,font_6x8,txtstr,strlen(txtstr));
00536         num_whole = baro_data._temp / 16; // 8 bit signed significant integer
00537         num_frac = (baro_data._temp & 0x0F) * 625 / 10; // 4 bit fractional .0625 per bit
00538         sprintf(txtstr, "Temp=%ld.%03d C", num_whole, num_frac);
00539         evbLCD->writeText(0, 6, font_6x8, txtstr, strlen(txtstr));
00540 
00541         /*
00542          * retrieve and print out Ambient Light level
00543          */
00544         lux_data = evbAmbLight->getData();
00545         num_whole = lux_data * 24 / 100; // 16000 lux full scale .24 lux per bit
00546         num_frac = lux_data * 24 % 100;
00547         sprintf(txtstr, "Light=%ld.%02d lux", num_whole, num_frac);
00548         evbLCD->writeText(0, 7, font_6x8, txtstr, strlen(txtstr));
00549 
00550         evbLCD->endUpdate();
00551 
00552         if (time(NULL) > tx_next) {
00553             tx_next = time(NULL) + tx_interval;
00554 
00555             lora_pl.clear();
00556 
00557             if (senet_demo) {
00558                 // Position Value
00559                 lora_pl.push_back(0);
00560                 lora_pl.push_back(position_value);
00561             } else {
00562                 // Current Acceleration 3-Axis Value
00563                 lora_pl.push_back(14);
00564                 lora_pl.push_back(6);
00565                 converts.f_s = accel_data._x;
00566                 lora_pl.push_back(converts.t_u[1]);
00567                 lora_pl.push_back(converts.t_u[0]);
00568                 converts.f_s = accel_data._y;
00569                 lora_pl.push_back(converts.t_u[1]);
00570                 lora_pl.push_back(converts.t_u[0]);
00571                 converts.f_s = accel_data._z;
00572                 lora_pl.push_back(converts.t_u[1]);
00573                 lora_pl.push_back(converts.t_u[0]);
00574                 // Current Pressure Value
00575                 lora_pl.push_back(8);
00576                 lora_pl.push_back(3);
00577                 convertl.f_u = pressure;
00578                 lora_pl.push_back(convertl.t_u[2]);
00579                 lora_pl.push_back(convertl.t_u[1]);
00580                 lora_pl.push_back(convertl.t_u[0]);
00581                 // Current Ambient Light Value
00582                 lora_pl.push_back(5);
00583                 lora_pl.push_back(2);
00584                 converts.f_u = lux_data;
00585                 lora_pl.push_back(converts.t_u[1]);
00586                 lora_pl.push_back(converts.t_u[0]);
00587                 // Current Temperature Value
00588                 lora_pl.push_back(11);
00589                 lora_pl.push_back(2);
00590                 converts.f_s = baro_data._temp;
00591                 lora_pl.push_back(converts.t_u[1]);
00592                 lora_pl.push_back(converts.t_u[0]);
00593             }
00594 
00595             printf("Sending LoRa message, length: %d\r\n", lora_pl.size());
00596             if ((mdot_ret = mdot_radio->send(lora_pl)) != mDot::MDOT_OK) {
00597                 log_error(mdot_radio, "failed to send", mdot_ret);
00598             } else {
00599                 printf("successfully sent data to gateway\r\n");
00600 
00601                 if (senet_demo) {
00602                     lora_pl.clear();
00603                     if ((mdot_ret = mdot_radio->recv(lora_pl)) != mDot::MDOT_OK) {
00604                         log_error(mdot_radio, "failed to recv:", mdot_ret);
00605                     } else {
00606                         printf("recv data: ");
00607                         for(int i = 0;i < lora_pl.size();i++) {
00608                             printf("%02X", lora_pl[i]);
00609                         }
00610                         printf("\r\n");
00611                         if(lora_pl[0] == position_value) {
00612                             evbBackLight->setLEDCurrent(16);
00613                         } else {
00614                             evbBackLight->setLEDCurrent(0);
00615                         }
00616                     }
00617                 }
00618             }
00619         }
00620 
00621         printf("finished iteration %d\r\n", loops++);
00622     }
00623 
00624     evbBaro->triggerOneShot();
00625 
00626     do {
00627         osDelay(200); // allows other threads to process
00628         result = evbBaro->getStatus();
00629     } while ((result & MPL3115A2::PTDR) == 0);
00630 
00631     baro_data = evbBaro->getAllData(true);
00632     printf ("minBaro=%ld maxBaro=%ld minTemp=%d maxTemp=%d\r\n", baro_data._minbaro, baro_data._maxbaro,
00633             baro_data._mintemp, baro_data._maxtemp);
00634 
00635     printf("End of Test\r\n");
00636 
00637     evbLCD->clearBuffer();
00638     sprintf(txtstr,"Exiting Program");
00639     evbLCD->writeText(0, 4, font_6x8, txtstr, strlen(txtstr));
00640 }
00641 
00642 /*
00643  * Sets pb1_low flag. Slag is cleared in pb1_debounce thread
00644  */
00645 void pb1ISR(void)
00646 {
00647     if (!pb1_low)
00648         pb1_low = true;
00649 }
00650 
00651 /*
00652  * Debounces pb1. Also exits program if pushbutton 1 is pressed
00653  */
00654 void pb1_debounce(void const *args)
00655 {
00656     static uint8_t count = 0;
00657 
00658     while (true) {
00659         if (pb1_low && (mDot08 == 0)) {
00660             count++;
00661         } else {
00662             count = 0;
00663             pb1_low = false;
00664         }
00665 
00666         if (count == 5) {
00667             printf("pb1_debounce: setting exit_program\r\n");
00668             exit_program = true;
00669         }
00670 
00671         Thread::wait(5);
00672     }
00673 }
00674 
00675 /*
00676  * Sets pb2_low flag. Flag is cleared in pb2_debounce thread
00677  */
00678 void pb2ISR(void)
00679 {
00680     if (!pb2_low)
00681         pb2_low = true;
00682 }
00683 
00684 /*
00685  * Debounces pb2. Also changes packet transmit time to every other,
00686  * every fifth, or every tenth sample when SW2 pushed
00687  * Also triggers a thread to transmit a configuration packet
00688  */
00689 void pb2_debounce(void const *args)
00690 {
00691     static uint8_t count = 0;
00692 
00693     while (true) {
00694         if (pb2_low && (mDot09 == 0)) {
00695             count++;
00696         } else {
00697             count = 0;
00698             pb2_low = false;
00699         }
00700 
00701         if (count == 5) {
00702             if (tx_interval > 60) {
00703                 tx_interval = 60;
00704             } else if (tx_interval > 30) {
00705                 tx_interval = 30;
00706             } else if (tx_interval > 10) {
00707                 tx_interval = 10;
00708             } else {
00709                 tx_interval = 120;
00710             }
00711 
00712             thread_3->signal_set(0x10); // signal config_pkt_xmit to send packet
00713         }
00714 
00715         Thread::wait(5);
00716      }
00717  }
00718 
00719 /*
00720  *  Function that print clear text verion of mDot errors
00721  */
00722 void log_error(mDot *dot, const char *msg, int32_t retval)
00723 {
00724     printf("%s - %ld:%s, %s\r\n", msg, retval, mDot::getReturnCodeString(retval).c_str(), dot->getLastError().c_str());
00725 }
00726 
00727 /*
00728  * Thread that is triggered by SW2 ISR. Sends a packet to the LoRa server with the new Packet Transmission time setting
00729  */
00730 void config_pkt_xmit(void const *args)
00731 {
00732     std::vector<uint8_t> lora_pl;
00733 
00734     while (true) {
00735         Thread::signal_wait(0x10); // wait for pb2ISR to signal send
00736 
00737         lora_pl.clear();
00738         // Send packet transmission interval
00739         lora_pl.push_back(15);
00740         lora_pl.push_back(1);
00741         lora_pl.push_back(tx_interval);
00742 
00743         if ((mdot_ret = mdot_radio->send(lora_pl)) != mDot::MDOT_OK) {
00744             log_error(mdot_radio, "failed to send config data", mdot_ret);
00745         } else {
00746             printf("sent config data to gateway\r\n");
00747         }
00748     }
00749 }