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: LoRaWAN-lib SX1272Lib lib_gps lib_mma8451q lib_mpl3115a2 mbed
Fork of LoRaWAN-NAMote72-Application-Demo_Multitech by
LoRaApp.cpp
00001 /* 00002 / _____) _ | | 00003 ( (____ _____ ____ _| |_ _____ ____| |__ 00004 \____ \| ___ | (_ _) ___ |/ ___) _ \ 00005 _____) ) ____| | | || |_| ____( (___| | | | 00006 (______/|_____)_|_|_| \__)_____)\____)_| |_| 00007 (C)2015 Semtech 00008 00009 Description: User-defined applications such as GPS, Temp, Accelerometer, LED indications etc. 00010 Event based actions such as LED blink on Tx, LED toggle on downlink etc 00011 00012 License: Revised BSD License, see LICENSE.TXT file include in the project 00013 00014 Maintainer: Uttam Bhat 00015 */ 00016 00017 #include "LoRaApp.h" 00018 00019 bool VerticalStatus = false; 00020 00021 /*! 00022 * Red LED timer event 00023 */ 00024 TimerLed RedLedTimer( Red ); 00025 00026 /*! 00027 * Yellow LED timer event 00028 */ 00029 TimerLed YellowLedTimer( Yellow ); 00030 00031 /*! 00032 * Green LED timer event 00033 */ 00034 TimerLed GreenLedTimer( Green ); 00035 00036 Application::Application( uint8_t * memptr ) 00037 { 00038 BuffAddr = memptr; 00039 memset( BuffAddr, 0, LORAWAN_APP_DATA_MAX_SIZE ); 00040 BuffPtr = 0; 00041 } 00042 00043 Application::~Application( ) 00044 { 00045 } 00046 00047 void Application::ApplicationAppendData( uint8_t *pData, uint8_t len ) 00048 { 00049 if( ( BuffPtr + len ) <= LORAWAN_APP_DATA_SIZE ) 00050 { 00051 memcpy( BuffAddr + BuffPtr, pData, len ); 00052 BuffPtr += len; 00053 } 00054 } 00055 00056 void Application::ApplicationPtrPos( uint8_t ptrPos ) 00057 { 00058 BuffPtr = ptrPos; 00059 } 00060 00061 void Application::ApplicationCall( eAppType App ) 00062 { 00063 switch( App ) 00064 { 00065 // Appends 8 Bytes (3 bytes longitude, 3 bytes latitude, 2 bytes altitude) to TX buffer 00066 case AppGps: 00067 { 00068 Gps.service( ); 00069 00070 uint16_t altitudeGps = atoi( Gps.NmeaGpsData.NmeaAltitude ); 00071 00072 if( ( BuffPtr + 8 ) <= LORAWAN_APP_DATA_SIZE ) 00073 { 00074 BuffAddr[BuffPtr++] = ( Gps.LatitudeBinary >> 16 ) & 0xFF; 00075 BuffAddr[BuffPtr++] = ( Gps.LatitudeBinary >> 8 ) & 0xFF; 00076 BuffAddr[BuffPtr++] = Gps.LatitudeBinary & 0xFF; 00077 BuffAddr[BuffPtr++] = ( Gps.LongitudeBinary >> 16 ) & 0xFF; 00078 BuffAddr[BuffPtr++] = ( Gps.LongitudeBinary >> 8 ) & 0xFF; 00079 BuffAddr[BuffPtr++] = Gps.LongitudeBinary & 0xFF; 00080 BuffAddr[BuffPtr++] = ( altitudeGps >> 8 ) & 0xFF; 00081 BuffAddr[BuffPtr++] = altitudeGps & 0xFF; 00082 } 00083 break; 00084 } 00085 00086 // Appends 1 Byte to TX buffer 00087 case AppPrsr: 00088 { 00089 if( ( BuffPtr + 2 ) <= LORAWAN_APP_DATA_SIZE ) 00090 { 00091 volatile uint8_t stat; 00092 float val; 00093 00094 Mpl3115a2.SetModeBarometer(); 00095 Mpl3115a2.ToggleOneShot( ); 00096 00097 stat = Mpl3115a2.read(STATUS_REG); 00098 while( (stat & 0x04) != 0x04 ) { 00099 wait(0.01); 00100 stat = Mpl3115a2.read(STATUS_REG); 00101 } 00102 00103 val = Mpl3115a2.ReadBarometer()/100.0; 00104 00105 BuffAddr[BuffPtr++] = ( ( uint16_t ) val >> 8 ) & 0xFF; 00106 BuffAddr[BuffPtr++] = ( ( uint16_t ) val ) & 0xFF; 00107 00108 } 00109 break; 00110 } 00111 00112 // Appends 1 Byte to TX buffer 00113 case AppTemp: 00114 { 00115 Mpl3115a2.ReadTemperature( ); 00116 if( ( BuffPtr + 1 ) <= LORAWAN_APP_DATA_SIZE ) 00117 { 00118 BuffAddr[BuffPtr++] = ( int32_t )Mpl3115a2.Temperature; // Signed degrees Celcius in half degree units. So, +/-63 °C 00119 } 00120 break; 00121 } 00122 00123 // Appends 1 Byte to TX buffer 00124 case AppBat: 00125 { 00126 if( ( BuffPtr + 1 ) <= LORAWAN_APP_DATA_SIZE ) 00127 { 00128 #ifdef BAT_VAL_PERCENT 00129 uint16_t value; 00130 value = BoardGetBatteryLevel(); 00131 BuffAddr[BuffPtr++] = ( value * 100 ) >> 8; // Bat level in % 00132 #else 00133 BuffAddr[BuffPtr++] = BoardGetBatteryLevel( ); // Per LoRaWAN spec; 0 = Charging; 1...254 = level, 255 = N/A 00134 #endif 00135 } 00136 break; 00137 } 00138 00139 // Appends incremental values of 1 Byte each to TX buffer until Full 00140 case AppRamp: 00141 { 00142 int32_t i, j; 00143 00144 // Populate Tx Buffer with increasing byte values starting from 0x00, 0x01, 0x02 ... 00145 for( i = BuffPtr, j = 0; i < LORAWAN_APP_DATA_SIZE; i++ ) 00146 { 00147 BuffAddr[i] = j++; 00148 } 00149 BuffPtr = LORAWAN_APP_DATA_SIZE; 00150 break; 00151 } 00152 00153 // Appends 2 Bytes to TX buffer 00154 case AppAccl: 00155 { 00156 uint8_t statusReg; 00157 00158 // Read the PS_STATUS register 00159 statusReg = Mma8451q.read_single( MMA8451_PL_STATUS ); 00160 00161 /* Display Orientation of NAMote on Serial Port */ 00162 SerialAcclMetrDisplay( statusReg ); 00163 00164 // If Orientation of the Mote changed then let Green LED ON 00165 if( ( statusReg & 0x80 ) != 0 ) 00166 { 00167 AppLed = 1; 00168 CtrlLED( Green, LED_ON ); 00169 } 00170 00171 // Read and populate device orientation in Tx Buffer 00172 if( ( BuffPtr + 2 ) <= LORAWAN_APP_DATA_SIZE ) 00173 { 00174 if( statusReg & 0x40 ) 00175 { 00176 if( statusReg & 0x01 ) 00177 { 00178 BuffAddr[BuffPtr++] = 0x66; // horizontal + faceup 00179 } 00180 else 00181 { 00182 BuffAddr[BuffPtr++] = 0x99; // horizontal + facedown 00183 } 00184 00185 BuffAddr[BuffPtr++] = 0; // vertical = false 00186 } 00187 else 00188 { 00189 BuffAddr[BuffPtr++] = 0; // horizontal = false 00190 BuffAddr[BuffPtr++] = 0x11; // vertical = true 00191 } 00192 } 00193 00194 break; 00195 } 00196 00197 case AppAcclSenet: 00198 { 00199 uint8_t statusReg; 00200 00201 // Read the PS_STATUS register 00202 statusReg = Mma8451q.read_single( MMA8451_PL_STATUS ); 00203 00204 /* Display Orientation of NAMote on Serial Port */ 00205 SerialAcclMetrDisplay( statusReg ); 00206 00207 // If Orientation of the Mote changed then populate Upper Nibble of 0th Byte of Tx Buffer 00208 if( ( statusReg & 0x40 ) != 0 ) 00209 { 00210 AppLed = 0; 00211 CtrlLED( Green, LED_OFF ); 00212 BuffAddr[BuffPtr++] = 0; // horizontal 00213 } 00214 else 00215 { 00216 AppLed = 1; 00217 CtrlLED( Green, LED_ON ); 00218 BuffAddr[BuffPtr++] = 10; // vertical 00219 } 00220 00221 break; 00222 } 00223 00224 case AppAcclSensor: 00225 { 00226 uint8_t statusReg; 00227 int8_t regVal; 00228 int16_t axesData; 00229 00230 // Read the PS_STATUS register 00231 statusReg = Mma8451q.read_single( MMA8451_PL_STATUS ); 00232 00233 /* Display Orientation of NAMote on Serial Port */ 00234 SerialAcclMetrDisplay( statusReg ); 00235 00236 // If Orientation of the Mote changed then populate Upper Nibble of 0th Byte of Tx Buffer 00237 if( ( statusReg & 0x80 ) != 0 ) 00238 { 00239 CtrlLED( Green, LED_ON ); 00240 } 00241 else 00242 { 00243 CtrlLED( Green, LED_OFF ); 00244 } 00245 00246 // Read and populate device orientation in Tx Buffer 00247 if( ( BuffPtr + 6 ) <= LORAWAN_APP_DATA_SIZE ) 00248 { 00249 uint8_t addr; 00250 addr = MMA8451_OUT_X_MSB; 00251 00252 // Read X-axis Data 00253 regVal = Mma8451q.read_single( addr++ ); 00254 axesData = regVal << 8; 00255 regVal = Mma8451q.read_single( addr++ ); 00256 axesData |= regVal; 00257 BuffAddr[BuffPtr++] = ( axesData >> 10 ) & 0xFF; 00258 BuffAddr[BuffPtr++] = ( axesData >> 2 ) & 0xFF; 00259 00260 // Read Y-axis Data 00261 regVal = Mma8451q.read_single( addr++ ); 00262 axesData = regVal << 8; 00263 regVal = Mma8451q.read_single( addr++ ); 00264 axesData |= regVal; 00265 BuffAddr[BuffPtr++] = ( axesData >> 10 ) & 0xFF; 00266 BuffAddr[BuffPtr++] = ( axesData >> 2 ) & 0xFF; 00267 00268 // Read Z-axis Data 00269 regVal = Mma8451q.read_single( addr++ ); 00270 axesData = regVal << 8; 00271 regVal = Mma8451q.read_single( addr++ ); 00272 axesData |= regVal; 00273 BuffAddr[BuffPtr++] = ( axesData >> 10 ) & 0xFF; 00274 BuffAddr[BuffPtr++] = ( axesData >> 2 ) & 0xFF; 00275 } 00276 00277 break; 00278 } 00279 00280 case AppPushButton: 00281 { 00282 uint16_t PushButtonCnt; 00283 uint8_t *p = (uint8_t *) &PushButtonCnt; 00284 00285 PushButtonCnt = LoRaMacUplinkStatus.UplinkCounter; 00286 00287 memcpy( &BuffAddr[BuffPtr], p, sizeof(uint16_t) ); 00288 00289 break; 00290 } 00291 00292 default: 00293 { 00294 break; 00295 } 00296 } 00297 printf( "###### ===== Sending data ==== ######\r\n"); 00298 SerialDisplayHex(BuffAddr, BuffPtr); 00299 } 00300 00301 static void OnRedLedTimerEvent( void ) 00302 { 00303 TimerStop( &RedLedTimer.LedTimer ); 00304 00305 if( RedLed == LED_OFF ) 00306 { 00307 RedLed = LED_ON; 00308 } 00309 else 00310 { 00311 RedLed = LED_OFF; 00312 } 00313 } 00314 00315 static void OnYellowLedTimerEvent( void ) 00316 { 00317 TimerStop( &YellowLedTimer.LedTimer ); 00318 00319 if( YellowLed == LED_OFF ) 00320 { 00321 YellowLed = LED_ON; 00322 } 00323 else 00324 { 00325 YellowLed = LED_OFF; 00326 } 00327 } 00328 00329 static void OnGreenLedTimerEvent( void ) 00330 { 00331 TimerStop( &GreenLedTimer.LedTimer ); 00332 00333 if( GreenLed == LED_OFF ) 00334 { 00335 GreenLed = LED_ON; 00336 } 00337 else 00338 { 00339 GreenLed = LED_OFF; 00340 } 00341 } 00342 00343 TimerLed::TimerLed( eLedType led ) 00344 { 00345 switch( led ) 00346 { 00347 case Red: 00348 { 00349 TimerInit( &LedTimer, OnRedLedTimerEvent ); 00350 break; 00351 } 00352 00353 case Yellow: 00354 { 00355 TimerInit( &LedTimer, OnYellowLedTimerEvent ); 00356 break; 00357 } 00358 00359 case Green: 00360 { 00361 TimerInit( &LedTimer, OnGreenLedTimerEvent ); 00362 break; 00363 } 00364 } 00365 00366 } 00367 00368 TimerLed::~TimerLed( ) 00369 { 00370 } 00371 00372 void BlinkLED( eLedType led, uint32_t time ) 00373 { 00374 switch( led ) 00375 { 00376 case Red: 00377 { 00378 TimerSetValue( &RedLedTimer.LedTimer, time ); 00379 TimerStart( &RedLedTimer.LedTimer ); 00380 RedLed = LED_ON; 00381 break; 00382 } 00383 00384 case Yellow: 00385 { 00386 TimerSetValue( &YellowLedTimer.LedTimer, time ); 00387 TimerStart( &YellowLedTimer.LedTimer ); 00388 YellowLed = LED_ON; 00389 break; 00390 } 00391 00392 case Green: 00393 { 00394 TimerSetValue( &GreenLedTimer.LedTimer, time ); 00395 TimerStart( &GreenLedTimer.LedTimer ); 00396 GreenLed = LED_ON; 00397 break; 00398 } 00399 } 00400 } 00401 00402 void ToggleLED( eLedType led ) 00403 { 00404 switch( led ) 00405 { 00406 case Red: 00407 { 00408 if( RedLed == LED_OFF ) 00409 { 00410 RedLed = LED_ON; 00411 } 00412 else 00413 { 00414 RedLed = LED_OFF; 00415 } 00416 break; 00417 } 00418 00419 case Yellow: 00420 { 00421 if( YellowLed == LED_OFF ) 00422 { 00423 YellowLed = LED_ON; 00424 } 00425 else 00426 { 00427 YellowLed = LED_OFF; 00428 } 00429 break; 00430 } 00431 00432 case Green: 00433 { 00434 if( GreenLed == LED_OFF ) 00435 { 00436 GreenLed = LED_ON; 00437 } 00438 else 00439 { 00440 GreenLed = LED_OFF; 00441 } 00442 break; 00443 } 00444 } 00445 } 00446 00447 void CtrlLED( eLedType led, uint8_t state ) 00448 { 00449 switch( led ) 00450 { 00451 case Red: 00452 { 00453 RedLed = state; 00454 break; 00455 } 00456 00457 case Yellow: 00458 { 00459 YellowLed = state; 00460 break; 00461 } 00462 00463 case Green: 00464 { 00465 GreenLed = state; 00466 break; 00467 } 00468 00469 case Usr: 00470 { 00471 if( state ) 00472 { 00473 UsrLed = LED_ON; 00474 } 00475 else 00476 { 00477 UsrLed = LED_OFF; 00478 } 00479 break; 00480 } 00481 } 00482 } 00483 00484 void CheckOrientation( void ) 00485 { 00486 uint8_t statusReg; 00487 00488 // Read the PS_STATUS register 00489 statusReg = Mma8451q.read_single( MMA8451_PL_STATUS ); 00490 00491 // If Orientation of the Mote changed then populate Upper Nibble of 0th Byte of Tx Buffer 00492 if( ( statusReg & 0x40 ) != 0 ) 00493 { 00494 CtrlLED( Green, LED_OFF ); 00495 VerticalStatus = false; // horizontal 00496 } 00497 else 00498 { 00499 CtrlLED( Green, LED_ON ); 00500 VerticalStatus = true; // vertical 00501 } 00502 }
Generated on Thu Jul 28 2022 06:45:12 by
1.7.2
