Fork from LoRa Alliance program. available here: https://developer.mbed.org/users/Alliance/code/LoRaWAN/
Dependencies: LoRaMacLib SX1276Lib mbed Chainable_RGB_LED DigitDisplay
Fork of LoRaWAN by
main.cpp
- Committer:
- Alliance
- Date:
- 2015-11-24
- Revision:
- 12:d7ac3e3720a5
- Parent:
- 11:b05c281295a3
- Child:
- 13:6cfbb6d1f491
File content as of revision 12:d7ac3e3720a5:
/* / _____) _ | | ( (____ _____ ____ _| |_ _____ ____| |__ \____ \| ___ | (_ _) ___ |/ ___) _ \ _____) ) ____| | | || |_| ____( (___| | | | (______/|_____)_|_|_| \__)_____)\____)_| |_| (C)2015 Semtech Description: LoRaMac classA device implementation License: Revised BSD License, see LICENSE.TXT file include in the project Maintainer: Miguel Luis and Gregory Cristian */ #include "mbed.h" #include "board.h" #include "LoRaMac.h" #include "utilities.h" #include "DigitDisplay.h" #include "ChainableLED.h" /*! * When set to 1 the application uses the Over-the-Air activation procedure * When set to 0 the application uses the Personalization activation procedure */ #define OVER_THE_AIR_ACTIVATION 0 /*! * Mote device IEEE EUI */ static uint8_t DevEui[] = { 0x73, 0x65, 0x6d, 0x74, 0x65, 0x63, 0xef, 0x2c /// <<< Change here }; /*! * Device address */ static uint32_t DevAddr = 0x6563ef2c; /// <<< Change here /*! * AES encryption/decryption cipher network session key */ static uint8_t NwkSKey[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /// <<< Change here 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xef, 0x2c }; /*! * AES encryption/decryption cipher application session key */ static uint8_t AppSKey[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /// <<< Change here 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xef, 0x2c }; /*! * Indicates if the MAC layer has already joined a network. */ static bool IsNetworkJoined = false; /*! * Defines the application data transmission duty cycle */ #define APP_TX_DUTYCYCLE 50000000 // 50 [s] value in us (minimum 10s) #define APP_TX_DUTYCYCLE_RND 10000000 // 10 [s] value in us (minimum 3s) /*! * User application data buffer size */ #define APP_DATA_SIZE 5 /*! * User application data */ static uint8_t AppData[APP_DATA_SIZE]; /*! * Defines the application data transmission duty cycle */ static uint32_t TxDutyCycleTime; Ticker TxNextPacketTimer; #if( OVER_THE_AIR_ACTIVATION != 0 ) /*! * Defines the join request timer */ Ticker JoinReqTimer; #endif /*! * Indicates if a new packet can be sent */ static bool TxNextPacket = true; static bool TxDone = false; static uint8_t AppPort = 3; static uint8_t AppDataSize = APP_DATA_SIZE; static LoRaMacEvent_t LoRaMacEvents; static float LightValue = 0.0; static uint8_t LightMode = 0; // 0:automatic, 1:manual Ticker Led1Timer; Ticker Led2Timer; Ticker BuzTimer; #define NUM_LED 3 AnalogIn LightSens( A1 ); ChainableLED color_led(D6, D7, NUM_LED); DigitDisplay display(D8, D9); DigitalOut buzzer(A2); static void OnBuzTimerEvent( void ) { buzzer = 0; BuzTimer.detach( ); } /*! * */ static void PrepareTxFrame( uint8_t port ) { uint32_t tempValue = (uint32_t)(LightValue*1000000.0); debug( "[Tx] LightValue=%d 0x%x\n\r" , tempValue, tempValue); AppData[0] = LightMode; AppData[1] = ((tempValue&0xFF000000)>>24)&0xFF; AppData[2] = ((tempValue&0x00FF0000)>>16)&0xFF; AppData[3] = ((tempValue&0x0000FF00)>>8)&0xFF; AppData[4] = (tempValue&0x000000FF); } static void ProcessRxFrame( LoRaMacEventFlags_t *flags, LoRaMacEventInfo_t *info ) { debug( "[Rx] Port=%d\n\r" , info->RxPort); switch( info->RxPort ) // Check Rx port number { case 10: display.write( 0, info->RxBuffer[0] ); display.write( 1, info->RxBuffer[1] ); display.write( 2, info->RxBuffer[2] ); display.write( 3, info->RxBuffer[3] ); break; case 20: LightMode = info->RxBuffer[0]; debug( "[Rx] LightMode=%x - R G B= 0x%x 0x%x 0x%x\n\r" , LightMode, info->RxBuffer[1], info->RxBuffer[2], info->RxBuffer[3]); if( LightMode ) { color_led.setColorRGB(0, info->RxBuffer[1], info->RxBuffer[2], info->RxBuffer[3] ); } break; case 30: BuzTimer.attach_us( &OnBuzTimerEvent, 500000 ); buzzer = 1; break; default: break; } } static bool SendFrame( void ) { uint8_t sendFrameStatus = 0; sendFrameStatus = LoRaMacSendFrame( AppPort, AppData, AppDataSize ); // sendFrameStatus = LoRaMacSendConfirmedFrame( AppPort, AppData, AppDataSize, 8 ); switch( sendFrameStatus ) { case 5: // NO_FREE_CHANNEL // Try again later return true; default: return false; } } #if( OVER_THE_AIR_ACTIVATION != 0 ) /*! * \brief Function executed on JoinReq Timeout event */ static void OnJoinReqTimerEvent( void ) { TxNextPacket = true; JoinReqTimer.detach( ); } #endif /*! * \brief Function executed on TxNextPacket Timeout event */ static void OnTxNextPacketTimerEvent( void ) { TxNextPacket = true; TxNextPacketTimer.detach( ); } /*! * \brief Function to be executed on MAC layer event */ static void OnMacEvent( LoRaMacEventFlags_t *flags, LoRaMacEventInfo_t *info ) { if( flags->Bits.JoinAccept == 1 ) { #if( OVER_THE_AIR_ACTIVATION != 0 ) JoinReqTimer.detach( ); #endif IsNetworkJoined = true; } if( flags->Bits.Tx == 1 ) { } if( flags->Bits.Rx == 1 ) { if( flags->Bits.RxData == true ) { ProcessRxFrame( flags, info ); } } // Schedule a new transmission TxDone = true; } /** * Main application entry point. */ int main( void ) { #if( OVER_THE_AIR_ACTIVATION != 0 ) uint8_t sendFrameStatus = 0; #endif bool trySendingFrameAgain = false; float tempLightValue = 0; LightMode = 0; // 0: manual, 1: automatic buzzer = 0; // 0: OFF, 1: ON debug( "\n\n\r LoRaWAN Class A Demo code \n\n\r" ); BoardInitMcu( ); BoardInitPeriph( ); // Initialize LoRaMac device unique ID // BoardGetUniqueId( DevEui ); LoRaMacEvents.MacEvent = OnMacEvent; LoRaMacInit( &LoRaMacEvents ); IsNetworkJoined = false; #if( OVER_THE_AIR_ACTIVATION == 0 ) // Random seed initialization srand( RAND_SEED ); // Choose a random device address // NwkID = 0 // NwkAddr rand [0, 33554431] if( ( DevAddr == 0 ) || ( DevAddr == 0xFFFFFFFF ) ) { // Generate random DevAddr if it does not exist debug("Generate random DevAddr\n\r"); DevAddr = randr( 0, 0x01FFFFFF ); } debug( "- DevAddr = 0x%x\n\r" , DevAddr); LoRaMacInitNwkIds( 0x000000, DevAddr, NwkSKey, AppSKey ); IsNetworkJoined = true; #endif TxNextPacket = true; LoRaMacSetAdrOn( false ); LoRaMacSetDutyCycleOn( false ); while( 1 ) { while( IsNetworkJoined == false ) { #if( OVER_THE_AIR_ACTIVATION != 0 ) if( TxNextPacket == true ) { TxNextPacket = false; sendFrameStatus = LoRaMacJoinReq( DevEui, AppEui, AppKey ); debug("Req Sent\n\r"); switch( sendFrameStatus ) { case 1: // BUSY break; case 0: // OK case 2: // NO_NETWORK_JOINED case 3: // LENGTH_PORT_ERROR case 4: // MAC_CMD_ERROR case 6: // DEVICE_OFF default: // Relaunch timer for next trial JoinReqTimer.attach_us( &OnJoinReqTimerEvent, OVER_THE_AIR_ACTIVATION_DUTYCYCLE ); break; } } // TimerLowPowerHandler( ); #endif } if( TxDone == true ) { TxDone = false; debug( "TxDone \n\n\r" ); // Schedule next packet transmission TxDutyCycleTime = APP_TX_DUTYCYCLE + randr( -APP_TX_DUTYCYCLE_RND, APP_TX_DUTYCYCLE_RND ); TxNextPacketTimer.attach_us( &OnTxNextPacketTimerEvent, TxDutyCycleTime ); } if( trySendingFrameAgain == true ) { trySendingFrameAgain = SendFrame( ); } if( TxNextPacket == true ) { TxNextPacketTimer.detach( ); TxNextPacket = false; PrepareTxFrame( AppPort ); trySendingFrameAgain = SendFrame( ); } // Read light sensor tempLightValue = LightSens.read( ) * 1.65; LightValue = ( 1 - tempLightValue ); // Set automatic RGB from light sensor if( LightMode == 0 ) { color_led.setColorRGB( 0, ( uint8_t )( 255 * LightValue ), ( uint8_t )( 255 * LightValue ), ( uint8_t )( 255 * LightValue ) ); } // TimerLowPowerHandler( ); } }