Node code for sx1272 LoRa transciever

Dependencies:   mbed BMP085 BufferedSerial DHT Sds021 Chainable_RGB_LED DigitDisplay LoRaWAN-lib SX1272Lib

Fork of LoRaWAN-demo-72-bootcamp by Semtech

Revision:
9:16106008960b
Parent:
7:ceb4063e6863
--- a/app/main.cpp	Sat Jan 07 08:52:00 2017 +0000
+++ b/app/main.cpp	Mon Jan 30 21:49:58 2017 +0000
@@ -22,16 +22,20 @@
 #include "DigitDisplay.h"
 #include "ChainableLED.h"
 
+Serial pc(USBTX, USBRX, 115200);
+
 /*!
  * Defines the application data transmission duty cycle. 5s, value in [us].
  */
-#define APP_TX_DUTYCYCLE                            5000000
+//#define APP_TX_DUTYCYCLE                            5000000
+#define APP_TX_DUTYCYCLE                              60000000
 
 /*!
  * Defines a random delay for application data transmission duty cycle. 1s,
  * value in [us].
  */
-#define APP_TX_DUTYCYCLE_RND                        1000000
+//#define APP_TX_DUTYCYCLE_RND                        1000000
+#define APP_TX_DUTYCYCLE_RND                        10000000
 
 /*!
  * Default datarate
@@ -63,7 +67,7 @@
 
 #define USE_SEMTECH_DEFAULT_CHANNEL_LINEUP          1
 
-#if( USE_SEMTECH_DEFAULT_CHANNEL_LINEUP == 1 ) 
+#if( USE_SEMTECH_DEFAULT_CHANNEL_LINEUP == 1 )
 
 #define LC4                { 867100000, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 }
 #define LC5                { 867300000, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 }
@@ -173,8 +177,8 @@
 static float LightValue = 0.0;
 
 /*!
- * Control the 3-color LED 
- * 0: automatic (LED goes brigther as the light decrease, 
+ * Control the 3-color LED
+ * 0: automatic (LED goes brigther as the light decrease,
  * 1: manual (The LED is controlled by the user)
  */
 static uint8_t LightMode = 0;  // 0: automatic, 1: manual
@@ -199,7 +203,7 @@
 /*!
  * Constructor for Light Sensor
  */
-AnalogIn LightSens( A1 ); 
+AnalogIn LightSens( A1 );
 
 /*!
  * Constructor for 4 Digit 7 semgent display
@@ -209,20 +213,18 @@
 /*!
  * Device states
  */
-static enum eDevicState
-{
+static enum eDevicState {
     DEVICE_STATE_INIT,
     DEVICE_STATE_JOIN,
     DEVICE_STATE_SEND,
     DEVICE_STATE_CYCLE,
     DEVICE_STATE_SLEEP
-}DeviceState;
+} DeviceState;
 
 /*!
  * LoRaWAN compliance tests support data
  */
-struct ComplianceTest_s
-{
+struct ComplianceTest_s {
     bool Running;
     uint8_t State;
     bool IsTxConfirmed;
@@ -233,7 +235,7 @@
     bool LinkCheck;
     uint8_t DemodMargin;
     uint8_t NbGateways;
-}ComplianceTest;
+} ComplianceTest;
 
 /*
  * SerialDisplay managment variables
@@ -247,22 +249,20 @@
 /*!
  * Strucure containing the Uplink status
  */
-struct sLoRaMacUplinkStatus
-{
+struct sLoRaMacUplinkStatus {
     uint8_t Acked;
     int8_t Datarate;
     uint16_t UplinkCounter;
     uint8_t Port;
     uint8_t *Buffer;
     uint8_t BufferSize;
-}LoRaMacUplinkStatus;
+} LoRaMacUplinkStatus;
 volatile bool UplinkStatusUpdated = false;
 
 /*!
  * Strucure containing the Downlink status
  */
-struct sLoRaMacDownlinkStatus
-{
+struct sLoRaMacDownlinkStatus {
     int16_t Rssi;
     int8_t Snr;
     uint16_t DownlinkCounter;
@@ -270,9 +270,14 @@
     uint8_t Port;
     uint8_t *Buffer;
     uint8_t BufferSize;
-}LoRaMacDownlinkStatus;
+} LoRaMacDownlinkStatus;
 volatile bool DownlinkStatusUpdated = false;
 
+/*!
+ * User Button to generate interupt and send messages
+ */
+InterruptIn userButton(USER_BUTTON);
+
 void SerialDisplayRefresh( void )
 {
     MibRequestConfirm_t mibReq;
@@ -301,16 +306,14 @@
     SerialDisplayUpdateDutyCycle( false );
 #endif
     SerialDisplayUpdatePublicNetwork( LORAWAN_PUBLIC_NETWORK );
-    
+
     SerialDisplayUpdateLedState( 3, AppLedStateOn );
 }
 
 void SerialRxProcess( void )
 {
-    if( SerialDisplayReadable( ) == true )
-    {
-        switch( SerialDisplayGetChar( ) )
-        {
+    if( SerialDisplayReadable( ) == true ) {
+        switch( SerialDisplayGetChar( ) ) {
             case 'R':
             case 'r':
                 // Refresh Serial screen
@@ -327,58 +330,138 @@
  */
 static void PrepareTxFrame( uint8_t port )
 {
-    switch( port )
-    {
-    case 10:
-        {  
+    switch( port ) {
+        case 10: {
+            int pos = 0;
+
+            pc.printf("Prepare message\n");
+#if 0
             uint32_t tempValue = ( uint32_t )( LightValue * 1000000.0 );
             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 );
-        }
-        break;
-    case 15:
-        {
-            AppData[0] = AppLedStateOn;
-            if( IsTxConfirmed == true )
-            {
-                AppData[1] = LoRaMacDownlinkStatus.DownlinkCounter >> 8;
-                AppData[2] = LoRaMacDownlinkStatus.DownlinkCounter;
-                AppData[3] = LoRaMacDownlinkStatus.Rssi >> 8;
-                AppData[4] = LoRaMacDownlinkStatus.Rssi;
-                AppData[5] = LoRaMacDownlinkStatus.Snr;
+#else
+            int err = 1;
+
+            pc.printf("read dht ");
+            for (int t = 0; t<5; t ++) {
+                err = dhtSensor.readData();
+                if (err == 0)
+                    break;
+            }
+            if (err) {
+                pc.printf("error: %d ", err);
+                for (int i=0; i<4; i++)
+                    AppData[pos++]  = 0xFF;
+            } else {
+
+                int16_t  humidity = dhtSensor.ReadHumidity()*100;
+                int16_t temp = dhtSensor.ReadTemperature(CELCIUS) * 100;
+                AppData[pos++]  = humidity  >> 8;
+                AppData[pos++]  = humidity;
+                AppData[pos++]  = temp >> 8;
+                AppData[pos++]  = temp ;
             }
+
+
+            pc.printf("read bmp ");
+            bmpSensor.measure();
+            int16_t pressure = bmpSensor.get_pressure();
+            AppData[pos++]  = pressure  >> 8;
+            AppData[pos++]  = pressure;
+            int16_t temp = bmpSensor.get_temperature() * 100;
+            AppData[pos++]  = temp >> 8;
+            AppData[pos++]  = temp ;
+            pc.printf("bmp: %d %d", pressure, temp);
+
+            pc.printf("read sds ");
+            sdsSensor.readData();
+            int pm = sdsSensor.PM2_5() * 10;
+            AppData[pos++]  = pm >> 8;
+            AppData[pos++]  = pm;
+            pm = sdsSensor.PM10() * 10;
+            AppData[pos++]  = pm >> 8;
+            AppData[pos++]  = pm;
+
+            AppDataSize = pos;
+            for (int i=0; i<pos; i++)
+            { pc.printf("%02x ", AppData[i]);
+            }
+            pc.printf("\n");
+#endif
+            pc.printf("Message Ready\n");
         }
         break;
-    case 224:
-        if( ComplianceTest.LinkCheck == true )
-        {
-            ComplianceTest.LinkCheck = false;
-            AppDataSize = 3;
-            AppData[0] = 5;
-            AppData[1] = ComplianceTest.DemodMargin;
-            AppData[2] = ComplianceTest.NbGateways;
-            ComplianceTest.State = 1;
-        }
-        else
-        {
-            switch( ComplianceTest.State )
-            {
-            case 4:
-                ComplianceTest.State = 1;
-                break;
-            case 1:
-                AppDataSize = 2;
-                AppData[0] = ComplianceTest.DownLinkCounter >> 8;
-                AppData[1] = ComplianceTest.DownLinkCounter;
-                break;
+        case 15: {
+            int pos = 0;
+            AppData[pos++] = AppLedStateOn;
+#if 0
+            int err = 1;
+
+            while(err != 0) {
+                wait(2.0f);
+//                err = dhtSensor.readData();
             }
+
+            int16_t  humidity = dhtSensor.ReadHumidity()*100;
+            AppData[pos++]  = humidity  >> 8;
+            AppData[pos++]  = humidity;
+            int16_t temp = dhtSensor.ReadTemperature(CELCIUS) * 100;
+            AppData[pos++]  = temp >> 8;
+            AppData[pos++]  = temp ;
+
+//            bmpSensor.measure();
+            int16_t pressure = bmpSensor.get_pressure();
+            AppData[pos++]  = pressure  >> 8;
+            AppData[pos++]  = pressure;
+            temp = bmpSensor.get_temperature() * 100;
+            AppData[pos++]  = temp >> 8;
+            AppData[pos++]  = temp ;
+
+//            sdsSensor.readData();
+            int pm = sdsSensor.PM2_5() * 10;
+            AppData[pos++]  = pm >> 8;
+            AppData[pos++]  = pm;
+            pm = sdsSensor.PM10() * 10;
+            AppData[pos++]  = pm >> 8;
+            AppData[pos++]  = pm;
+
+            if( IsTxConfirmed == true ) {
+                AppData[pos++] = LoRaMacDownlinkStatus.DownlinkCounter >> 8;
+                AppData[pos++] = LoRaMacDownlinkStatus.DownlinkCounter;
+                AppData[pos++] = LoRaMacDownlinkStatus.Rssi >> 8;
+                AppData[pos++] = LoRaMacDownlinkStatus.Rssi;
+                AppData[pos++] = LoRaMacDownlinkStatus.Snr;
+            }
+#endif
+            AppDataSize = pos;
         }
         break;
-    default:
-        break;
+        case 224:
+            if( ComplianceTest.LinkCheck == true ) {
+                ComplianceTest.LinkCheck = false;
+                AppDataSize = 3;
+                AppData[0] = 5;
+                AppData[1] = ComplianceTest.DemodMargin;
+                AppData[2] = ComplianceTest.NbGateways;
+                ComplianceTest.State = 1;
+            } else {
+                switch( ComplianceTest.State ) {
+                    case 4:
+                        ComplianceTest.State = 1;
+                        break;
+                    case 1:
+                        AppDataSize = 2;
+                        AppData[0] = ComplianceTest.DownLinkCounter >> 8;
+                        AppData[1] = ComplianceTest.DownLinkCounter;
+                        break;
+                }
+            }
+            break;
+        default:
+            break;
     }
 }
 
@@ -391,9 +474,8 @@
 {
     McpsReq_t mcpsReq;
     LoRaMacTxInfo_t txInfo;
-    
-    if( LoRaMacQueryTxPossible( AppDataSize, &txInfo ) != LORAMAC_STATUS_OK )
-    {
+
+    if( LoRaMacQueryTxPossible( AppDataSize, &txInfo ) != LORAMAC_STATUS_OK ) {
         // Send empty frame in order to flush MAC commands
         mcpsReq.Type = MCPS_UNCONFIRMED;
         mcpsReq.Req.Unconfirmed.fBuffer = NULL;
@@ -405,25 +487,20 @@
         LoRaMacUplinkStatus.Buffer = NULL;
         LoRaMacUplinkStatus.BufferSize = 0;
         SerialDisplayUpdateFrameType( false );
-    }
-    else
-    {
+    } else {
         LoRaMacUplinkStatus.Acked = false;
         LoRaMacUplinkStatus.Port = AppPort;
         LoRaMacUplinkStatus.Buffer = AppData;
         LoRaMacUplinkStatus.BufferSize = AppDataSize;
         SerialDisplayUpdateFrameType( IsTxConfirmed );
 
-        if( IsTxConfirmed == false )
-        {
+        if( IsTxConfirmed == false ) {
             mcpsReq.Type = MCPS_UNCONFIRMED;
             mcpsReq.Req.Unconfirmed.fPort = AppPort;
             mcpsReq.Req.Unconfirmed.fBuffer = AppData;
             mcpsReq.Req.Unconfirmed.fBufferSize = AppDataSize;
             mcpsReq.Req.Unconfirmed.Datarate = LORAWAN_DEFAULT_DATARATE;
-        }
-        else
-        {
+        } else {
             mcpsReq.Type = MCPS_CONFIRMED;
             mcpsReq.Req.Confirmed.fPort = AppPort;
             mcpsReq.Req.Confirmed.fBuffer = AppData;
@@ -433,8 +510,7 @@
         }
     }
 
-    if( LoRaMacMcpsRequest( &mcpsReq ) == LORAMAC_STATUS_OK )
-    {
+    if( LoRaMacMcpsRequest( &mcpsReq ) == LORAMAC_STATUS_OK ) {
         return false;
     }
     return true;
@@ -453,15 +529,11 @@
     mibReq.Type = MIB_NETWORK_JOINED;
     status = LoRaMacMibGetRequestConfirm( &mibReq );
 
-    if( status == LORAMAC_STATUS_OK )
-    {
-        if( mibReq.Param.IsNetworkJoined == true )
-        {
+    if( status == LORAMAC_STATUS_OK ) {
+        if( mibReq.Param.IsNetworkJoined == true ) {
             DeviceState = DEVICE_STATE_SEND;
             NextTx = true;
-        }
-        else
-        {
+        } else {
             DeviceState = DEVICE_STATE_JOIN;
         }
     }
@@ -506,18 +578,14 @@
  */
 static void McpsConfirm( McpsConfirm_t *mcpsConfirm )
 {
-    if( mcpsConfirm->Status == LORAMAC_EVENT_INFO_STATUS_OK )
-    {
-        switch( mcpsConfirm->McpsRequest )
-        {
-            case MCPS_UNCONFIRMED:
-            {
+    if( mcpsConfirm->Status == LORAMAC_EVENT_INFO_STATUS_OK ) {
+        switch( mcpsConfirm->McpsRequest ) {
+            case MCPS_UNCONFIRMED: {
                 // Check Datarate
                 // Check TxPower
                 break;
             }
-            case MCPS_CONFIRMED:
-            {
+            case MCPS_CONFIRMED: {
                 // Check Datarate
                 // Check TxPower
                 // Check AckReceived
@@ -525,8 +593,7 @@
                 LoRaMacUplinkStatus.Acked = mcpsConfirm->AckReceived;
                 break;
             }
-            case MCPS_PROPRIETARY:
-            {
+            case MCPS_PROPRIETARY: {
                 break;
             }
             default:
@@ -553,27 +620,21 @@
  */
 static void McpsIndication( McpsIndication_t *mcpsIndication )
 {
-    if( mcpsIndication->Status != LORAMAC_EVENT_INFO_STATUS_OK )
-    {
+    if( mcpsIndication->Status != LORAMAC_EVENT_INFO_STATUS_OK ) {
         return;
     }
 
-    switch( mcpsIndication->McpsIndication )
-    {
-        case MCPS_UNCONFIRMED:
-        {
+    switch( mcpsIndication->McpsIndication ) {
+        case MCPS_UNCONFIRMED: {
             break;
         }
-        case MCPS_CONFIRMED:
-        {
+        case MCPS_CONFIRMED: {
             break;
         }
-        case MCPS_PROPRIETARY:
-        {
+        case MCPS_PROPRIETARY: {
             break;
         }
-        case MCPS_MULTICAST:
-        {
+        case MCPS_MULTICAST: {
             break;
         }
         default:
@@ -590,14 +651,11 @@
     // Check Snr
     // Check RxSlot
     LoRaMacDownlinkStatus.Rssi = mcpsIndication->Rssi;
-    if( mcpsIndication->Snr & 0x80 ) // The SNR sign bit is 1
-    {
+    if( mcpsIndication->Snr & 0x80 ) { // The SNR sign bit is 1
         // Invert and divide by 4
         LoRaMacDownlinkStatus.Snr = ( ( ~mcpsIndication->Snr + 1 ) & 0xFF ) >> 2;
         LoRaMacDownlinkStatus.Snr = -LoRaMacDownlinkStatus.Snr;
-    }
-    else
-    {
+    } else {
         // Divide by 4
         LoRaMacDownlinkStatus.Snr = ( mcpsIndication->Snr & 0xFF ) >> 2;
     }
@@ -607,138 +665,125 @@
     LoRaMacDownlinkStatus.Buffer = mcpsIndication->Buffer;
     LoRaMacDownlinkStatus.BufferSize = mcpsIndication->BufferSize;
 
-    if( ComplianceTest.Running == true )
-    {
+    if( ComplianceTest.Running == true ) {
         ComplianceTest.DownLinkCounter++;
     }
 
-    if( mcpsIndication->RxData == true )
-    {
-        switch( mcpsIndication->Port )
-        {
-        case 1: // The application LED can be controlled on port 1 or 2
-        case 2:
-            if( mcpsIndication->BufferSize == 1 )
-            {
-                AppLedStateOn = mcpsIndication->Buffer[0] & 0x01;
-                Led3StateChanged = true;
-            }
-            break;
-        case 10: 
-            Display.write( 0, mcpsIndication->Buffer[0] );
-            Display.write( 1, mcpsIndication->Buffer[1] );
-            Display.write( 2, mcpsIndication->Buffer[2] );
-            Display.write( 3, mcpsIndication->Buffer[3] ); 
-            break;
-        case 20:
-            LightMode = mcpsIndication->Buffer[0];
-            if( LightMode )
-            {
-                ColorLed.setColorRGB( 0, mcpsIndication->Buffer[1], mcpsIndication->Buffer[2], mcpsIndication->Buffer[3] );
-            }
-            break;
-        case 30:
-            BuzzerTimer.attach_us( &OnBuzzerTimerEvent, 200000 );
-            Buzzer = 1;
-            break;
-        case 224:
-            if( ComplianceTest.Running == false )
-            {
-                // Check compliance test enable command (i)
-                if( ( mcpsIndication->BufferSize == 4 ) &&
-                    ( mcpsIndication->Buffer[0] == 0x01 ) &&
-                    ( mcpsIndication->Buffer[1] == 0x01 ) &&
-                    ( mcpsIndication->Buffer[2] == 0x01 ) &&
-                    ( mcpsIndication->Buffer[3] == 0x01 ) )
-                {
-                    IsTxConfirmed = false;
-                    AppPort = 224;
-                    AppDataSize = 2;
-                    ComplianceTest.DownLinkCounter = 0;
-                    ComplianceTest.LinkCheck = false;
-                    ComplianceTest.DemodMargin = 0;
-                    ComplianceTest.NbGateways = 0;
-                    ComplianceTest.Running = true;
-                    ComplianceTest.State = 1;
-                    
-                    MibRequestConfirm_t mibReq;
-                    mibReq.Type = MIB_ADR;
-                    mibReq.Param.AdrEnable = true;
-                    LoRaMacMibSetRequestConfirm( &mibReq );
+    if( mcpsIndication->RxData == true ) {
+        switch( mcpsIndication->Port ) {
+            case 1: // The application LED can be controlled on port 1 or 2
+            case 2:
+                if( mcpsIndication->BufferSize == 1 ) {
+                    AppLedStateOn = mcpsIndication->Buffer[0] & 0x01;
+                    Led3StateChanged = true;
+                }
+                break;
+            case 10:
+                Display.write( 0, mcpsIndication->Buffer[0] );
+                Display.write( 1, mcpsIndication->Buffer[1] );
+                Display.write( 2, mcpsIndication->Buffer[2] );
+                Display.write( 3, mcpsIndication->Buffer[3] );
+                break;
+            case 20:
+                LightMode = mcpsIndication->Buffer[0];
+                if( LightMode ) {
+                    ColorLed.setColorRGB( 0, mcpsIndication->Buffer[1], mcpsIndication->Buffer[2], mcpsIndication->Buffer[3] );
+                }
+                break;
+            case 30:
+                BuzzerTimer.attach_us( &OnBuzzerTimerEvent, 200000 );
+                Buzzer = 1;
+                break;
+            case 224:
+                if( ComplianceTest.Running == false ) {
+                    // Check compliance test enable command (i)
+                    if( ( mcpsIndication->BufferSize == 4 ) &&
+                            ( mcpsIndication->Buffer[0] == 0x01 ) &&
+                            ( mcpsIndication->Buffer[1] == 0x01 ) &&
+                            ( mcpsIndication->Buffer[2] == 0x01 ) &&
+                            ( mcpsIndication->Buffer[3] == 0x01 ) ) {
+                        IsTxConfirmed = false;
+                        AppPort = 224;
+                        AppDataSize = 2;
+                        ComplianceTest.DownLinkCounter = 0;
+                        ComplianceTest.LinkCheck = false;
+                        ComplianceTest.DemodMargin = 0;
+                        ComplianceTest.NbGateways = 0;
+                        ComplianceTest.Running = true;
+                        ComplianceTest.State = 1;
+
+                        MibRequestConfirm_t mibReq;
+                        mibReq.Type = MIB_ADR;
+                        mibReq.Param.AdrEnable = true;
+                        LoRaMacMibSetRequestConfirm( &mibReq );
 
 #if defined( USE_BAND_868 )
-                    LoRaMacTestSetDutyCycleOn( false );
+                        LoRaMacTestSetDutyCycleOn( false );
 #endif
-                }
-            }
-            else
-            {
-                ComplianceTest.State = mcpsIndication->Buffer[0];
-                switch( ComplianceTest.State )
-                {
-                case 0: // Check compliance test disable command (ii)
-                    IsTxConfirmed = LORAWAN_CONFIRMED_MSG_ON;
-                    AppPort = LORAWAN_APP_PORT;
-                    AppDataSize = LORAWAN_APP_DATA_SIZE;
-                    ComplianceTest.DownLinkCounter = 0;
-                    ComplianceTest.Running = false;
-                    
-                    MibRequestConfirm_t mibReq;
-                    mibReq.Type = MIB_ADR;
-                    mibReq.Param.AdrEnable = LORAWAN_ADR_ON;
-                    LoRaMacMibSetRequestConfirm( &mibReq );
+                    }
+                } else {
+                    ComplianceTest.State = mcpsIndication->Buffer[0];
+                    switch( ComplianceTest.State ) {
+                        case 0: // Check compliance test disable command (ii)
+                            IsTxConfirmed = LORAWAN_CONFIRMED_MSG_ON;
+                            AppPort = LORAWAN_APP_PORT;
+                            AppDataSize = LORAWAN_APP_DATA_SIZE;
+                            ComplianceTest.DownLinkCounter = 0;
+                            ComplianceTest.Running = false;
+
+                            MibRequestConfirm_t mibReq;
+                            mibReq.Type = MIB_ADR;
+                            mibReq.Param.AdrEnable = LORAWAN_ADR_ON;
+                            LoRaMacMibSetRequestConfirm( &mibReq );
 #if defined( USE_BAND_868 )
-                    LoRaMacTestSetDutyCycleOn( LORAWAN_DUTYCYCLE_ON );
+                            LoRaMacTestSetDutyCycleOn( LORAWAN_DUTYCYCLE_ON );
 #endif
-                    break;
-                case 1: // (iii, iv)
-                    AppDataSize = 2;
-                    break;
-                case 2: // Enable confirmed messages (v)
-                    IsTxConfirmed = true;
-                    ComplianceTest.State = 1;
-                    break;
-                case 3:  // Disable confirmed messages (vi)
-                    IsTxConfirmed = false;
-                    ComplianceTest.State = 1;
-                    break;
-                case 4: // (vii)
-                    AppDataSize = mcpsIndication->BufferSize;
+                            break;
+                        case 1: // (iii, iv)
+                            AppDataSize = 2;
+                            break;
+                        case 2: // Enable confirmed messages (v)
+                            IsTxConfirmed = true;
+                            ComplianceTest.State = 1;
+                            break;
+                        case 3:  // Disable confirmed messages (vi)
+                            IsTxConfirmed = false;
+                            ComplianceTest.State = 1;
+                            break;
+                        case 4: // (vii)
+                            AppDataSize = mcpsIndication->BufferSize;
 
-                    AppData[0] = 4;
-                    for( uint8_t i = 1; i < AppDataSize; i++ )
-                    {
-                        AppData[i] = mcpsIndication->Buffer[i] + 1;
+                            AppData[0] = 4;
+                            for( uint8_t i = 1; i < AppDataSize; i++ ) {
+                                AppData[i] = mcpsIndication->Buffer[i] + 1;
+                            }
+                            break;
+                        case 5: { // (viii)
+                            MlmeReq_t mlmeReq;
+                            mlmeReq.Type = MLME_LINK_CHECK;
+                            LoRaMacMlmeRequest( &mlmeReq );
+                        }
+                        break;
+                        case 6: { // (ix)
+                            MlmeReq_t mlmeReq;
+
+                            mlmeReq.Type = MLME_JOIN;
+
+                            mlmeReq.Req.Join.DevEui = DevEui;
+                            mlmeReq.Req.Join.AppEui = AppEui;
+                            mlmeReq.Req.Join.AppKey = AppKey;
+
+                            LoRaMacMlmeRequest( &mlmeReq );
+                            DeviceState = DEVICE_STATE_SLEEP;
+                        }
+                        break;
+                        default:
+                            break;
                     }
-                    break;
-                case 5: // (viii)
-                    {
-                        MlmeReq_t mlmeReq;
-                        mlmeReq.Type = MLME_LINK_CHECK;
-                        LoRaMacMlmeRequest( &mlmeReq );
-                    }
-                    break;
-                case 6: // (ix)
-                    {
-                        MlmeReq_t mlmeReq;
-
-                        mlmeReq.Type = MLME_JOIN;
-
-                        mlmeReq.Req.Join.DevEui = DevEui;
-                        mlmeReq.Req.Join.AppEui = AppEui;
-                        mlmeReq.Req.Join.AppKey = AppKey;
-
-                        LoRaMacMlmeRequest( &mlmeReq );
-                        DeviceState = DEVICE_STATE_SLEEP;
-                    }
-                    break;
-                default:
-                    break;
                 }
-            }
-            break;
-        default:
-            break;
+                break;
+            default:
+                break;
         }
     }
 
@@ -757,24 +802,19 @@
  */
 static void MlmeConfirm( MlmeConfirm_t *mlmeConfirm )
 {
-    if( mlmeConfirm->Status == LORAMAC_EVENT_INFO_STATUS_OK )
-    {
-        switch( mlmeConfirm->MlmeRequest )
-        {
-            case MLME_JOIN:
-            {
+    if( mlmeConfirm->Status == LORAMAC_EVENT_INFO_STATUS_OK ) {
+        switch( mlmeConfirm->MlmeRequest ) {
+            case MLME_JOIN: {
                 // Status is OK, node has joined the network
                 IsNetworkJoinedStatusUpdate = true;
                 DeviceState = DEVICE_STATE_SEND;
                 NextTx = true;
                 break;
             }
-            case MLME_LINK_CHECK:
-            {
+            case MLME_LINK_CHECK: {
                 // Check DemodMargin
                 // Check NbGateways
-                if( ComplianceTest.Running == true )
-                {
+                if( ComplianceTest.Running == true ) {
                     ComplianceTest.LinkCheck = true;
                     ComplianceTest.DemodMargin = mlmeConfirm->DemodMargin;
                     ComplianceTest.NbGateways = mlmeConfirm->NbGateways;
@@ -789,16 +829,28 @@
     UplinkStatusUpdated = true;
 }
 
+/*!
+ * \brief Function executed when user button is pressed
+ */
+void buttonPressed()
+{
+    pc.printf("Button pressed\n");
+    DeviceState = DEVICE_STATE_SEND;
+}
+
 /**
  * Main application entry point.
  */
 int main( void )
 {
+    pc.printf("main entry\n");
     LoRaMacPrimitives_t LoRaMacPrimitives;
     LoRaMacCallback_t LoRaMacCallbacks;
     MibRequestConfirm_t mibReq;
 
+    pc.printf("Board init");
     BoardInit( );
+    pc.printf("Serial display");
     SerialDisplayInit( );
 
     LightMode = 0;      // 0: manual,   1: automatic
@@ -815,49 +867,43 @@
     SerialDisplayUpdateKey( 13, AppSKey );
 #endif
 
+    userButton.fall(&buttonPressed);
+
     DeviceState = DEVICE_STATE_INIT;
 
-    while( 1 )
-    {
+    while( 1 ) {
         SerialRxProcess( );
-        if( IsNetworkJoinedStatusUpdate == true )
-        {
+        if( IsNetworkJoinedStatusUpdate == true ) {
             IsNetworkJoinedStatusUpdate = false;
             mibReq.Type = MIB_NETWORK_JOINED;
             LoRaMacMibGetRequestConfirm( &mibReq );
             SerialDisplayUpdateNetworkIsJoined( mibReq.Param.IsNetworkJoined );
         }
-        if( Led1StateChanged == true )
-        {
+        if( Led1StateChanged == true ) {
             Led1StateChanged = false;
             SerialDisplayUpdateLedState( 1, Led1State );
         }
-        if( Led2StateChanged == true )
-        {
+        if( Led2StateChanged == true ) {
             Led2StateChanged = false;
             SerialDisplayUpdateLedState( 2, Led2State );
         }
-        if( Led3StateChanged == true )
-        {
+        if( Led3StateChanged == true ) {
             Led3StateChanged = false;
             SerialDisplayUpdateLedState( 3, AppLedStateOn );
         }
-        if( UplinkStatusUpdated == true )
-        {
+        if( UplinkStatusUpdated == true ) {
             UplinkStatusUpdated = false;
             SerialDisplayUpdateUplink( LoRaMacUplinkStatus.Acked, LoRaMacUplinkStatus.Datarate, LoRaMacUplinkStatus.UplinkCounter, LoRaMacUplinkStatus.Port, LoRaMacUplinkStatus.Buffer, LoRaMacUplinkStatus.BufferSize );
         }
-        if( DownlinkStatusUpdated == true )
-        {
+        if( DownlinkStatusUpdated == true ) {
             DownlinkStatusUpdated = false;
             SerialDisplayUpdateLedState( 2, Led2State );
             SerialDisplayUpdateDownlink( LoRaMacDownlinkStatus.RxData, LoRaMacDownlinkStatus.Rssi, LoRaMacDownlinkStatus.Snr, LoRaMacDownlinkStatus.DownlinkCounter, LoRaMacDownlinkStatus.Port, LoRaMacDownlinkStatus.Buffer, LoRaMacDownlinkStatus.BufferSize );
         }
-        
-        switch( DeviceState )
-        {
-            case DEVICE_STATE_INIT:
-            {
+
+        switch( DeviceState ) {
+            case DEVICE_STATE_INIT: {
+                pc.printf("DEVICE_STATE_INIT\n");
                 LoRaMacPrimitives.MacMcpsConfirm = McpsConfirm;
                 LoRaMacPrimitives.MacMcpsIndication = McpsIndication;
                 LoRaMacPrimitives.MacMlmeConfirm = MlmeConfirm;
@@ -884,7 +930,7 @@
                 LoRaMacTestSetDutyCycleOn( LORAWAN_DUTYCYCLE_ON );
                 SerialDisplayUpdateDutyCycle( LORAWAN_DUTYCYCLE_ON );
 
-#if( USE_SEMTECH_DEFAULT_CHANNEL_LINEUP == 1 ) 
+#if( USE_SEMTECH_DEFAULT_CHANNEL_LINEUP == 1 )
                 LoRaMacChannelAdd( 3, ( ChannelParams_t )LC4 );
                 LoRaMacChannelAdd( 4, ( ChannelParams_t )LC5 );
                 LoRaMacChannelAdd( 5, ( ChannelParams_t )LC6 );
@@ -894,7 +940,9 @@
                 LoRaMacChannelAdd( 9, ( ChannelParams_t )LC10 );
 
                 mibReq.Type = MIB_RX2_CHANNEL;
-                mibReq.Param.Rx2Channel = ( Rx2ChannelParams_t ){ 869525000, DR_3 };
+                mibReq.Param.Rx2Channel = ( Rx2ChannelParams_t ) {
+                    869525000, DR_3
+                };
                 LoRaMacMibSetRequestConfirm( &mibReq );
 #endif
 
@@ -908,8 +956,8 @@
                 DeviceState = DEVICE_STATE_JOIN;
                 break;
             }
-            case DEVICE_STATE_JOIN:
-            {
+            case DEVICE_STATE_JOIN: {
+                pc.printf("DEVICE_STATE_JOIN\n");
 #if( OVER_THE_AIR_ACTIVATION != 0 )
                 MlmeReq_t mlmeReq;
 
@@ -919,8 +967,7 @@
                 mlmeReq.Req.Join.AppEui = AppEui;
                 mlmeReq.Req.Join.AppKey = AppKey;
 
-                if( NextTx == true )
-                {
+                if( NextTx == true ) {
                     LoRaMacMlmeRequest( &mlmeReq );
                 }
                 DeviceState = DEVICE_STATE_SLEEP;
@@ -950,31 +997,27 @@
                 IsNetworkJoinedStatusUpdate = true;
                 break;
             }
-            case DEVICE_STATE_SEND:
-            {
-                if( NextTx == true )
-                {
+            case DEVICE_STATE_SEND: {
+                pc.printf("DEVICE_STATE_SEND\n");
+                if( NextTx == true ) {
                     SerialDisplayUpdateUplinkAcked( false );
                     SerialDisplayUpdateDonwlinkRxData( false );
                     PrepareTxFrame( AppPort );
 
                     NextTx = SendFrame( );
                 }
-                if( ComplianceTest.Running == true )
-                {
+                if( ComplianceTest.Running == true ) {
                     // Schedule next packet transmission
                     TxDutyCycleTime = 5000000; // 5000000 us
-                }
-                else
-                {
+                } else {
                     // Schedule next packet transmission
                     TxDutyCycleTime = APP_TX_DUTYCYCLE + randr( -APP_TX_DUTYCYCLE_RND, APP_TX_DUTYCYCLE_RND );
                 }
                 DeviceState = DEVICE_STATE_CYCLE;
                 break;
             }
-            case DEVICE_STATE_CYCLE:
-            {
+            case DEVICE_STATE_CYCLE: {
+                pc.printf("DEVICE_STATE_CYCLE\n");
                 DeviceState = DEVICE_STATE_SLEEP;
 
                 // Schedule next packet transmission
@@ -982,25 +1025,23 @@
                 TimerStart( &TxNextPacketTimer );
                 break;
             }
-            case DEVICE_STATE_SLEEP:
-            {
+            case DEVICE_STATE_SLEEP: {
+//                pc.printf("DEVICE_STATE_SLEEP\n");
                 // Wake up through events
                 break;
             }
-            default:
-            {
+            default: {
                 DeviceState = DEVICE_STATE_INIT;
                 break;
             }
-            
+
         }
 
         // Read light sensor
         LightValue = ( 1 - ( LightSens.read( ) * 1.65 ) );
 
         // Set automatic RGB from light sensor
-        if( LightMode == 0 )
-        {
+        if( LightMode == 0 ) {
             ColorLed.setColorRGB( 0, ( uint8_t )( 255 * LightValue ), ( uint8_t )( 255 * LightValue ), ( uint8_t )( 255 * LightValue ) );
         }
     }