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
main.cpp
00001 /*================================================================================ 00002 * 00003 * CLASIFICATION: **** PUBLIC RELEASE AS-IS APPLICATION EXAMPLE **** 00004 * 00005 * SOURCE FILE NAME: main.cpp 00006 * 00007 * DESCRIPTIVE NAME: MBED Source for MultiTech mDot, EVB, and MDOT-BOX Devices 00008 * 00009 * COPYRIGHT: Copyright 2014-2017, Telit 00010 * 00011 * LICENSED MATERIAL - PROGRAM PROPERTY OF TELIT 00012 * REFER TO TELIT COPYRIGHT INSTRUCTION 00013 * 00014 ** WEB SITE: www.telit.com 00015 * 00016 * WRITTEN BY: Eliott Fersko and John Keever 00017 * 00018 * DATE: April 17, 2017 00019 * 00020 * VERSION: 1.02 00021 * 00022 * FUNCTION: Provide working example for LoRa 'Sensor-to-Cloud' 00023 * Demonstration using MultiTech LoRa Starter Kit and 00024 * Telit Data and Cloud Platform Services Offerings 00025 * 00026 * SOURCE FILE TYPE: MBED C++ 00027 * 00028 * FUNCTIONS/ENTRY POINTS: main 00029 * 00030 * INPUT = None. 00031 * OUTPUT = None. 00032 * 00033 * EXIT-NORMAL = N/A 00034 * EXIT-ERROR = N/A 00035 * 00036 * EXTERNAL REFERENCES = None. 00037 * 00038 * EXTERNAL FUNCTIONS = None. 00039 * 00040 * CONTROL BLOCKS = None. 00041 * 00042 *================================================================================*/ 00043 /* LEGAL DISCLAIMER */ 00044 /*================================================================================ 00045 00046 Redistribution and use in source and binary forms, with or without 00047 modification, are permitted provided that the following conditions 00048 are met: 00049 00050 Neither the name of ILS Technology nor Telit nor the names of its 00051 contributors may be used to endorse or promote products derived 00052 from this software without specific prior written permission. 00053 00054 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 00055 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00056 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 00057 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 00058 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 00059 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 00060 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 00061 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 00062 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00063 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 00064 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00065 00066 *================================================================================*/ 00067 /* CHANGE LOG */ 00068 /*================================================================================*/ 00069 /* |Changed | | */ 00070 /* Date | by |Version ID| Comments */ 00071 /*----------+--------+----------+-------------------------------------------------*/ 00072 /*04-12-2017|JEK |V1.00 |Original Version - mDot, EVB, MDOT-BOX */ 00073 /*04-14-2017|JEK |V1.01 |Added IRQ Handlers - SW1/SW2 (Threads?) */ 00074 /*04-17-2017|JEK |V1.02 |Added Binary LoRa Payload Message Framing Type */ 00075 /*04-24-2017|EMF |V1.03 |Updated Libraries */ 00076 /*05-10-2017|EMF |V1.04 |Added support for ST-Micro MEMS Sensor Shield */ 00077 /*================================================================================*/ 00078 /*NOTE: Please keep the change log up to date!!! */ 00079 /*================================================================================*/ 00080 00081 #include "mbed.h" 00082 #include "MMA845x.h" 00083 #include "MPL3115A2.h" 00084 #include "ISL29011.h" 00085 #include "NCP5623B.h" 00086 #include "DOGS102.h" 00087 #include "font_6x8.h" 00088 #include "MultiTech_Logo.h" 00089 #include "mDot.h" 00090 #include "rtos.h" 00091 #include "GPSPARSER.h" 00092 #include "MTSSerial.h" 00093 #include "x_nucleo_iks01a1.h" 00094 00095 #include <cmath> 00096 #include <string> 00097 #include <vector> 00098 #include <ctime> 00099 #include <Ticker.h> 00100 00101 #define CALL_METH(obj, meth, param, ret) ((obj == NULL) ? \ 00102 ((*(param) = (ret)), 0) : \ 00103 ((obj)->meth(param)) \ 00104 ) 00105 00106 00107 enum LED1_COLOR { 00108 RED = 0, 00109 GREEN = 1 00110 }; 00111 00112 namespace { 00113 const int MS_INTERVALS = 1000; 00114 } 00115 00116 /* 00117 * union for converting from 32-bit to 4 8-bit values 00118 */ 00119 union convert32 { 00120 int32_t f_s; // convert from signed 32 bit int 00121 uint32_t f_u; // convert from unsigned 32 bit int 00122 uint8_t t_u[4]; // convert to 8 bit unsigned array 00123 }; 00124 00125 typedef struct { 00126 int32_t AXIS_X; 00127 int32_t AXIS_Y; 00128 int32_t AXIS_Z; 00129 } AxesRaw_TypeDef; 00130 00131 00132 /* 00133 * union for converting from 16- bit to 2 8-bit values 00134 */ 00135 union convert16 { 00136 int16_t f_s; // convert from signed 16 bit int 00137 uint16_t f_u; // convert from unsigned 16 bit int 00138 uint8_t t_u[2]; // convert to 8 bit unsigned array 00139 }; 00140 00141 //DigitalIn mDot02(PA_2); // GPIO/UART_TX 00142 //DigitalOut mDot03(PA_3); // GPIO/UART_RX 00143 //DigitalIn mDot04(PA_6); // GPIO/SPI_MISO 00144 //DigitalIn mDot06(PA_8); // GPIO/I2C_SCL 00145 //DigitalIn mDot07(PC_9); // GPIO/I2C_SDA 00146 00147 InterruptIn mDot08(PA_12); // GPIO/USB PB S1 on EVB 00148 InterruptIn mDot09(PA_11); // GPIO/USB PB S2 on EVB 00149 00150 //DigitalIn mDot11(PA_7); // GPIO/SPI_MOSI 00151 00152 InterruptIn mDot12(PA_0); // GPIO/UART_CTS PRESSURE_INT2 on EVB 00153 DigitalOut mDot13(PC_13,1); // GPIO LCD_C/D 00154 InterruptIn mDot15(PC_1); // GPIO LIGHT_PROX_INT on EVB 00155 InterruptIn mDot16(PA_1); // GPIO/UART_RTS ACCEL_INT2 on EVB 00156 DigitalOut mDot17(PA_4,1); // GPIO/SPI_NCS LCD_CS on EVB 00157 00158 // DigitalIn mDot18(PA_5); // GPIO/SPI_SCK 00159 // DigitalInOut mDot19(PB_0,PIN_INPUT,PullNone,0); // GPIO PushPull LED Low=Red High=Green set MODE=INPUT to turn off 00160 // AnalogIn mDot20(PB_1); // GPIO Current Sense Analog in on EVB 00161 00162 Serial debugUART(PA_9, PA_10); // mDot debug UART 00163 MTSSerial mDotUART(PA_2,PA_3); // mDot external UART mDot02 and mDot03 00164 I2C mDoti2c(PC_9,PA_8); // mDot External I2C mDot6 and mDot7 00165 SPI mDotspi(PA_7,PA_6,PA_5); // mDot external SPI mDot11, mDot4, and mDot18 00166 AnalogIn current_sensor(PB_1); // EVB - GPIO - Current Sensor Analog Input 00167 00168 /* **** replace these values with the proper public or private network settings **** 00169 * config_network_nameand config_network_pass are for private networks. 00170 */ 00171 00172 //static std::string config_network_name = "telitlora"; 00173 //static std::string config_network_pass = "telitpass"; 00174 //static uint8_t config_frequency_sub_band = 7; 00175 00176 00177 00178 static volatile bool timer_irq_triggered = false; 00179 static volatile bool ff_irq_triggered = false; 00180 00181 static std::string config_network_name = "MTCDT-19186797"; 00182 static std::string config_network_pass = "MTCDT-19186797"; 00183 static uint8_t config_frequency_sub_band = 1; 00184 00185 /* config_app_id and config_app_key are for public networks. 00186 static uint8_t app_id[8] = {0x00,0x01,0x02,0x03,0x0A,0x0B,0x0C,0x0D}; 00187 std::vector<uint8_t> config_app_id; 00188 static uint8_t app_key[16] = {0x00,0x01,0x02,0x03,0x0A,0x0B,0x0C,0x0D}; 00189 std::vector<uint8_t> config_app_key; 00190 */ 00191 00192 uint8_t result; 00193 uint8_t data; 00194 uint8_t sf_val = mDot::SF_7; 00195 uint8_t pwr_val = 11; // dBm 00196 uint8_t swp_pwr; 00197 uint8_t swp_sf; 00198 00199 // max size of text string for 6x8 font. Set to 12 if using 8x8 font 00200 char txtstr[17]; 00201 00202 int32_t mdot_ret; 00203 int32_t join_delay; 00204 00205 osThreadId mainThreadID; 00206 00207 // flags for push button debounce code 00208 bool pb1_low = false; 00209 bool pb2_low = false; 00210 bool toggle_text = false; 00211 bool sw1_state = false; 00212 bool sw2_state = false; 00213 00214 uint32_t num_whole; 00215 uint16_t num_frac; 00216 00217 uint32_t pressure; 00218 double current; 00219 00220 bool exit_program = false; 00221 00222 //EVB sensor variables 00223 MMA845x_DATA accel_data; 00224 MPL3115A2_DATA baro_data; 00225 uint16_t lux_data; 00226 MMA845x* evbAccel; 00227 MPL3115A2* evbBaro; 00228 ISL29011* evbAmbLight; 00229 NCP5623B* evbBackLight; 00230 DOGS102* evbLCD; 00231 00232 //MEMS sensor variables 00233 float TEMPERATURE_Value; 00234 float HUMIDITY_Value; 00235 float PRESSURE_Value; 00236 float PRESSURE_Temp_Value; 00237 AxesRaw_TypeDef MAG_Value; 00238 AxesRaw_TypeDef ACC_Value; 00239 AxesRaw_TypeDef GYR_Value; 00240 char buffer1[32]; 00241 char buffer2[32]; 00242 char buffer3[32]; 00243 char buffer4[32]; 00244 unsigned int ret = 0; 00245 00246 mDot* mdot_radio; 00247 Mutex mdot_mutex; 00248 00249 //MEMS shield sensor variables 00250 //static X_NUCLEO_IKS01A1 *mems_expansion_board = X_NUCLEO_IKS01A1::Instance(); 00251 X_NUCLEO_IKS01A1 *mems_expansion_board = X_NUCLEO_IKS01A1::Instance(I2C_SDA, I2C_SCL, PC_1); 00252 static Ticker ticker; 00253 00254 00255 GyroSensor *memsGyro; 00256 MotionSensor *memsAccel; 00257 MagneticSensor *memsMag; 00258 HumiditySensor *memsHumidity; 00259 PressureSensor *memsPressure; 00260 TempSensor *memsTemp1; 00261 TempSensor *memsTemp2; 00262 00263 00264 GPSPARSER* mdot_gps; 00265 00266 convert32 convertl; 00267 convert16 converts; 00268 00269 void pb1ISR(void); 00270 void pb2ISR(void); 00271 void pb1_debounce(void const *args); 00272 void pb2_debounce(void const *args); 00273 00274 MPL3115A2* resetBaro(const MPL3115A2* oldBaro); 00275 void log_error(mDot* dot, const char* msg, int32_t retval); 00276 int32_t sendString(const std::string text); 00277 bool writeValueOrError(); 00278 00279 const int FAIL_MAX=15; 00280 int failtime=FAIL_MAX; 00281 int cycle_cnt = 0; 00282 00283 char sensor_text[64]; 00284 char lora_temp_string[16]; 00285 char lora_alt_string[16]; 00286 char lora_press_string[16]; 00287 char lora_light_string[16]; 00288 char lora_current_string[16]; 00289 char lora_humid_string[16]; 00290 00291 bool bHasGPS = false; 00292 bool bHasACC = false; 00293 bool bHasLCD = false; 00294 00295 /*** Helper Functions ------------------------------------------------------------ ***/ 00296 /* print floats & doubles */ 00297 static char *printDouble(char* str, double v, int decimalDigits=2) 00298 { 00299 int i = 1; 00300 int intPart, fractPart; 00301 int len; 00302 char *ptr; 00303 00304 /* prepare decimal digits multiplicator */ 00305 for (;decimalDigits!=0; i*=10, decimalDigits--); 00306 00307 /* calculate integer & fractinal parts */ 00308 intPart = (int)v; 00309 fractPart = (int)((v-(double)(int)v)*i); 00310 00311 /* fill in integer part */ 00312 sprintf(str, "%i.", intPart); 00313 00314 /* prepare fill in of fractional part */ 00315 len = strlen(str); 00316 ptr = &str[len]; 00317 00318 /* fill in leading fractional zeros */ 00319 for (i/=10;i>1; i/=10, ptr++) { 00320 if(fractPart >= i) break; 00321 *ptr = '0'; 00322 } 00323 00324 /* fill in (rest of) fractional part */ 00325 sprintf(ptr, "%i", fractPart); 00326 00327 return str; 00328 } 00329 /*=================================================================================== 00330 Main Program Logic - Entry 00331 ===================================================================================*/ 00332 int main() 00333 { 00334 std::vector<uint8_t> mdot_data; 00335 std::vector<uint8_t> mdot_EUI; 00336 uint16_t i = 0; 00337 uint8_t id1 = 0; 00338 00339 debugUART.baud(9600); 00340 00341 printf ("Starting Application...\r\n"); 00342 00343 mainThreadID = osThreadGetId(); 00344 00345 printf("Begin I2C/SPI Device Initialization...\r\n"); 00346 00347 00348 // Use Magnetometer As MEMS sensor shield Enumeration... 00349 00350 memsMag = mems_expansion_board->magnetometer; 00351 CALL_METH(memsMag, ReadID, &id1, 0x0); 00352 printf("Magnetometer ID value = %i \n\r", id1); 00353 00354 //chcek for default magnetomter ID 61... 00355 if(id1 == 61) 00356 { 00357 printf("Magnetometer Found - MEMS sensor shield detected...\r\n"); 00358 bHasACC = true; 00359 00360 // Initialize Integrated Sensors... 00361 printf("Instantiate Magnetometer...\r\n"); 00362 memsMag = mems_expansion_board->magnetometer; 00363 00364 printf("Instantiate Accelerometer...\r\n"); 00365 memsAccel = mems_expansion_board->GetAccelerometer(); 00366 00367 printf("Instantiate Gyroscope...\r\n"); 00368 memsGyro = mems_expansion_board->GetGyroscope(); 00369 00370 printf("Instantiate Barometric Pressure Sensor...\r\n"); 00371 memsPressure = mems_expansion_board->pt_sensor; 00372 00373 printf("Instantiate Temperature Pressure Sensor...\r\n"); 00374 //memsTemp1 = mems_expansion_board->ht_sensor; 00375 memsTemp2 = mems_expansion_board->pt_sensor; 00376 00377 printf("Instantiate Humidity Sensor...\r\n"); 00378 memsHumidity = mems_expansion_board->ht_sensor; 00379 00380 } 00381 00382 00383 else 00384 { 00385 printf("No Magnetometer Found...\r\n"); 00386 // Use Accelerometer As MDOT-BOX/EVB Enumeration... 00387 printf("Instantiate Accelerometer...\r\n"); 00388 evbAccel = new MMA845x(mDoti2c,MMA845x::SA0_VSS); 00389 00390 printf("Accelerometer Status = %d\r\n", evbAccel->getStatus()); 00391 printf("Accelerometer who_am_i value = %x \n\r", evbAccel->getWhoAmI()); 00392 00393 if( (evbAccel->getStatus() == 1) && (evbAccel->getWhoAmI() == 0) ) 00394 { 00395 printf("No Accelerometer Found - Basic mDot, Not MDOT-BOX or EVB...\r\n"); 00396 } 00397 00398 else 00399 { 00400 printf("Accelerometer Found - Either MDOT-BOX or EVB...\r\n"); 00401 bHasACC = true; 00402 00403 // Initialize Integrated Sensors... 00404 printf("Instantiate Barometric Pressure Sensor...\r\n"); 00405 evbBaro = new MPL3115A2(mDoti2c); // Setup Barometric Sensor 00406 printf("Barometric Sensor Status = %d\r\n", evbBaro->getStatus()); 00407 printf("Barometer who_am_i check = %d\r\n", evbBaro->testWhoAmI()); 00408 printf("Barometer who_am_i check = %s\r\n", evbBaro->testWhoAmI() ? "TRUE" : "FALSE"); 00409 00410 if( evbBaro->getStatus() == 0 ) printf("No Barometric Sensor...\r\n"); 00411 00412 printf("Instantiate Ambient Light Sensor...\r\n"); 00413 evbAmbLight = new ISL29011(mDoti2c); // Setup Ambient Light Sensor 00414 00415 // Setup the Accelerometer for 8g range, 14 bit resolution, Noise reduction off, sample rate 1.56 Hz 00416 // Normal oversample mode, High pass filter off 00417 evbAccel->setCommonParameters(MMA845x::RANGE_8g,MMA845x::RES_MAX,MMA845x::LN_OFF, MMA845x::DR_1_56,MMA845x::OS_NORMAL,MMA845x::HPF_OFF ); 00418 00419 // Setup the Barometric sensor for post processed Ambient pressure, 4 samples per data acquisition. 00420 // and a sample taken every second when in active mode 00421 evbBaro->setParameters(MPL3115A2::DATA_NORMAL, MPL3115A2::DM_BAROMETER, MPL3115A2::OR_16, MPL3115A2::AT_1); 00422 00423 // Setup the Ambient Light Sensor for continuous Ambient Light Sensing, 16 bit resolution, and 16000 lux range 00424 evbAmbLight->setMode(ISL29011::ALS_CONT); 00425 evbAmbLight->setResolution(ISL29011::ADC_16BIT); 00426 evbAmbLight->setRange(ISL29011::RNG_16000); 00427 00428 // Set the accelerometer for active mode 00429 evbAccel->activeMode(); 00430 00431 // Clear the min-max registers in the Barometric Sensor 00432 evbBaro->clearMinMaxRegs(); 00433 00434 // Support Integrated LCD Display 00435 bHasLCD = true; 00436 00437 printf("Instantiate BackLight and LCD Display...\r\n"); 00438 evbBackLight = new NCP5623B(mDoti2c); // setup backlight and LED 2 driver chip 00439 00440 evbLCD = new DOGS102(mDotspi, mDot17, mDot13); // setup LCD Display 00441 00442 printf("Font Table Address: %p\r\n",&font_6x8); 00443 printf("Bitmap Logo Address: %p\r\n",&MultiTech_Logo); 00444 00445 // Setup and display logo on LCD 00446 evbLCD->startUpdate(); 00447 evbLCD->writeBitmap(0,0,MultiTech_Logo); 00448 00449 sprintf(txtstr,"MTDOT-EVB"); 00450 evbLCD->writeText(24,3,font_6x8,txtstr,strlen(txtstr)); 00451 sprintf(txtstr,"Sensor Demo"); 00452 evbLCD->writeText(18,4,font_6x8,txtstr,strlen(txtstr)); 00453 00454 evbLCD->endUpdate(); 00455 00456 printf("Setup PushButton Interface Handlers...\r\n"); 00457 00458 printf("Launching Debounce Threads...\r\n"); 00459 Thread thread_1(pb1_debounce); 00460 Thread thread_2(pb2_debounce); 00461 printf("Debounce Threads Launched...\r\n"); 00462 00463 printf("Set SW1/SW2 IRQs...\r\n"); 00464 // Setup SW1 as Data rate and power out select 00465 mDot08.disable_irq(); 00466 mDot08.fall(&pb1ISR); 00467 00468 // need to call this function after rise or fall because rise/fall sets mode to PullNone 00469 mDot08.mode(PullUp); 00470 mDot08.enable_irq(); 00471 00472 // Setup SW2 as send PING 00473 mDot09.disable_irq(); 00474 mDot09.fall(&pb2ISR); 00475 00476 // need to call this function after rise or fall because rise/fall sets mode to PullNone 00477 mDot09.mode(PullUp); 00478 mDot09.enable_irq(); 00479 00480 // Setting other InterruptIn pins with Pull Ups 00481 mDot12.mode(PullUp); 00482 mDot15.mode(PullUp); 00483 mDot16.mode(PullUp); 00484 00485 printf("SW1/SW2 IRQs Set...\r\n"); 00486 } 00487 } 00488 00489 printf("I2C/SPI Device Initialization Complete...\r\n"); 00490 00491 printf("\r\nSetup mDot Radio Communications...\r\n"); 00492 00493 // get a mDot handle 00494 mdot_radio = mDot::getInstance(); 00495 00496 if (mdot_radio) 00497 { 00498 // reset to default config so we know what state we're in 00499 mdot_mutex.lock(); // lock mdot before setting configuration 00500 mdot_radio->resetConfig(); 00501 00502 // Setting up LED1 as activity LED 00503 mdot_radio->setActivityLedPin(PB_0); 00504 mdot_radio->setActivityLedEnable(true); 00505 00506 // Read node ID 00507 mdot_EUI = mdot_radio->getDeviceId(); 00508 printf("mDot EUI = "); 00509 00510 for(i=0; i<mdot_EUI.size(); i++) { 00511 printf("%02x ", mdot_EUI[i]); 00512 } 00513 printf("\r\n"); 00514 00515 // Setting up the mDot with network information. 00516 00517 // This call sets up private or public mode on the MTDOT. Set the function to true if 00518 // connecting to a public network 00519 printf("Setting Private Network Mode...\r\n"); 00520 if ((mdot_ret = mdot_radio->setPublicNetwork(false)) != mDot::MDOT_OK) { 00521 log_error(mdot_radio, "ERROR: Failed to set Public Network Mode", mdot_ret); 00522 } 00523 00524 // Frequency sub-band is valid for NAM only and for Private networks should be set to a value 00525 // between 1-8 that matches the the LoRa gateway setting. Public networks use sub-band 0 only. 00526 // This function can be commented out for EU networks 00527 printf("Setting Frequency Sub-Band...\r\n"); 00528 if ((mdot_ret = mdot_radio->setFrequencySubBand(config_frequency_sub_band)) != mDot::MDOT_OK) { 00529 log_error(mdot_radio, "ERROR: Failed to set Frequency Sub-Band", mdot_ret); 00530 } 00531 00532 // Setting TX power for radio. Max allowed is +14dBm for EU and +20 dBm for NAM. Default is +11 dBm 00533 printf("Setting TX Power Level to %2d dBm...\r\n", pwr_val); 00534 if ((mdot_ret = mdot_radio->setTxPower(pwr_val)) != mDot::MDOT_OK) { 00535 log_error(mdot_radio, "ERROR: Failed to set TX Power Level", mdot_ret); 00536 } 00537 00538 // Setting TX data rate for radio. Max allowed is SF_12 for EU and SF10 dBm for NAM. Default is SF_10 00539 printf("Setting TX data rate to SF_7...\r\n"); 00540 if ((mdot_ret = mdot_radio->setTxDataRate(sf_val)) != mDot::MDOT_OK) { 00541 log_error(mdot_radio, "ERROR: Failed to set TX Data Rate", mdot_ret); 00542 } 00543 00544 // Configure Pushbutton Display Labels... 00545 sprintf(txtstr,"SF=%2d PWR=%2d",sf_val,pwr_val); 00546 if( bHasLCD ) evbLCD->writeText(0,7,font_6x8,txtstr,strlen(txtstr)); 00547 printf("%s\r\n",txtstr); 00548 00549 00550 // Setting Packet ACK to 1 try. 00551 00552 printf("Setting Packet Retry to 1...\r\n"); 00553 if ((mdot_ret = mdot_radio->setAck(1)) != mDot::MDOT_OK) { 00554 log_error(mdot_radio, "ERROR: Failed to set Packet Retry\r\n", mdot_ret); 00555 } 00556 00557 00558 // setNetworkName is used for private networks. 00559 // Use setNetworkID(AppID) for public networks 00560 00561 // config_app_id.assign(app_id,app_id+7); 00562 00563 printf("Setting Network Name...\r\n"); 00564 if ((mdot_ret = mdot_radio->setNetworkName(config_network_name)) != mDot::MDOT_OK) { 00565 // if ((mdot_ret = mdot_radio->setNetworkID(config_app_id)) != mDot::MDOT_OK) { 00566 log_error(mdot_radio, "ERROR: Failed to set Network Name", mdot_ret); 00567 } 00568 00569 // setNetworkPassphrase is used for private networks 00570 // Use setNetworkKey for public networks 00571 00572 // config_app_key.assign(app_key,app_key+15); 00573 00574 printf("Setting Network Password...\r\n"); 00575 if ((mdot_ret = mdot_radio->setNetworkPassphrase(config_network_pass)) != mDot::MDOT_OK) { 00576 // if ((mdot_ret = mdot_radio->setNetworkKey(config_app_key)) != mDot::MDOT_OK) { 00577 log_error(mdot_radio, "ERROR: Failed to set Network Password", mdot_ret); 00578 } 00579 00580 mdot_mutex.unlock(); // unlock mdot mutex before join attempt so SW1 can work 00581 00582 // attempt to join the network 00583 printf("Joining LoRa Network...\r\n"); 00584 do { 00585 mdot_mutex.lock(); // lock mdot mutex before join attempt 00586 mdot_ret = mdot_radio->joinNetwork(); 00587 mdot_mutex.unlock(); // unlock mdot mutex after join attempt so SW1 can work 00588 00589 if (mdot_ret != mDot::MDOT_OK) 00590 { 00591 log_error(mdot_radio,"ERROR: Failed to Join Network:", mdot_ret); 00592 00593 if (toggle_text) 00594 sprintf(txtstr," > Join Failed <"); 00595 else 00596 sprintf(txtstr," < Join Failed >"); 00597 00598 if( bHasLCD ) evbLCD->writeText(0,5,font_6x8,txtstr,strlen(txtstr)); 00599 00600 if (mdot_radio->getFrequencyBand() == mDot::FB_868) 00601 { 00602 join_delay = mdot_radio->getNextTxMs(); 00603 } 00604 else 00605 { 00606 join_delay = 10; 00607 } 00608 printf("Join Delay = %lu\r\n",join_delay); 00609 osDelay(join_delay + 1); 00610 toggle_text = !toggle_text; 00611 } 00612 00613 /* 00614 * Setting TX power and Data Rate for radio just in case user requested by SW2 00615 */ 00616 mdot_mutex.lock(); // lock mdot mutex before setting change 00617 mdot_radio->setTxPower(pwr_val); 00618 mdot_radio->setTxDataRate(sf_val); 00619 mdot_mutex.unlock(); // unlock mdot mutex after settings change so SW1 can work 00620 00621 } while (mdot_ret != mDot::MDOT_OK); 00622 00623 printf("Successfully Joined LoRa Network...\r\n"); 00624 00625 sprintf(txtstr,"*Network Joined*"); 00626 if( bHasLCD ) evbLCD->writeText(0,5,font_6x8,txtstr,strlen(txtstr)); 00627 00628 } 00629 else 00630 { 00631 printf("ERROR: Unable to Join LoRa Network...\r\n"); 00632 sprintf(txtstr,"Radio Init Failed!"); 00633 if( bHasLCD ) evbLCD->writeText(0,5,font_6x8,txtstr,strlen(txtstr)); 00634 printf("%s\r\n",txtstr); 00635 exit(1); 00636 } 00637 00638 // Check for MDOT-BOX Configuration (GPS) 00639 00640 if( bHasACC && bHasLCD ) 00641 { 00642 printf("Instantiate GPS...\r\n"); 00643 mdot_gps = new GPSPARSER(&mDotUART); 00644 00645 if(!mdot_gps->gpsDetected()) 00646 { 00647 printf(">>>> No GPS Detected... Not an MDOT-BOX, EVB Identified\r\n"); 00648 00649 sprintf(txtstr,"*No GPS Detected*"); 00650 if( bHasLCD ) evbLCD->writeText(0,6,font_6x8,txtstr,strlen(txtstr)); 00651 } 00652 else 00653 { 00654 // main_single = main_sweep = false; 00655 do 00656 { 00657 // osSignalWait(0x10, 2000); 00658 if (mdot_gps->getLockStatus()) 00659 { 00660 sprintf(txtstr,"!!GPS locked!!"); 00661 if( bHasLCD ) evbLCD->writeText(0,6,font_6x8,txtstr,strlen(txtstr)); 00662 printf("%s \r\n",txtstr); 00663 } 00664 else 00665 { 00666 if (toggle_text) 00667 sprintf(txtstr," > no GPS lock <"); 00668 else 00669 sprintf(txtstr," < no GPS lock >"); 00670 00671 if( bHasLCD ) evbLCD->writeText(0,6,font_6x8,txtstr,strlen(txtstr)); 00672 printf("%s \r\n",txtstr); 00673 toggle_text = !toggle_text; 00674 } 00675 } while ( !(mdot_gps->getLockStatus()) ); 00676 } 00677 } 00678 00679 printf("Initialization/Configuration Completed...\r\n"); 00680 00681 osDelay(1500); 00682 if( bHasLCD ) evbBackLight->setPWM(NCP5623B::LED_3,16); // enable LED2 on EVB and set to 50% PWM 00683 00684 // sets LED2 to 50% max current 00685 if( bHasLCD ) evbBackLight->setLEDCurrent(16); 00686 00687 00688 // Check for PB1 press during network join attempt 00689 /* 00690 if (exit_program) 00691 { 00692 printf("PB1 Pressed, Exiting Program...\r\n"); 00693 if( bHasLCD ) evbLCD->clearBuffer(); 00694 sprintf(txtstr,"Exiting Program"); 00695 if( bHasLCD ) evbLCD->writeText(0,4,font_6x8,txtstr,strlen(txtstr)); 00696 exit(1); 00697 } 00698 */ 00699 00700 // Enter Main Data Acquisition Loop... 00701 printf("Processing Data Acquisition Scan Loop...\r\n"); 00702 00703 i = 0; 00704 cycle_cnt = 100; 00705 00706 if( bHasLCD ) evbLCD->clearBuffer(); 00707 00708 do 00709 { 00710 //EVB 00711 if( bHasACC && bHasLCD ) 00712 { 00713 // Check Accelerometer XYZ data ready bit to see if acquisition complete 00714 failtime = FAIL_MAX; 00715 do 00716 { 00717 osDelay(100); // allows other threads to process 00718 result = evbAccel->getStatus(); 00719 failtime--; 00720 } while ((result & MMA845x::XYZDR) == 0 && failtime > 0); 00721 00722 if (failtime==0) 00723 { 00724 evbBaro=resetBaro(evbBaro); 00725 continue; 00726 } 00727 00728 // Retrieve and print out accelerometer data 00729 accel_data = evbAccel->getXYZ(); 00730 sprintf(txtstr, "Accel-X = %d", accel_data._x); 00731 evbLCD->writeText(0,0,font_6x8,txtstr,strlen(txtstr)); 00732 sprintf(txtstr, "Accel-Y = %d", accel_data._y); 00733 evbLCD->writeText(0,1,font_6x8,txtstr,strlen(txtstr)); 00734 sprintf(txtstr, "Accel-Z = %d", accel_data._z ); 00735 evbLCD->writeText(0,2,font_6x8,txtstr,strlen(txtstr)); 00736 00737 // Trigger a Barometric Pressure Reading 00738 evbBaro->setParameters(MPL3115A2::DATA_NORMAL, MPL3115A2::DM_BAROMETER, MPL3115A2::OR_16, MPL3115A2::AT_1); 00739 evbBaro->triggerOneShot(); 00740 00741 // Test Barometer Device, Check to see if acquisition is complete 00742 failtime=FAIL_MAX; 00743 do 00744 { 00745 osDelay(100); // allows other threads to process 00746 result = evbBaro->getStatus(); 00747 failtime--; 00748 } while ((result & MPL3115A2::PTDR) == 0 && failtime > 0 ); 00749 00750 if(failtime==0) 00751 { 00752 evbBaro=resetBaro(evbBaro); 00753 continue; 00754 } 00755 00756 // Retrieve and Display Barometric Pressure 00757 pressure = evbBaro->getBaroData() >> 12; // convert 32 bit signed to 20 bit unsigned value 00758 num_whole = pressure >> 2; // 18 bit integer significant 00759 num_frac = (pressure & 0x3) * 25; // 2 bit fractional 0.25 per bit 00760 00761 // If failtime reached 0 , indicates that the result might be junk. 00762 sprintf(txtstr,"Press=%ld.%01d Pa", num_whole, num_frac/10); 00763 00764 pressure = evbBaro->getBaroData() >> 12; // convert 32 bit signed to 20 bit unsigned value 00765 num_whole = pressure >> 2; // 18 bit integer significant 00766 num_frac = (pressure & 0x3) * 25; // 2 bit fractional 0.25 per bit 00767 00768 writeValueOrError(); // will write to lorapresstring and txtstr 00769 00770 // Trigger a Altitude reading 00771 // evbBaro->setAltitudeCalib(101); 00772 evbBaro->setParameters(MPL3115A2::DATA_NORMAL, MPL3115A2::DM_ALTIMETER, MPL3115A2::OR_16, MPL3115A2::AT_1); 00773 // evbBaro->setAltitudeCalib(101); 00774 evbBaro->triggerOneShot(); 00775 00776 // Test barometer device status to see if acquisition is complete 00777 failtime=FAIL_MAX; 00778 do 00779 { 00780 osDelay(100); // allows other threads to process 00781 result = evbBaro->getStatus(); 00782 failtime--; 00783 } while ((result & MPL3115A2::PTDR) == 0 && failtime > 0 ); 00784 00785 if (failtime==0) 00786 { 00787 evbBaro=resetBaro(evbBaro); 00788 continue; 00789 } 00790 00791 // Retrieve and Display Altimeter Reading 00792 baro_data = evbBaro->getAllData(false); 00793 baro_data._baro /= 4096; // convert 32 bit signed to 20 bit signed value 00794 num_whole = baro_data._baro / 16; // 18 bit signed significant integer (JEK Added 60 as SWAG Offset for Boca) 00795 num_frac = (baro_data._baro & 0xF) * 625 / 100; // 4 bit fractional .0625 per bit 00796 sprintf(txtstr,"Alti=%ld.%03d m", num_whole, num_frac); 00797 sprintf(lora_alt_string,"%ld.%03d", num_whole, num_frac); 00798 evbLCD->writeText(0,4,font_6x8,txtstr,strlen(txtstr)); 00799 00800 // Retrieve and Display Temperature Reading 00801 num_whole = baro_data._temp / 16; // 8 bit signed significant integer 00802 num_frac = (baro_data._temp & 0x0F) * 625 / 100; // 4 bit fractional .0625 per bit 00803 sprintf(txtstr,"Temp=%ld.%03d C", num_whole, num_frac); 00804 sprintf(lora_temp_string,"%ld.%03d", num_whole, num_frac); 00805 evbLCD->writeText(0,5,font_6x8,txtstr,strlen(txtstr)); 00806 00807 // Retrieve and Display Ambient Light Level 00808 lux_data = evbAmbLight->getData(); 00809 num_whole = lux_data * 24 / 100; // 16000 lux full scale .24 lux per bit 00810 num_frac = lux_data * 24 % 100; 00811 sprintf(txtstr, "Light=%ld.%02d lux", num_whole, num_frac ); 00812 sprintf(lora_light_string, "%ld.%02d", num_whole, num_frac ); 00813 evbLCD->writeText(0,6,font_6x8,txtstr,strlen(txtstr)); 00814 00815 // Retrieve and Display Current Sensor Level (EVB Analog Input) 00816 current = (double) current_sensor * 65535.0; 00817 sprintf(lora_current_string, "%d", (int) current); 00818 00819 // Handle Pushbutton #1 (SW1) - This should be handled by the 'pb1_debounce' thread. 00820 if( pb1_low ) 00821 { 00822 sw1_state = !sw1_state; 00823 if( bHasLCD ) evbBackLight->setPWM(NCP5623B::LED_3,0); // enable LED2 on EVB and set to 0% PWM 00824 00825 sprintf(txtstr,"PB1 Press-SW1: %d", sw1_state); 00826 if( bHasLCD ) evbLCD->writeText(0,7,font_6x8,txtstr,strlen(txtstr)); 00827 printf("%s \r\n",txtstr); 00828 00829 pb1_low = false; 00830 } 00831 00832 // Handle Pushbutton #2 (SW2) - This should be handled by the 'pb2_debounce' thread. 00833 if( pb2_low ) 00834 { 00835 sw2_state = !sw2_state; 00836 if( bHasLCD ) evbBackLight->setPWM(NCP5623B::LED_3,16); // enable LED2 on EVB and set to 50% PWM 00837 00838 sprintf(txtstr,"PB2 Press-SW2: %d", sw2_state); 00839 if( bHasLCD ) evbLCD->writeText(0,7,font_6x8,txtstr,strlen(txtstr)); 00840 printf("%s \r\n",txtstr); 00841 00842 pb2_low = false; 00843 } 00844 } 00845 //MEMS 00846 else if(!bHasLCD && bHasACC) 00847 { 00848 00849 std::vector<uint8_t> tx_data; 00850 00851 00852 // Payload structure for mydevices cayenne: 00853 // 1 byte Data1 ID 00854 // 1 Byte Data1 Type 00855 // N Bytes Data1 00856 // 1 byte data 2 ID 00857 // 1 byte data 2 type 00858 // n Bytes data 2 00859 // ... 00860 00861 // formats: 00862 // Temperature sensor: 00863 /* 00864 * IPSO: 3303 00865 * LPP 103 00866 * HEX: 67 00867 * Data size: 2 00868 * Resolution: 0.1 degres C 00869 00870 * Humidity sensor 00871 * IPSO: 3304 00872 * LPP: 104 00873 * Hex: 68 00874 * Datasize: 1 00875 * Resolution: 0.5% unsigned 00876 00877 * Barometer/pressure sensor 00878 * IPSO: 3315 00879 * LPP: 115 00880 * Hex: 73 00881 * Datasize: 2 00882 * Resolution 0.1hPa unsigned MSB 00883 00884 * Accelerometer 00885 * IPSO: 3313 00886 * LPP: 113 00887 * Hex: 71 00888 * Data size: 6 00889 * Resolution: 0.001G signed MSB per axis 00890 00891 * Gyrometer 00892 * IPSO: 3334 00893 * LPP: 134 00894 * Hex: 86 00895 * Data size: 6 00896 * Resolution: 0.01 degrees/s signed msb per axis 00897 */ 00898 00899 //temp floats 00900 float temp_value, humid_value, pressure_value; 00901 int16_t int_temp_value, int_humid_value, int_pressure_value; 00902 00903 // HTS221 Humidity sensor 00904 00905 ret |= (!CALL_METH(memsTemp1, GetTemperature, &temp_value, 0.0f) ? 0x0 : 0x1); 00906 ret |= (!CALL_METH(memsHumidity, GetHumidity, &humid_value, 0.0f) ? 0x0 : 0x2);; 00907 00908 /* 00909 //serialize data and append to packet 00910 // Cayenne data: temperature; tag is 0x67, 2 bytes signed, 0.1 C/bit 00911 tx_data.push_back(uint8_t(1)); // data id 00912 tx_data.push_back(uint8_t(0x67)); // data type - temp 00913 int_temp_value = floor(temp_value*10 + 0.5f); 00914 tx_data.push_back(uint8_t( 0xFF & (int_temp_value >> 8))); 00915 tx_data.push_back(uint8_t(0xFF & int_temp_value)); 00916 00917 00918 tx_data.push_back(uint8_t(2)); // data id 00919 tx_data.push_back(uint8_t(0x68)); // data type - humidity 00920 int_humid_value = floor(humid_value * 2.0f + 0.5f); 00921 tx_data.push_back(uint8_t(0xFF & int_humid_value )); 00922 */ 00923 00924 ret |= (!CALL_METH(memsPressure, GetPressure, &pressure_value, 0.0f) ? 0x0 : 0x4);; 00925 00926 /* 00927 // pressure is reported in mbar, cayenne wants it in 0.1 hPa 00928 // 1mbar = 1 hPa 00929 int_pressure_value = floor(pressure_value * 100.0f + 0.5f); 00930 00931 tx_data.push_back(uint8_t(3)); // data id 00932 tx_data.push_back(uint8_t(0x73)); // data type - pressure 00933 int_pressure_value = floor(pressure_value / 0.1f + 0.5f); 00934 tx_data.push_back(uint8_t(0xFF & (int_pressure_value >> 8))); 00935 tx_data.push_back(uint8_t(0xFF & int_pressure_value)); 00936 */ 00937 00938 // Get accelerometer data 00939 int32_t accel_vector[3]; 00940 // returns in mG 00941 memsAccel->Get_X_Axes(accel_vector); 00942 00943 /* 00944 tx_data.push_back(uint8_t(4)); // data id 00945 tx_data.push_back(uint8_t(0x71)); // data type - accelerometer 00946 for(int i=0; i<3; i++) { 00947 tx_data.push_back(uint8_t(0xFF & accel_vector[i]) >> 8); 00948 tx_data.push_back(uint8_t(0xFF & accel_vector[i])); 00949 } 00950 */ 00951 00952 // Get gyro data 00953 int32_t gyro_vector[3]; 00954 memsGyro->Get_G_Axes(gyro_vector); 00955 00956 /* 00957 // gyro reports in milidegrees/sec, cayenne wants centidegrees/sec 00958 tx_data.push_back(uint8_t(5)); //data id 00959 tx_data.push_back(uint8_t(0x86)); // data type - gyrometer 00960 for(int i=0; i<3; i++) { 00961 gyro_vector[i] /= 10; 00962 tx_data.push_back(uint8_t(0xFF & (gyro_vector[i] >> 8))); 00963 tx_data.push_back(uint8_t(0xFF & gyro_vector[i])); 00964 } 00965 */ 00966 00967 // Get magnetometer data 00968 int32_t mag_vector[3]; 00969 memsMag->Get_M_Axes(mag_vector); 00970 // gyro reports in milidegrees/sec, cayenne wants centidegrees/sec 00971 00972 /* 00973 tx_data.push_back(uint8_t(5)); //data id 00974 tx_data.push_back(uint8_t(0x99)); // data type - mangetometer 00975 for(int i=0; i<3; i++) { 00976 mag_vector[i] /= 10; 00977 tx_data.push_back(uint8_t(0xFF & (mag_vector[i] >> 8))); 00978 tx_data.push_back(uint8_t(0xFF & mag_vector[i])); 00979 } 00980 */ 00981 00982 00983 //send_data(tx_data); 00984 00985 //--------------------------------------------------------------------------- 00986 // Verbose Text Format: Least Data Payload, Most Human Readible 00987 //--------------------------------------------------------------------------- 00988 00989 /* 00990 if(!bHasLCD && bHasACC) 00991 { 00992 00993 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", 00994 accel_vector[0], 00995 accel_vector[1], 00996 accel_vector[2], 00997 gyro_vector[0], 00998 gyro_vector[1], 00999 gyro_vector[2], 01000 mag_vector[0], 01001 mag_vector[1], 01002 mag_vector[2], 01003 printDouble(buffer3, pressure_value), 01004 printDouble(buffer1, temp_value), 01005 printDouble(buffer2, humid_value)); 01006 } 01007 else 01008 { 01009 sprintf(sensor_text, "accel-x:%d|accel-y:%d|accel-z:%d|press:%s|alti:%s|temp:%s|light:%s|moist:%s", 01010 accel_data._x, 01011 accel_data._y, 01012 accel_data._z, 01013 lora_press_string, 01014 lora_alt_string, 01015 lora_temp_string, 01016 lora_light_string, 01017 lora_current_string); 01018 01019 } 01020 01021 01022 if ((mdot_ret = sendString((const std::string)sensor_text)) != mDot::MDOT_OK) { 01023 log_error(mdot_radio, "ERROR: Failed to Send Data", mdot_ret); 01024 } else { 01025 printf("Ok, Successfully Sent Data to Gateway...\r\n"); 01026 } 01027 */ 01028 01029 if( cycle_cnt > 30 ) 01030 { 01031 sprintf(txtstr,"Transmitting... "); 01032 if( bHasLCD ) evbLCD->writeText(0,7,font_6x8,txtstr,strlen(txtstr)); 01033 01034 01035 //--------------------------------------------------------------------------- 01036 // Byte Vector Format: More Data Payload, Less Human Readible 01037 //--------------------------------------------------------------------------- 01038 01039 if(!bHasLCD && bHasACC) 01040 { 01041 01042 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", 01043 accel_vector[0], 01044 accel_vector[1], 01045 accel_vector[2], 01046 gyro_vector[0], 01047 gyro_vector[1], 01048 gyro_vector[2], 01049 mag_vector[0], 01050 mag_vector[1], 01051 mag_vector[2], 01052 printDouble(buffer3, pressure_value), 01053 printDouble(buffer1, temp_value), 01054 printDouble(buffer2, humid_value)); 01055 } 01056 01057 else 01058 { 01059 sprintf(sensor_text, "x:%d,y:%d,z:%d,p:%s,al:%s,t:%s,l:%s,c:%s", 01060 accel_data._x, 01061 accel_data._y, 01062 accel_data._z, 01063 lora_press_string, 01064 lora_alt_string, 01065 lora_temp_string, 01066 lora_light_string, 01067 lora_current_string); 01068 } 01069 01070 if ((mdot_ret = sendString((const std::string)sensor_text)) != mDot::MDOT_OK) { 01071 log_error(mdot_radio, "ERROR: Failed to Send Data", mdot_ret); 01072 } else { 01073 printf("Ok, Successfully Sent Data to Gateway...\r\n"); 01074 } 01075 01076 /* 01077 //--------------------------------------------------------------------------- 01078 // Binary Encoded Format: Most Data Payload, Not Human Readible 01079 //--------------------------------------------------------------------------- 01080 mdot_data.clear(); 01081 mdot_data.push_back(0x0E); // key for Current Acceleration 3-Axis Value 01082 converts.f_s = accel_data._x *4; // shift data 2 bits while retaining sign 01083 mdot_data.push_back(converts.t_u[1]); // get 8 MSB of 14 bit value 01084 converts.f_s = accel_data._y * 4; // shift data 2 bits while retaining sign 01085 mdot_data.push_back(converts.t_u[1]); // get 8 MSB of 14 bit value 01086 converts.f_s = accel_data._z * 4; // shift data 2 bits while retaining sign 01087 mdot_data.push_back(converts.t_u[1]); // get 8 MSB of 14 bit value 01088 mdot_data.push_back(0x08); // key for Current Pressure Value 01089 convertl.f_u = pressure; // pressure data is 20 bits unsigned 01090 mdot_data.push_back(convertl.t_u[2]); 01091 mdot_data.push_back(convertl.t_u[1]); 01092 mdot_data.push_back(convertl.t_u[0]); 01093 mdot_data.push_back(0x05); // key for Current Ambient Light Value 01094 converts.f_u = lux_data; // data is 16 bits unsigned 01095 mdot_data.push_back(converts.t_u[1]); 01096 mdot_data.push_back(converts.t_u[0]); 01097 mdot_data.push_back(0x0B); // key for Current Temperature Value 01098 converts.f_s = baro_data._temp; // temperature is signed 12 bit 01099 mdot_data.push_back(converts.t_u[1]); 01100 mdot_data.push_back(converts.t_u[0]); 01101 01102 if ((mdot_ret = mdot_radio->send(mdot_data)) != mDot::MDOT_OK) { 01103 log_error(mdot_radio, "ERROR: Failed to Send Data", mdot_ret); 01104 } else { 01105 printf("Ok, Successfully Sent Data to Gateway...\r\n"); 01106 } 01107 01108 */ 01109 01110 osDelay(500); 01111 sprintf(txtstr,"Scanning... "); 01112 if( bHasLCD ) evbLCD->writeText(0,7,font_6x8,txtstr,strlen(txtstr)); 01113 cycle_cnt = 0; 01114 } 01115 } 01116 01117 osDelay(1000); 01118 cycle_cnt++; 01119 01120 // Put Thread to Sleep for 30 Seconds... 01121 // osDelay(30000); 01122 01123 } while(i < 86400); 01124 01125 printf("End of Data Collection Cycle (24 Hours) - Ending Application, GoodBye...\r\n"); 01126 01127 if( bHasLCD ) evbLCD->clearBuffer(); 01128 sprintf(txtstr,"Exiting Program"); 01129 if( bHasLCD ) evbLCD->writeText(0,7,font_6x8,txtstr,strlen(txtstr)); 01130 } 01131 01132 /*** Interrupt Handler Top-Halves ------------------------------------------------------ ***/ 01133 /* Called in interrupt context, therefore just set a trigger variable */ 01134 static void timer_irq(void) { 01135 timer_irq_triggered = true; 01136 } 01137 01138 /* Called in interrupt context, therefore just set a trigger variable */ 01139 static void ff_irq(void) { 01140 ff_irq_triggered = true; 01141 01142 /* Disable IRQ until handled */ 01143 mems_expansion_board->gyro_lsm6ds3->Disable_Free_Fall_Detection_IRQ(); 01144 } 01145 01146 01147 /*** Interrupt Handler Bottom-Halves ------------------------------------------------- ***/ 01148 /* Handle Free Fall Interrupt 01149 (here we are in "normal" context, i.e. not in IRQ context) 01150 */ 01151 static void handle_ff_irq(void) { 01152 printf("\nFree Fall Detected!\n\n"); 01153 01154 /* Re-enable IRQ */ 01155 mems_expansion_board->gyro_lsm6ds3->Enable_Free_Fall_Detection_IRQ(); 01156 } 01157 01158 /*=================================================================================== 01159 Send String Payload to Conduit Gateway 01160 ===================================================================================*/ 01161 int32_t sendString(const std::string text) 01162 { 01163 int32_t ret; 01164 if (mdot_radio->getNextTxMs() != 0) 01165 { 01166 printf("Sending in %lu ms...\r\n", mdot_radio->getNextTxMs()); 01167 return false; 01168 } 01169 01170 printf("Sending: '%s'\r\n", text.c_str()); 01171 std::vector<uint8_t> data(text.begin(), text.end()); 01172 if ((ret = mdot_radio->send(data, 1)) != mDot::MDOT_OK) 01173 { 01174 log_error(mdot_radio, "ERROR: Failed to Send Data", ret); 01175 } 01176 01177 return ret; 01178 } 01179 01180 /*=================================================================================== 01181 Interrupt Service Request Handler - Sets pb1_low flag. Flag is cleared in pb1_debounce thread 01182 ===================================================================================*/ 01183 void pb1ISR(void) 01184 { 01185 pb1_low = true; 01186 } 01187 01188 /*=================================================================================== 01189 Pushbutton Debounce - Debounces pb1 PB1 changes SW1 State Value (Sets LED Off) 01190 ===================================================================================*/ 01191 void pb1_debounce(void const *args) 01192 { 01193 printf("Thread pb1_debounce started...\r\n"); 01194 01195 while(true) 01196 { 01197 // if( pb1_low && (mDot08 == 0)) 01198 if( pb1_low ) 01199 { 01200 sprintf(txtstr,"PB1 Pressed..."); 01201 if( bHasLCD ) evbLCD->writeText(0,7,font_6x8,txtstr,strlen(txtstr)); 01202 printf("%s\r\n",txtstr); 01203 01204 pb1_low = false; 01205 } 01206 01207 Thread::wait(50); 01208 } 01209 } 01210 01211 /*=================================================================================== 01212 Interrupt Service Request Handler - Sets pb1_low flag. Flag is cleared in pb1_debounce thread 01213 ===================================================================================*/ 01214 void pb2ISR(void) 01215 { 01216 pb2_low = true; 01217 } 01218 01219 /*=================================================================================== 01220 Pushbutton Debounce - Debounces pb2 PB2 changes SW2 State Value (Sets LED On) 01221 ===================================================================================*/ 01222 void pb2_debounce(void const *args) 01223 { 01224 printf("Thread pb2_debounce started...\r\n"); 01225 01226 while(true) 01227 { 01228 // if( pb2_low && (mDot09 == 1)) 01229 if( pb2_low ) 01230 { 01231 sprintf(txtstr,"PB2 Pressed..."); 01232 if( bHasLCD ) evbLCD->writeText(0,7,font_6x8,txtstr,strlen(txtstr)); 01233 printf("%s \r\n",txtstr); 01234 01235 pb2_low = false; 01236 } 01237 01238 Thread::wait(50); 01239 } 01240 } 01241 01242 /*=================================================================================== 01243 Display Value/Error String of Barometric Pressure Sensor 01244 ===================================================================================*/ 01245 bool writeValueOrError() 01246 { 01247 bool res; 01248 01249 if (failtime==0) 01250 { 01251 sprintf(lora_press_string, "%s", "--.--"); 01252 sprintf(txtstr, "%s", "--.--"); 01253 if( bHasLCD ) evbLCD->writeText(0,4,font_6x8,txtstr, strlen(txtstr)); 01254 res=false; 01255 } 01256 else 01257 { 01258 sprintf(lora_press_string, "%ld.%02d", num_whole, num_frac); 01259 if( bHasLCD ) evbLCD->writeText(0,3,font_6x8,txtstr,strlen(txtstr)); 01260 res=true; 01261 } 01262 01263 return res; 01264 } 01265 01266 /*=================================================================================== 01267 Resets Barometric Pressure Sensor 01268 ===================================================================================*/ 01269 MPL3115A2* resetBaro(const MPL3115A2* oldBaro) 01270 { 01271 delete oldBaro; 01272 MPL3115A2* baro = new MPL3115A2(mDoti2c); 01273 baro->testWhoAmI(); 01274 01275 printf("Resetting barometer.. %x \n\r", baro->getStatus() ); 01276 baro->setParameters(MPL3115A2::DATA_NORMAL, MPL3115A2::DM_BAROMETER, MPL3115A2::OR_16, MPL3115A2::AT_1); 01277 evbBaro->clearMinMaxRegs(); 01278 01279 return baro; 01280 } 01281 01282 /*=================================================================================== 01283 Print clear text verion of mDot/EVB errors 01284 ===================================================================================*/ 01285 void log_error(mDot* dot, const char* msg, int32_t retval) 01286 { 01287 printf("%s - %ld:%s, %s\r\n", msg, retval, mDot::getReturnCodeString(retval).c_str(), dot->getLastError().c_str()); 01288 }
Generated on Wed Jul 13 2022 07:33:19 by
1.7.2