LoRa on Multitech with Semtech mote
Dependencies: LoRaWAN-lib SX1272Lib lib_gps lib_mma8451q lib_mpl3115a2 mbed
Fork of LoRaWAN-NAMote72-Application-Demo_Multitech by
app/LoRaApp.cpp
- Committer:
- ubhat
- Date:
- 2016-08-30
- Revision:
- 14:f687ec277e1b
- Parent:
- 13:6b6f4be13633
- Child:
- 15:39a23f5affd1
File content as of revision 14:f687ec277e1b:
/* / _____) _ | | ( (____ _____ ____ _| |_ _____ ____| |__ \____ \| ___ | (_ _) ___ |/ ___) _ \ _____) ) ____| | | || |_| ____( (___| | | | (______/|_____)_|_|_| \__)_____)\____)_| |_| (C)2015 Semtech Description: User-defined applications such as GPS, Temp, Accelerometer, LED indications etc. Event based actions such as LED blink on Tx, LED toggle on downlink etc License: Revised BSD License, see LICENSE.TXT file include in the project Maintainer: Uttam Bhat */ #include "LoRaApp.h" bool VerticalStatus = false; /*! * Red LED timer event */ TimerLed RedLedTimer( Red ); /*! * Yellow LED timer event */ TimerLed YellowLedTimer( Yellow ); /*! * Green LED timer event */ TimerLed GreenLedTimer( Green ); Application::Application( uint8_t * memptr ) { BuffAddr = memptr; memset( BuffAddr, 0, LORAWAN_APP_DATA_MAX_SIZE ); BuffPtr = 0; } Application::~Application( ) { } void Application::ApplicationAppendData( uint8_t *pData, uint8_t len ) { memcpy( BuffAddr + BuffPtr, pData, len ); BuffPtr += len; } void Application::ApplicationPtrPos( uint8_t ptrPos ) { BuffPtr = ptrPos; } void Application::ApplicationCall( eAppType App ) { switch( App ) { // Appends 8 Bytes (3 bytes longitude, 3 bytes latitude, 2 bytes altitude) to TX buffer case AppGps: { Gps.service( ); uint16_t altitudeGps = atoi( Gps.NmeaGpsData.NmeaAltitude ); if( ( BuffPtr + 8 ) <= LORAWAN_APP_DATA_SIZE ) { BuffAddr[BuffPtr++] = ( Gps.LatitudeBinary >> 16 ) & 0xFF; BuffAddr[BuffPtr++] = ( Gps.LatitudeBinary >> 8 ) & 0xFF; BuffAddr[BuffPtr++] = Gps.LatitudeBinary & 0xFF; BuffAddr[BuffPtr++] = ( Gps.LongitudeBinary >> 16 ) & 0xFF; BuffAddr[BuffPtr++] = ( Gps.LongitudeBinary >> 8 ) & 0xFF; BuffAddr[BuffPtr++] = Gps.LongitudeBinary & 0xFF; BuffAddr[BuffPtr++] = ( altitudeGps >> 8 ) & 0xFF; BuffAddr[BuffPtr++] = altitudeGps & 0xFF; } break; } // Appends 1 Byte to TX buffer case AppPrsr: { if( ( BuffPtr + 2 ) <= LORAWAN_APP_DATA_SIZE ) { volatile uint8_t stat; float val; Mpl3115a2.SetModeBarometer(); Mpl3115a2.ToggleOneShot( ); stat = Mpl3115a2.read(STATUS_REG); while( (stat & 0x04) != 0x04 ) { wait(0.01); stat = Mpl3115a2.read(STATUS_REG); } val = Mpl3115a2.ReadBarometer()/100.0; BuffAddr[BuffPtr++] = ( ( uint16_t ) val >> 8 ) & 0xFF; BuffAddr[BuffPtr++] = ( ( uint16_t ) val ) & 0xFF; } break; } // Appends 1 Byte to TX buffer case AppTemp: { Mpl3115a2.ReadTemperature( ); if( ( BuffPtr + 1 ) <= LORAWAN_APP_DATA_SIZE ) { BuffAddr[BuffPtr++] = ( int32_t )Mpl3115a2.Temperature; // Signed degrees Celcius in half degree units. So, +/-63 °C } break; } // Appends 1 Byte to TX buffer case AppBat: { if( ( BuffPtr + 1 ) <= LORAWAN_APP_DATA_SIZE ) { #ifdef BAT_VAL_PERCENT uint16_t value; value = BoardGetBatteryLevel(); BuffAddr[BuffPtr++] = ( value * 100 ) >> 8; // Bat level in % #else BuffAddr[BuffPtr++] = BoardGetBatteryLevel( ); // Per LoRaWAN spec; 0 = Charging; 1...254 = level, 255 = N/A #endif } break; } // Appends incremental values of 1 Byte each to TX buffer until Full case AppRamp: { int32_t i, j; // Populate Tx Buffer with increasing byte values starting from 0x00, 0x01, 0x02 ... for( i = BuffPtr, j = 0; i < LORAWAN_APP_DATA_SIZE; i++ ) { BuffAddr[i] = j++; } BuffPtr = LORAWAN_APP_DATA_SIZE; break; } // Appends 2 Bytes to TX buffer case AppAccl: { uint8_t statusReg; // Read the PS_STATUS register statusReg = Mma8451q.read_single( MMA8451_PL_STATUS ); /* Display Orientation of NAMote on Serial Port */ SerialAcclMetrDisplay( statusReg ); // If Orientation of the Mote changed then let Green LED ON if( ( statusReg & 0x80 ) != 0 ) { AppLed = 1; CtrlLED( Green, LED_ON ); } // Read and populate device orientation in Tx Buffer if( ( BuffPtr + 2 ) <= LORAWAN_APP_DATA_SIZE ) { if( statusReg & 0x40 ) { if( statusReg & 0x01 ) { BuffAddr[BuffPtr++] = 0x66; // horizontal + faceup } else { BuffAddr[BuffPtr++] = 0x99; // horizontal + facedown } BuffAddr[BuffPtr++] = 0; // vertical = false } else { BuffAddr[BuffPtr++] = 0; // horizontal = false BuffAddr[BuffPtr++] = 0x11; // vertical = true } } break; } case AppAcclSenet: { uint8_t statusReg; // Read the PS_STATUS register statusReg = Mma8451q.read_single( MMA8451_PL_STATUS ); /* Display Orientation of NAMote on Serial Port */ SerialAcclMetrDisplay( statusReg ); // If Orientation of the Mote changed then populate Upper Nibble of 0th Byte of Tx Buffer if( ( statusReg & 0x40 ) != 0 ) { AppLed = 0; CtrlLED( Green, LED_OFF ); BuffAddr[BuffPtr++] = 0; // horizontal } else { AppLed = 1; CtrlLED( Green, LED_ON ); BuffAddr[BuffPtr++] = 10; // vertical } break; } case AppAcclSensor: { uint8_t statusReg; int8_t regVal; int16_t axesData; // Read the PS_STATUS register statusReg = Mma8451q.read_single( MMA8451_PL_STATUS ); /* Display Orientation of NAMote on Serial Port */ SerialAcclMetrDisplay( statusReg ); // If Orientation of the Mote changed then populate Upper Nibble of 0th Byte of Tx Buffer if( ( statusReg & 0x80 ) != 0 ) { CtrlLED( Green, LED_ON ); } else { CtrlLED( Green, LED_OFF ); } // Read and populate device orientation in Tx Buffer if( ( BuffPtr + 6 ) <= LORAWAN_APP_DATA_SIZE ) { uint8_t addr; addr = MMA8451_OUT_X_MSB; // Read X-axis Data regVal = Mma8451q.read_single( addr++ ); axesData = regVal << 8; regVal = Mma8451q.read_single( addr++ ); axesData |= regVal; BuffAddr[BuffPtr++] = ( axesData >> 10 ) & 0xFF; BuffAddr[BuffPtr++] = ( axesData >> 2 ) & 0xFF; // Read Y-axis Data regVal = Mma8451q.read_single( addr++ ); axesData = regVal << 8; regVal = Mma8451q.read_single( addr++ ); axesData |= regVal; BuffAddr[BuffPtr++] = ( axesData >> 10 ) & 0xFF; BuffAddr[BuffPtr++] = ( axesData >> 2 ) & 0xFF; // Read Z-axis Data regVal = Mma8451q.read_single( addr++ ); axesData = regVal << 8; regVal = Mma8451q.read_single( addr++ ); axesData |= regVal; BuffAddr[BuffPtr++] = ( axesData >> 10 ) & 0xFF; BuffAddr[BuffPtr++] = ( axesData >> 2 ) & 0xFF; } break; } case AppPushButton: { uint16_t PushButtonCnt; uint8_t *p = (uint8_t *) &PushButtonCnt; PushButtonCnt = LoRaMacUplinkStatus.UplinkCounter; memcpy( &BuffAddr[BuffPtr], p, sizeof(uint16_t) ); break; } default: { break; } } } static void OnRedLedTimerEvent( void ) { TimerStop( &RedLedTimer.LedTimer ); if( RedLed == LED_OFF ) { RedLed = LED_ON; } else { RedLed = LED_OFF; } } static void OnYellowLedTimerEvent( void ) { TimerStop( &YellowLedTimer.LedTimer ); if( YellowLed == LED_OFF ) { YellowLed = LED_ON; } else { YellowLed = LED_OFF; } } static void OnGreenLedTimerEvent( void ) { TimerStop( &GreenLedTimer.LedTimer ); if( GreenLed == LED_OFF ) { GreenLed = LED_ON; } else { GreenLed = LED_OFF; } } TimerLed::TimerLed( eLedType led ) { switch( led ) { case Red: { TimerInit( &LedTimer, OnRedLedTimerEvent ); break; } case Yellow: { TimerInit( &LedTimer, OnYellowLedTimerEvent ); break; } case Green: { TimerInit( &LedTimer, OnGreenLedTimerEvent ); break; } } } TimerLed::~TimerLed( ) { } void BlinkLED( eLedType led, uint32_t time ) { switch( led ) { case Red: { TimerSetValue( &RedLedTimer.LedTimer, time ); TimerStart( &RedLedTimer.LedTimer ); RedLed = LED_ON; break; } case Yellow: { TimerSetValue( &YellowLedTimer.LedTimer, time ); TimerStart( &YellowLedTimer.LedTimer ); YellowLed = LED_ON; break; } case Green: { TimerSetValue( &GreenLedTimer.LedTimer, time ); TimerStart( &GreenLedTimer.LedTimer ); GreenLed = LED_ON; break; } } } void ToggleLED( eLedType led ) { switch( led ) { case Red: { if( RedLed == LED_OFF ) { RedLed = LED_ON; } else { RedLed = LED_OFF; } break; } case Yellow: { if( YellowLed == LED_OFF ) { YellowLed = LED_ON; } else { YellowLed = LED_OFF; } break; } case Green: { if( GreenLed == LED_OFF ) { GreenLed = LED_ON; } else { GreenLed = LED_OFF; } break; } } } void CtrlLED( eLedType led, uint8_t state ) { switch( led ) { case Red: { RedLed = state; break; } case Yellow: { YellowLed = state; break; } case Green: { GreenLed = state; break; } case Usr: { if( state ) { UsrLed = LED_ON; } else { UsrLed = LED_OFF; } break; } } } void CheckOrientation( void ) { uint8_t statusReg; // Read the PS_STATUS register statusReg = Mma8451q.read_single( MMA8451_PL_STATUS ); // If Orientation of the Mote changed then populate Upper Nibble of 0th Byte of Tx Buffer if( ( statusReg & 0x40 ) != 0 ) { CtrlLED( Green, LED_OFF ); VerticalStatus = false; // horizontal } else { CtrlLED( Green, LED_ON ); VerticalStatus = true; // vertical } }