Nagaraj Krishnamurthy / LoRaWAN-NAMote72-Application-Demo_IoTium

Dependencies:   LoRaWAN-lib SX1272Lib lib_gps lib_mma8451q lib_mpl3115a2 mbed

Fork of LoRaWAN-NAMote72-Application-Demo_Multitech by Nagaraj Krishnamurthy

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers LoRaApp.cpp Source File

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 }