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 ISL29011 MMA845x MPL3115A2 NCP5623B libmDot mbed-rtos mbed
main.cpp
00001 /** 00002 * @file main.cpp 00003 * @brief Main application for mDot-EVB demo 00004 * @author Tim Barr MultiTech Systems Inc. 00005 * @version 1.05 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 TAB 10/22/15 Fixed format error in temperature print to LCD. Corrected error in 00032 * public netework setup. Swapped \n and \r in prinf calls because 00033 * Windows seems to be picky about the order 00034 * 00035 * 1.05 TAB 11/17/15 Changed baud rate for debug from 921k to 115k. Added code to support 00036 * 868 MHz band operation. Added mutex around certain mDot radio commands. 00037 * Changed network name and passphrase. Changed pb references to sw to 00038 * match MTDOT-BOX overlay. Changed function of SW1 from end program to 00039 * cycle through power levels and data rates. 00040 */ 00041 00042 #include "mbed.h" 00043 #include "MMA845x.h" 00044 #include "MPL3115A2.h" 00045 #include "ISL29011.h" 00046 #include "NCP5623B.h" 00047 #include "DOGS102.h" 00048 #include "font_6x8.h" 00049 #include "MultiTech_Logo.h" 00050 #include "mDot.h" 00051 #include "rtos.h" 00052 #include <string> 00053 #include <vector> 00054 00055 enum LED1_COLOR { 00056 RED = 0, 00057 GREEN = 1 00058 }; 00059 00060 /* 00061 * union for converting from 32-bit to 4 8-bit values 00062 */ 00063 union convert32 { 00064 int32_t f_s; // convert from signed 32 bit int 00065 uint32_t f_u; // convert from unsigned 32 bit int 00066 uint8_t t_u[4]; // convert to 8 bit unsigned array 00067 }; 00068 00069 /* 00070 * union for converting from 16- bit to 2 8-bit values 00071 */ 00072 union convert16 { 00073 int16_t f_s; // convert from signed 16 bit int 00074 uint16_t f_u; // convert from unsigned 16 bit int 00075 uint8_t t_u[2]; // convert to 8 bit unsigned array 00076 }; 00077 00078 //DigitalIn mDot02(PA_2); // GPIO/UART_TX 00079 //DigitalOut mDot03(PA_3); // GPIO/UART_RX 00080 //DigitalIn mDot04(PA_6); // GPIO/SPI_MISO 00081 //DigitalIn mDot06(PA_8); // GPIO/I2C_SCL 00082 //DigitalIn mDot07(PC_9); // GPIO/I2C_SDA 00083 00084 InterruptIn mDot08(PA_12); // GPIO/USB PB SW1 on EVB 00085 InterruptIn mDot09(PA_11); // GPIO/USB PB SW2 on EVB 00086 00087 //DigitalIn mDot11(PA_7); // GPIO/SPI_MOSI 00088 00089 InterruptIn mDot12(PA_0); // GPIO/UART_CTS PRESSURE_INT2 on EVB 00090 DigitalOut mDot13(PC_13,1); // GPIO LCD_C/D 00091 InterruptIn mDot15(PC_1); // GPIO LIGHT_PROX_INT on EVB 00092 InterruptIn mDot16(PA_1); // GPIO/UART_RTS ACCEL_INT2 on EVB 00093 DigitalOut mDot17(PA_4,1); // GPIO/SPI_NCS LCD_CS on EVB 00094 00095 //DigitalIn mDot18(PA_5); // GPIO/SPI_SCK 00096 00097 //DigitalInOut mDot19(PB_0,PIN_INPUT,PullNone,0); // GPIO PushPull LED Low=Red High=Green set MODE=INPUT to turn off 00098 AnalogIn mDot20(PB_1); // GPIO Current Sense Analog in on EVB 00099 00100 Serial debugUART(PA_9, PA_10); // mDot debug UART 00101 00102 //Serial mDotUART(PA_2, PA_3); // mDot external UART mDot02 and mDot03 00103 00104 I2C mDoti2c(PC_9,PA_8); // mDot External I2C mDot6 and mDot7 00105 00106 SPI mDotspi(PA_7,PA_6,PA_5); // mDot external SPI mDot11, mDot4, and mDot18 00107 00108 /* **** replace these values with the proper public or private network settings **** 00109 * config_network_name and config_network_pass are for private networks. 00110 */ 00111 00112 //Default network server settings 00113 static std::string config_network_name = "Multitech"; 00114 static std::string config_network_pass = "Multitech"; 00115 static uint8_t config_frequency_sub_band = 3; 00116 00117 /* config_app_id and config_app_key are for public networks. 00118 static uint8_t app_id[8] = {0x00,0x01,0x02,0x03,0x0A,0x0B,0x0C,0x0D}; 00119 std::vector<uint8_t> config_app_id; 00120 static uint8_t app_key[16] = {0x00,0x01,0x02,0x03,0x0A,0x0B,0x0C,0x0D}; 00121 std::vector<uint8_t> config_app_key; 00122 */ 00123 00124 uint8_t result, mdot_freq; 00125 uint8_t pckt_time = 8; 00126 uint16_t xmit_delay = 8; 00127 char data; 00128 unsigned char test; 00129 char txtstr[17]; 00130 int32_t num_whole, mdot_ret, join_delay; 00131 uint32_t pressure; 00132 int16_t num_frac; 00133 uint8_t sf_val = mDot::SF_7; 00134 uint8_t pwr_val = 11; // dBm 00135 00136 MMA845x_DATA accel_data; 00137 MPL3115A2_DATA baro_data; 00138 uint16_t lux_data; 00139 MMA845x* evbAccel; 00140 MPL3115A2* evbBaro; 00141 ISL29011* evbAmbLight; 00142 NCP5623B* evbBackLight; 00143 DOGS102* evbLCD; 00144 mDot* mdot_radio; 00145 Mutex mdot_mutex; 00146 00147 convert32 convertl; 00148 convert16 converts; 00149 00150 // flags for pushbutton debounce code 00151 bool sw1_low = false; 00152 bool sw2_low = false; 00153 bool toggle_text = false; 00154 00155 void sw1ISR(void); 00156 void sw2ISR(void); 00157 void sw1_debounce(void const *args); 00158 void sw2_debounce(void const *args); 00159 Thread* thread_3; 00160 00161 void log_error(mDot* dot, const char* msg, int32_t retval); 00162 00163 void config_pkt_xmit (void const *args); 00164 00165 int main() 00166 { 00167 00168 std::vector<uint8_t> mdot_data; 00169 std::vector<uint8_t> mdot_EUI; 00170 uint16_t i = 0; 00171 uint8_t j =0; 00172 00173 debugUART.baud(115200); 00174 // mDotUART.baud(9600); // mdot UART unused but available on external connector 00175 00176 Thread thread_1(sw1_debounce); // threads for de-bouncing pushbutton switches 00177 Thread thread_2(sw2_debounce); 00178 00179 thread_3 = new Thread(config_pkt_xmit); // start thread that sends LoRa packet when SW2 pressed 00180 00181 evbAccel = new MMA845x(mDoti2c,MMA845x::SA0_VSS); // setup Accelerometer 00182 evbBaro = new MPL3115A2(mDoti2c); // setup Barometric sensor 00183 evbAmbLight = new ISL29011(mDoti2c); // Setup Ambient Light Sensor 00184 evbBackLight = new NCP5623B(mDoti2c); // setup backlight and LED 2 driver chip 00185 evbLCD = new DOGS102(mDotspi, mDot17, mDot13); // setup LCD 00186 00187 /* 00188 * Setup SW1 as program stop function 00189 */ 00190 mDot08.disable_irq(); 00191 mDot08.fall(&sw1ISR); 00192 00193 /* 00194 * need to call this function after rise or fall because rise/fall sets 00195 * mode to PullNone 00196 */ 00197 mDot08.mode(PullUp); 00198 00199 mDot08.enable_irq(); 00200 00201 /* 00202 * Setup SW2 as packet time change 00203 */ 00204 mDot09.disable_irq(); 00205 mDot09.fall(&sw2ISR); 00206 00207 /* 00208 * need to call this function after rise or fall because rise/fall sets 00209 * mode to PullNone 00210 */ 00211 mDot09.mode(PullUp); 00212 00213 mDot09.enable_irq(); 00214 00215 /* 00216 * Setting other InterruptIn pins with Pull Ups 00217 */ 00218 mDot12.mode(PullUp); 00219 mDot15.mode(PullUp); 00220 mDot16.mode(PullUp); 00221 00222 printf("font table address %p\r\n",&font_6x8); 00223 printf("bitmap address %p\r\n",&MultiTech_Logo); 00224 00225 // Setup and display logo on LCD 00226 evbLCD->startUpdate(); 00227 00228 evbLCD->writeBitmap(0,0,MultiTech_Logo); 00229 00230 printf("\r\n setup mdot\r\n"); 00231 00232 // get a mDot handle 00233 mdot_radio = mDot::getInstance(); 00234 00235 if (mdot_radio) { 00236 mdot_mutex.lock(); // lock mdot before setting configuration 00237 00238 // reset to default config so we know what state we're in 00239 mdot_radio->resetConfig(); 00240 00241 // Setting up LED1 as activity LED 00242 mdot_radio->setActivityLedPin(PB_0); 00243 mdot_radio->setActivityLedEnable(true); 00244 00245 // Read node ID and frequency band 00246 mdot_EUI = mdot_radio->getDeviceId(); 00247 mdot_freq = mdot_radio->getFrequencyBand(); 00248 00249 printf("mDot EUI = "); 00250 00251 for (i=0; i<mdot_EUI.size(); i++) { 00252 printf("%02x ", mdot_EUI[i]); 00253 } 00254 printf("\r\n"); 00255 sprintf(txtstr,"MTDOT EVB"); 00256 printf("mDot Frequency = "); 00257 if (mdot_freq == mDot::FB_868) { 00258 printf( "868 MHz\r\n"); 00259 sprintf(txtstr,"%s 868 MHz",txtstr); 00260 } else { 00261 printf("915 MHz\r\n"); 00262 sprintf(txtstr,"%s 915 MHz",txtstr); 00263 } 00264 00265 evbLCD->writeText(0,3,font_6x8,txtstr,strlen(txtstr)); 00266 sprintf(txtstr,"Sensor Demo"); 00267 evbLCD->writeText(24,4,font_6x8,txtstr,strlen(txtstr)); 00268 00269 evbLCD->endUpdate(); 00270 00271 00272 // Setting up the mDot with network information. 00273 00274 /* 00275 * This call sets up private or public mode on the MTDOT. Set the function to true if 00276 * connecting to a public network 00277 */ 00278 printf("setting Private Network Mode\r\n"); 00279 if ((mdot_ret = mdot_radio->setPublicNetwork(false)) != mDot::MDOT_OK) { 00280 log_error(mdot_radio, "failed to set Public Network Mode", mdot_ret); 00281 } 00282 00283 /* 00284 * Frequency sub-band is valid for NAM only and for Private networks should be set to a value 00285 * between 1-8 that matches the the LoRa gateway setting. Public networks use sub-band 0 only. 00286 * This function can be commented out for EU networks 00287 */ 00288 if (mdot_freq == mDot::FB_915) { 00289 printf("setting frequency sub band\r\n"); 00290 if ((mdot_ret = mdot_radio->setFrequencySubBand(config_frequency_sub_band)) != mDot::MDOT_OK) { 00291 log_error(mdot_radio, "failed to set frequency sub band", mdot_ret); 00292 } 00293 } 00294 00295 /* 00296 * setNetworkName is used for private networks. 00297 * Use setNetworkID(AppID) for public networks 00298 */ 00299 00300 // config_app_id.assign(app_id,app_id+7); 00301 00302 printf("setting network name\r\n"); 00303 if ((mdot_ret = mdot_radio->setNetworkName(config_network_name)) != mDot::MDOT_OK) { 00304 // if ((mdot_ret = mdot_radio->setNetworkId(config_app_id)) != mDot::MDOT_OK) { 00305 log_error(mdot_radio, "failed to set network name", mdot_ret); 00306 } 00307 00308 /* 00309 * setNetworkPassphrase is used for private networks 00310 * Use setNetworkKey for public networks 00311 */ 00312 00313 // config_app_key.assign(app_key,app_key+15); 00314 00315 printf("setting network password\r\n"); 00316 if ((mdot_ret = mdot_radio->setNetworkPassphrase(config_network_pass)) != mDot::MDOT_OK) { 00317 // if ((mdot_ret = mdot_radio->setNetworkKey(config_app_key)) != mDot::MDOT_OK) { 00318 log_error(mdot_radio, "failed to set network password", mdot_ret); 00319 } 00320 00321 /* 00322 * Setting TX power for radio. Max allowed is +14dBm for EU and +20 dBm for NAM. Default is +11 dBm 00323 */ 00324 printf("setting TX Power Level to %2d dBm\r\n", pwr_val); 00325 if ((mdot_ret = mdot_radio->setTxPower(pwr_val)) != mDot::MDOT_OK) { 00326 log_error(mdot_radio, "failed to set TX power level", mdot_ret); 00327 } 00328 00329 /* 00330 * Setting TX data rate for radio. Max allowed is SF_12 for EU and SF10 dBm for NAM. Default is SF_9 00331 */ 00332 printf("setting TX data rate to SF_7\r\n"); 00333 if ((mdot_ret = mdot_radio->setTxDataRate(sf_val)) != mDot::MDOT_OK) { 00334 log_error(mdot_radio, "failed to set TX data rate", mdot_ret); 00335 } 00336 00337 mdot_mutex.unlock(); // unlock mdot mutex before join attempt so SW1 can work 00338 00339 // attempt to join the network 00340 printf("joining network\r\n"); 00341 do { 00342 mdot_mutex.lock(); // lock mdot mutex before join attempt 00343 mdot_ret = mdot_radio->joinNetwork(); 00344 mdot_mutex.unlock(); // unlock mdot mutex after join attempt so SW1 can work 00345 00346 if (mdot_ret != mDot::MDOT_OK) { 00347 log_error(mdot_radio,"failed to join network:", mdot_ret); 00348 00349 if (toggle_text) 00350 sprintf(txtstr," > Join Failed <"); 00351 else 00352 sprintf(txtstr," < Join Failed >"); 00353 00354 evbLCD->writeText(0,5,font_6x8,txtstr,strlen(txtstr)); 00355 00356 if (mdot_radio->getFrequencyBand() == mDot::FB_868) { 00357 join_delay = mdot_radio->getNextTxMs(); 00358 } else { 00359 join_delay = 10; 00360 } 00361 printf("delay = %lu\r\n",join_delay); 00362 osDelay(join_delay + 1); 00363 toggle_text = !toggle_text; 00364 } 00365 /* 00366 * Setting TX power and Data Rate for radio just in case user requested by SW2 00367 */ 00368 mdot_mutex.lock(); // lock mdot mutex before setting change 00369 mdot_radio->setTxPower(pwr_val); 00370 mdot_radio->setTxDataRate(sf_val); 00371 mdot_mutex.unlock(); // unlock mdot mutex after settings change 00372 00373 } while (mdot_ret != mDot::MDOT_OK); 00374 00375 sprintf(txtstr,"*Network Joined*"); 00376 evbLCD->writeText(0,5,font_6x8,txtstr,strlen(txtstr)); 00377 00378 } else { 00379 sprintf(txtstr,"Radio Init Failed!"); 00380 evbLCD->writeText(0,5,font_6x8,txtstr,strlen(txtstr)); 00381 printf("%s\r\n",txtstr); 00382 exit(1); 00383 } 00384 00385 osDelay(200); 00386 evbBackLight->setPWM(NCP5623B::LED_3,16); // enable LED2 on EVB and set to 50% PWM 00387 00388 // sets LED2 to 50% max current 00389 evbBackLight->setLEDCurrent(16); 00390 00391 printf("Start of Test\r\n"); 00392 00393 osDelay (500); // allows other threads to process 00394 printf("shutdown LED:\r\n"); 00395 evbBackLight->shutdown(); 00396 00397 osDelay (500); // allows other threads to process 00398 printf("Turn on LED2\r\n"); 00399 evbBackLight->setLEDCurrent(16); 00400 00401 data = evbAccel->getWhoAmI(); 00402 printf("Accelerometer who_am_i value = %x \r\n", data); 00403 00404 result = evbAccel->getStatus(); 00405 printf("status byte = %x \r\n", result); 00406 00407 printf("Barometer who_am_i check = %s \r\n", evbBaro->testWhoAmI() ? "TRUE" : "FALSE"); 00408 00409 result = evbBaro->getStatus(); 00410 printf("status byte = %x \r\n", result); 00411 00412 /* 00413 * Setup the Accelerometer for 8g range, 14 bit resolution, Noise reduction off, sample rate 1.56 Hz 00414 * normal oversample mode, High pass filter off 00415 */ 00416 evbAccel->setCommonParameters(MMA845x::RANGE_8g,MMA845x::RES_MAX,MMA845x::LN_OFF, 00417 MMA845x::DR_1_56,MMA845x::OS_NORMAL,MMA845x::HPF_OFF ); 00418 00419 /* 00420 * Setup the Barometric sensor for post processed Ambient pressure, 4 samples per data acquisition. 00421 * and a sample taken every second when in active mode 00422 */ 00423 evbBaro->setParameters(MPL3115A2::DATA_NORMAL, MPL3115A2::DM_BAROMETER, MPL3115A2::OR_16, 00424 MPL3115A2::AT_1); 00425 /* 00426 * Setup the Ambient Light Sensor for continuous Ambient Light Sensing, 16 bit resolution, 00427 * and 16000 lux range 00428 */ 00429 00430 evbAmbLight->setMode(ISL29011::ALS_CONT); 00431 evbAmbLight->setResolution(ISL29011::ADC_16BIT); 00432 evbAmbLight->setRange(ISL29011::RNG_16000); 00433 00434 /* 00435 * Set the accelerometer for active mode 00436 */ 00437 evbAccel->activeMode(); 00438 00439 /* 00440 * Clear the min-max registers in the Barometric Sensor 00441 */ 00442 evbBaro->clearMinMaxRegs(); 00443 00444 evbBackLight->setLEDCurrent(0); 00445 00446 /* 00447 * Main data acquisition loop 00448 */ 00449 00450 i = 0; 00451 00452 do { 00453 evbLCD->startUpdate(); 00454 // clear LCD line 0-6 only 00455 sprintf(txtstr, " "); 00456 for (j=0; j<6; j++) 00457 evbLCD->writeText(0,j,font_6x8,txtstr,strlen(txtstr)); 00458 00459 /* 00460 * Test Accelerometer XYZ data ready bit to see if acquisition complete 00461 */ 00462 do { 00463 osDelay(100); // allows other threads to process 00464 result = evbAccel->getStatus(); 00465 } while ((result & MMA845x::XYZDR) == 0 ); 00466 00467 /* 00468 * Retrieve and print out accelerometer data 00469 */ 00470 accel_data = evbAccel->getXYZ(); 00471 00472 sprintf(txtstr, "Accel: x = %d", accel_data._x); 00473 evbLCD->writeText(0,0,font_6x8,txtstr,strlen(txtstr)); 00474 sprintf(txtstr, "y = %d", accel_data._y); 00475 evbLCD->writeText(42,1,font_6x8,txtstr,strlen(txtstr)); 00476 sprintf(txtstr, "z = %d", accel_data._z ); 00477 evbLCD->writeText(42,2,font_6x8,txtstr,strlen(txtstr)); 00478 00479 /* 00480 * Trigger a Pressure reading 00481 */ 00482 evbBaro->setParameters(MPL3115A2::DATA_NORMAL, MPL3115A2::DM_BAROMETER, MPL3115A2::OR_16, 00483 MPL3115A2::AT_1); 00484 evbBaro->triggerOneShot(); 00485 00486 /* 00487 * Test barometer device status to see if acquisition is complete 00488 */ 00489 do { 00490 osDelay(100); // allows other threads to process 00491 result = evbBaro->getStatus(); 00492 } while ((result & MPL3115A2::PTDR) == 0 ); 00493 00494 /* 00495 * Retrieve and print out barometric pressure 00496 */ 00497 pressure = evbBaro->getBaroData() >> 12; // convert 32 bit signed to 20 bit unsigned value 00498 num_whole = pressure >> 2; // 18 bit integer significant 00499 num_frac = (pressure & 0x3) * 25; // 2 bit fractional 0.25 per bit 00500 sprintf(txtstr,"Press=%ld.%02d Pa", num_whole, num_frac); 00501 evbLCD->writeText(0,3,font_6x8,txtstr,strlen(txtstr)); 00502 00503 /* 00504 * Trigger a Altitude reading 00505 */ 00506 evbBaro->setParameters(MPL3115A2::DATA_NORMAL, MPL3115A2::DM_ALTIMETER, MPL3115A2::OR_16, 00507 MPL3115A2::AT_1); 00508 evbBaro->triggerOneShot(); 00509 00510 /* 00511 * Test barometer device status to see if acquisition is complete 00512 */ 00513 do { 00514 osDelay(100); // allows other threads to process 00515 result = evbBaro->getStatus(); 00516 } while ((result & MPL3115A2::PTDR) == 0 ); 00517 00518 /* 00519 * Retrieve and print out altitude and temperature 00520 */ 00521 baro_data = evbBaro->getAllData(false); 00522 baro_data._baro /= 4096; // convert 32 bit signed to 20 bit signed value 00523 num_whole = baro_data._baro / 16; // 18 bit signed significant integer 00524 num_frac = (baro_data._baro & 0xF) * 625 / 100; // 4 bit fractional .0625 per bit 00525 sprintf(txtstr,"Alti=%ld.%02d m", num_whole, num_frac); 00526 evbLCD->writeText(0,4,font_6x8,txtstr,strlen(txtstr)); 00527 num_whole = baro_data._temp / 16; // 8 bit signed significant integer 00528 num_frac = (baro_data._temp & 0x0F) * 625 / 100; // 4 bit fractional .0625 per bit 00529 sprintf(txtstr,"Temp=%ld.%03d C", num_whole, num_frac); 00530 evbLCD->writeText(0,5,font_6x8,txtstr,strlen(txtstr)); 00531 00532 /* 00533 * retrieve and print out Ambient Light level 00534 */ 00535 lux_data = evbAmbLight->getData(); 00536 num_whole = lux_data * 24 / 100; // 16000 lux full scale .24 lux per bit 00537 num_frac = lux_data * 24 % 100; 00538 sprintf(txtstr, "Light=%ld.%02d lux", num_whole, num_frac ); 00539 evbLCD->writeText(0,6,font_6x8,txtstr,strlen(txtstr)); 00540 00541 evbLCD->endUpdate(); 00542 00543 printf("finished iteration %d\r\n",(++i)); 00544 00545 /* Transmit data packet based on pckt_time setting and result of 00546 * mdot_radio->getNextTxMs() function and mutex available. The getNextTxMs() 00547 * function returns the number of millisecond before another packet can be 00548 * sent in 868 MHz band. This can vary depending on wther the 10%, 1% or 0.1% 00549 * channel is used and the time on air for a specific setup of the radio 00550 */ 00551 00552 if ((xmit_delay <= i) && (mdot_radio->getNextTxMs() == 0) && (mdot_mutex.trylock())) { 00553 /* 00554 * Setting TX power and Data Rate for radio just in case user requested by SW2 00555 */ 00556 mdot_radio->setTxPower(pwr_val); 00557 mdot_radio->setTxDataRate(sf_val); 00558 00559 mdot_data.clear(); 00560 mdot_data.push_back(0x1D); // key for start of data 00561 mdot_data.push_back(0x0E); // key for Current Acceleration 3-Axis Value 00562 converts.f_s = accel_data._x *4; // shift data 2 bits while retaining sign 00563 mdot_data.push_back(converts.t_u[1]); // get 8 MSB of 14 bit value 00564 converts.f_s = accel_data._y * 4; // shift data 2 bits while retaining sign 00565 mdot_data.push_back(converts.t_u[1]); // get 8 MSB of 14 bit value 00566 converts.f_s = accel_data._z * 4; // shift data 2 bits while retaining sign 00567 mdot_data.push_back(converts.t_u[1]); // get 8 MSB of 14 bit value 00568 mdot_data.push_back(0x08); // key for Current Pressure Value 00569 convertl.f_u = pressure; // pressure data is 20 bits unsigned 00570 mdot_data.push_back(convertl.t_u[2]); 00571 mdot_data.push_back(convertl.t_u[1]); 00572 mdot_data.push_back(convertl.t_u[0]); 00573 00574 /* for 915 MHz band and SF_10 max packet size is 11 bytes. 00575 * so the payload gets split in two packets here. 00576 */ 00577 if ((mdot_freq == mDot::FB_915) && (sf_val == mDot::SF_10)) { 00578 mdot_ret = mdot_radio->send(mdot_data); 00579 if ( mdot_ret != mDot::MDOT_OK) { 00580 sprintf(txtstr,"mDot Send failed"); 00581 evbLCD->writeText(0,7,font_6x8,txtstr,strlen(txtstr)); 00582 log_error(mdot_radio, txtstr, mdot_ret); 00583 continue; 00584 } else { 00585 printf("successfully sent packet 1 to gateway\r\n"); 00586 } 00587 mdot_data.clear(); // clear data for next "chunk" 00588 } 00589 00590 00591 mdot_data.push_back(0x05); // key for Current Ambient Light Value 00592 converts.f_u = lux_data; // data is 16 bits unsigned 00593 mdot_data.push_back(converts.t_u[1]); 00594 mdot_data.push_back(converts.t_u[0]); 00595 mdot_data.push_back(0x0B); // key for Current Temperature Value 00596 converts.f_s = baro_data._temp; // temperature is signed 12 bit 00597 mdot_data.push_back(converts.t_u[1]); 00598 mdot_data.push_back(converts.t_u[0]); 00599 mdot_data.push_back(0x1D); // key for end of data 00600 00601 mdot_ret = mdot_radio->send(mdot_data); 00602 if (mdot_ret != mDot::MDOT_OK) { 00603 log_error(mdot_radio, "failed to send", mdot_ret); 00604 sprintf(txtstr,"PKT Send Failed"); 00605 evbLCD->writeText(0,7,font_6x8,txtstr,strlen(txtstr)); 00606 } else { 00607 sprintf(txtstr,"SENT DR=%2d Pwr=%2d",(12 - sf_val),pwr_val); 00608 evbLCD->writeText(0,7,font_6x8,txtstr,strlen(txtstr)); 00609 printf("%s \r\n",txtstr); 00610 } 00611 mdot_mutex.unlock(); // unlock mutex after all data transmitted 00612 xmit_delay = i + pckt_time; 00613 if (mdot_freq == mDot::FB_868) 00614 printf("Next transmit time = %d milliseconds \r\n",mdot_radio->getNextTxMs()); 00615 00616 } else { 00617 sprintf(txtstr," DR=%2d Pwr=%2d ",(12 - sf_val),pwr_val); 00618 evbLCD->writeText(0,7,font_6x8,txtstr,strlen(txtstr)); 00619 } 00620 } while(i < 65000); 00621 00622 evbBaro->triggerOneShot(); 00623 00624 do { 00625 osDelay(200); // allows other threads to process 00626 result = evbBaro->getStatus(); 00627 } while ((result & MPL3115A2::PTDR) == 0 ); 00628 00629 baro_data = evbBaro->getAllData(true); 00630 printf ("minBaro=%ld maxBaro=%ld minTemp=%d maxTemp=%d\r\n", baro_data._minbaro, baro_data._maxbaro, 00631 baro_data._mintemp, baro_data._maxtemp); 00632 00633 printf("End of Test\r\n"); 00634 00635 evbLCD->clearBuffer(); 00636 sprintf(txtstr,"Exiting Program"); 00637 evbLCD->writeText(0,4,font_6x8,txtstr,strlen(txtstr)); 00638 00639 } 00640 00641 /* 00642 * Sets sw1_low flag. Slag is cleared in sw1_debounce thread 00643 */ 00644 void sw1ISR(void) 00645 { 00646 if (!sw1_low) 00647 sw1_low = true; 00648 } 00649 00650 /* 00651 * Debounces sw1 changes spreading factor and output power 00652 * Cycles through SF_7-SF_9 for 4 power levels for 915 MHz band 00653 * Cycles through SF_7-SF_12 for 4 power levels for 868 MHz band 00654 */ 00655 void sw1_debounce(void const *args) 00656 { 00657 static uint8_t count = 0; 00658 static uint8_t test_sf = 0; 00659 static uint8_t test_pwr = 0; 00660 00661 while (true) { 00662 00663 if (sw1_low && (mDot08 == 0)) 00664 count++; 00665 else { 00666 count = 0; 00667 sw1_low = false; 00668 } 00669 00670 if (count == 5) { 00671 test_sf++; 00672 00673 if (((test_sf > 3) && (mdot_freq == mDot::FB_915)) || ((test_sf > 5) && (mdot_freq == mDot::FB_868))) { 00674 test_sf = 0; 00675 test_pwr ++; 00676 if (test_pwr > 3) 00677 test_pwr = 0; 00678 } 00679 00680 // selects power output level using upper bits for select 00681 switch(test_pwr) { 00682 case 0: 00683 pwr_val = 11; 00684 break; 00685 case 1: 00686 pwr_val = 14; 00687 break; 00688 case 2: 00689 pwr_val = 18; 00690 break; 00691 case 3: 00692 pwr_val = 20; 00693 } 00694 00695 // sets data rate based on lower bits 00696 sf_val = mDot::SF_7 - (test_sf & 0x07); 00697 00698 sprintf(txtstr," DR=%2d Pwr=%2d ",(12 - sf_val),pwr_val); 00699 evbLCD->writeText(0,7,font_6x8,txtstr,strlen(txtstr)); 00700 printf("%s \r\n",txtstr); 00701 } 00702 00703 Thread::wait(5); 00704 } 00705 } 00706 00707 /* 00708 * Sets sw2_low flag. Flag is cleared in sw2_debounce thread 00709 */ 00710 void sw2ISR(void) 00711 { 00712 if (!sw2_low) 00713 sw2_low = true; 00714 } 00715 00716 /* 00717 * Debounces sw2. Changes packet transmit time to every 2nd, 00718 * 4th, 8th, or 16th sample when SW2 pushed. For 868 MHz mode 00719 * the time for next packet value is also tested. 00720 * Also triggers a thread to transmit a configuration packet 00721 */ 00722 void sw2_debounce(void const *args) 00723 { 00724 00725 static uint8_t count = 0; 00726 00727 while (true) { 00728 00729 if (sw2_low && (mDot09 == 0)) 00730 count++; 00731 else { 00732 count = 0; 00733 sw2_low = false; 00734 } 00735 00736 if (count == 5) { 00737 00738 if (pckt_time >= 4) 00739 pckt_time /= 2; 00740 else pckt_time = 16; 00741 00742 thread_3->signal_set(0x10); // signal config_pkt_xmit to send packet 00743 } 00744 00745 Thread::wait(5); 00746 } 00747 } 00748 00749 /* 00750 * Function that prints clear text verion of mDot errors 00751 */ 00752 void log_error(mDot* dot, const char* msg, int32_t retval) 00753 { 00754 printf("%s - %ld:%s, %s\r\n", msg, retval, mDot::getReturnCodeString(retval).c_str(), dot->getLastError().c_str()); 00755 } 00756 00757 /* 00758 * Thread that is triggered by SW2 ISR. Sends a packet to the LoRa server with the new Packet Transmission time setting 00759 */ 00760 void config_pkt_xmit (void const *args) 00761 { 00762 00763 std::vector<uint8_t> data; 00764 uint16_t wait_time; 00765 00766 while (true) { 00767 Thread::signal_wait(0x10); // wait for sw2ISR to signal send 00768 data.clear(); 00769 data.push_back(0x0F); // key for Configuration data (packet transmission timer) 00770 data.push_back(pckt_time); 00771 00772 mdot_mutex.lock(); // lock mdot mutex before packet send 00773 00774 if ((wait_time = mdot_radio->getNextTxMs()) > 0) // wait for next xmit time 00775 osDelay(wait_time); 00776 00777 if ((mdot_ret = mdot_radio->send(data)) != mDot::MDOT_OK) { 00778 log_error(mdot_radio, "failed to send config data", mdot_ret); 00779 } else { 00780 printf("sent config data to gateway\r\n"); 00781 } 00782 mdot_mutex.unlock(); // unlock mdot mutex after packet send 00783 } 00784 }
Generated on Fri Jul 15 2022 17:05:35 by
1.7.2