Demonstration of Class-A LoRaWAN device using NAMote-72
Dependencies: LoRaWAN-lib mbed lib_mpl3115a2 lib_mma8451q lib_gps SX1272Lib
Dependents: LoRaWAN-NAMote72-BVS-confirmed-tester-0-7v1_copy
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 memcpy( BuffAddr + BuffPtr, pData, len ); 00050 BuffPtr += len; 00051 } 00052 00053 void Application::ApplicationPtrPos( uint8_t ptrPos ) 00054 { 00055 BuffPtr = ptrPos; 00056 } 00057 00058 void Application::ApplicationCall( eAppType App ) 00059 { 00060 switch( App ) 00061 { 00062 // Appends 8 Bytes (3 bytes longitude, 3 bytes latitude, 2 bytes altitude) to TX buffer 00063 case AppGps: 00064 { 00065 Gps.service( ); 00066 00067 uint16_t altitudeGps = atoi( Gps.NmeaGpsData.NmeaAltitude ); 00068 00069 if( ( BuffPtr + 8 ) <= LORAWAN_APP_DATA_SIZE ) 00070 { 00071 BuffAddr[BuffPtr++] = ( Gps.LatitudeBinary >> 16 ) & 0xFF; 00072 BuffAddr[BuffPtr++] = ( Gps.LatitudeBinary >> 8 ) & 0xFF; 00073 BuffAddr[BuffPtr++] = Gps.LatitudeBinary & 0xFF; 00074 BuffAddr[BuffPtr++] = ( Gps.LongitudeBinary >> 16 ) & 0xFF; 00075 BuffAddr[BuffPtr++] = ( Gps.LongitudeBinary >> 8 ) & 0xFF; 00076 BuffAddr[BuffPtr++] = Gps.LongitudeBinary & 0xFF; 00077 BuffAddr[BuffPtr++] = ( altitudeGps >> 8 ) & 0xFF; 00078 BuffAddr[BuffPtr++] = altitudeGps & 0xFF; 00079 } 00080 break; 00081 } 00082 00083 // Appends 1 Byte to TX buffer 00084 case AppTemp: 00085 { 00086 Mpl3115a2.ReadTemperature( ); 00087 if( ( BuffPtr + 1 ) <= LORAWAN_APP_DATA_SIZE ) 00088 { 00089 BuffAddr[BuffPtr++] = ( int32_t )Mpl3115a2.Temperature; // Signed degrees Celcius in half degree units. So, +/-63 °C 00090 } 00091 break; 00092 } 00093 00094 // Appends 1 Byte to TX buffer 00095 case AppBat: 00096 { 00097 if( ( BuffPtr + 1 ) <= LORAWAN_APP_DATA_SIZE ) 00098 { 00099 BuffAddr[BuffPtr++] = BoardGetBatteryLevel( ); // Per LoRaWAN spec; 0 = Charging; 1...254 = level, 255 = N/A 00100 } 00101 break; 00102 } 00103 00104 // Appends incremental values of 1 Byte each to TX buffer until Full 00105 case AppRamp: 00106 { 00107 int32_t i, j; 00108 00109 // Populate Tx Buffer with increasing byte values starting from 0x00, 0x01, 0x02 ... 00110 for( i = BuffPtr, j = 0; i < LORAWAN_APP_DATA_SIZE; i++ ) 00111 { 00112 BuffAddr[i] = j++; 00113 } 00114 BuffPtr = LORAWAN_APP_DATA_SIZE; 00115 break; 00116 } 00117 00118 // Appends 2 Bytes to TX buffer 00119 case AppAccl: 00120 { 00121 uint8_t statusReg; 00122 00123 // Read the PS_STATUS register 00124 statusReg = Mma8451q.read_single( MMA8451_PL_STATUS ); 00125 00126 /* Display Orientation of NAMote on Serial Port */ 00127 //SerialAcclMetrDisplay( statusReg ); 00128 00129 // If Orientation of the Mote changed then let Green LED ON 00130 if( ( statusReg & 0x80 ) != 0 ) 00131 { 00132 AppLed = 1; 00133 CtrlLED( Green, LED_ON ); 00134 } 00135 00136 // Read and populate device orientation in Tx Buffer 00137 if( ( BuffPtr + 2 ) <= LORAWAN_APP_DATA_SIZE ) 00138 { 00139 if( statusReg & 0x40 ) 00140 { 00141 if( statusReg & 0x01 ) 00142 { 00143 BuffAddr[BuffPtr++] = 0x66; // horizontal + faceup 00144 } 00145 else 00146 { 00147 BuffAddr[BuffPtr++] = 0x99; // horizontal + facedown 00148 } 00149 00150 BuffAddr[BuffPtr++] = 0; // vertical = false 00151 } 00152 else 00153 { 00154 BuffAddr[BuffPtr++] = 0; // horizontal = false 00155 BuffAddr[BuffPtr++] = 0x11; // vertical = true 00156 } 00157 } 00158 00159 break; 00160 } 00161 00162 case AppAcclSenet: 00163 { 00164 uint8_t statusReg; 00165 00166 // Read the PS_STATUS register 00167 statusReg = Mma8451q.read_single( MMA8451_PL_STATUS ); 00168 00169 /* Display Orientation of NAMote on Serial Port */ 00170 SerialAcclMetrDisplay( statusReg ); 00171 00172 // If Orientation of the Mote changed then populate Upper Nibble of 0th Byte of Tx Buffer 00173 if( ( statusReg & 0x40 ) != 0 ) 00174 { 00175 AppLed = 0; 00176 CtrlLED( Green, LED_OFF ); 00177 BuffAddr[BuffPtr++] = 0; // horizontal 00178 } 00179 else 00180 { 00181 AppLed = 1; 00182 CtrlLED( Green, LED_ON ); 00183 BuffAddr[BuffPtr++] = 10; // vertical 00184 } 00185 break; 00186 } 00187 00188 case AppPushButton: 00189 { 00190 uint16_t PushButtonCnt; 00191 uint8_t *p = ( uint8_t * )&PushButtonCnt; 00192 00193 PushButtonCnt = LoRaMacUplinkStatus.UplinkCounter; 00194 00195 memcpy( &BuffAddr[BuffPtr], p, sizeof( uint16_t ) ); 00196 break; 00197 } 00198 00199 default: 00200 { 00201 break; 00202 } 00203 } 00204 } 00205 00206 static void OnRedLedTimerEvent( void ) 00207 { 00208 TimerStop( &RedLedTimer.LedTimer ); 00209 00210 if( RedLed == LED_OFF ) 00211 { 00212 RedLed = LED_ON; 00213 } 00214 else 00215 { 00216 RedLed = LED_OFF; 00217 } 00218 } 00219 00220 static void OnYellowLedTimerEvent( void ) 00221 { 00222 TimerStop( &YellowLedTimer.LedTimer ); 00223 00224 if( YellowLed == LED_OFF ) 00225 { 00226 YellowLed = LED_ON; 00227 } 00228 else 00229 { 00230 YellowLed = LED_OFF; 00231 } 00232 } 00233 00234 static void OnGreenLedTimerEvent( void ) 00235 { 00236 TimerStop( &GreenLedTimer.LedTimer ); 00237 00238 if( GreenLed == LED_OFF ) 00239 { 00240 GreenLed = LED_ON; 00241 } 00242 else 00243 { 00244 GreenLed = LED_OFF; 00245 } 00246 } 00247 00248 TimerLed::TimerLed( eLedType led ) 00249 { 00250 switch( led ) 00251 { 00252 case Red: 00253 { 00254 TimerInit( &LedTimer, OnRedLedTimerEvent ); 00255 break; 00256 } 00257 00258 case Yellow: 00259 { 00260 TimerInit( &LedTimer, OnYellowLedTimerEvent ); 00261 break; 00262 } 00263 00264 case Green: 00265 { 00266 TimerInit( &LedTimer, OnGreenLedTimerEvent ); 00267 break; 00268 } 00269 default: 00270 { 00271 break; 00272 } 00273 } 00274 00275 } 00276 00277 TimerLed::~TimerLed( ) 00278 { 00279 } 00280 00281 void BlinkLED( eLedType led, uint32_t time ) 00282 { 00283 switch( led ) 00284 { 00285 case Red: 00286 { 00287 TimerSetValue( &RedLedTimer.LedTimer, time ); 00288 TimerStart( &RedLedTimer.LedTimer ); 00289 RedLed = LED_ON; 00290 break; 00291 } 00292 00293 case Yellow: 00294 { 00295 TimerSetValue( &YellowLedTimer.LedTimer, time ); 00296 TimerStart( &YellowLedTimer.LedTimer ); 00297 YellowLed = LED_ON; 00298 break; 00299 } 00300 00301 case Green: 00302 { 00303 TimerSetValue( &GreenLedTimer.LedTimer, time ); 00304 TimerStart( &GreenLedTimer.LedTimer ); 00305 GreenLed = LED_ON; 00306 break; 00307 } 00308 default: 00309 { 00310 break; 00311 } 00312 } 00313 } 00314 00315 void ToggleLED( eLedType led ) 00316 { 00317 switch( led ) 00318 { 00319 case Red: 00320 { 00321 if( RedLed == LED_OFF ) 00322 { 00323 RedLed = LED_ON; 00324 } 00325 else 00326 { 00327 RedLed = LED_OFF; 00328 } 00329 break; 00330 } 00331 00332 case Yellow: 00333 { 00334 if( YellowLed == LED_OFF ) 00335 { 00336 YellowLed = LED_ON; 00337 } 00338 else 00339 { 00340 YellowLed = LED_OFF; 00341 } 00342 break; 00343 } 00344 00345 case Green: 00346 { 00347 if( GreenLed == LED_OFF ) 00348 { 00349 GreenLed = LED_ON; 00350 } 00351 else 00352 { 00353 GreenLed = LED_OFF; 00354 } 00355 break; 00356 } 00357 default: 00358 { 00359 break; 00360 } 00361 } 00362 } 00363 00364 void CtrlLED( eLedType led, uint8_t state ) 00365 { 00366 switch( led ) 00367 { 00368 case Red: 00369 { 00370 RedLed = state; 00371 break; 00372 } 00373 00374 case Yellow: 00375 { 00376 YellowLed = state; 00377 break; 00378 } 00379 00380 case Green: 00381 { 00382 GreenLed = state; 00383 break; 00384 } 00385 00386 case Usr: 00387 { 00388 if( state ) 00389 { 00390 UsrLed = LED_ON; 00391 } 00392 else 00393 { 00394 UsrLed = LED_OFF; 00395 } 00396 break; 00397 } 00398 } 00399 } 00400 00401 void CheckOrientation( void ) 00402 { 00403 uint8_t statusReg; 00404 00405 // Read the PS_STATUS register 00406 statusReg = Mma8451q.read_single( MMA8451_PL_STATUS ); 00407 00408 // If Orientation of the Mote changed then populate Upper Nibble of 0th Byte of Tx Buffer 00409 if( ( statusReg & 0x40 ) != 0 ) 00410 { 00411 CtrlLED( Green, LED_OFF ); 00412 VerticalStatus = false; // horizontal 00413 } 00414 else 00415 { 00416 CtrlLED( Green, LED_ON ); 00417 VerticalStatus = true; // vertical 00418 } 00419 }
Generated on Fri Jul 15 2022 22:53:35 by
![doxygen](doxygen.png)