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

Files at this revision

API Documentation at this revision

Comitter:
abouillot
Date:
Mon Jan 30 21:49:58 2017 +0000
Parent:
8:4f65ef8c6e3c
Commit message:
Added support for BMP085, DHT22 and SDS021 sensors; Added support of update upon User Button push

Changed in this revision

BMP085.lib Show annotated file Show diff for this revision Revisions of this file
BufferedSerial.lib Show annotated file Show diff for this revision Revisions of this file
DHT.lib Show annotated file Show diff for this revision Revisions of this file
Sds021.lib Show annotated file Show diff for this revision Revisions of this file
app/Comissioning.h Show annotated file Show diff for this revision Revisions of this file
app/SerialDisplay.cpp Show annotated file Show diff for this revision Revisions of this file
app/main.cpp Show annotated file Show diff for this revision Revisions of this file
board/board.cpp Show annotated file Show diff for this revision Revisions of this file
board/board.h Show annotated file Show diff for this revision Revisions of this file
diff -r 4f65ef8c6e3c -r 16106008960b BMP085.lib
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/BMP085.lib	Mon Jan 30 21:49:58 2017 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/abouillot/code/BMP085/#ed587a5331e4
diff -r 4f65ef8c6e3c -r 16106008960b BufferedSerial.lib
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/BufferedSerial.lib	Mon Jan 30 21:49:58 2017 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/abouillot/code/BufferedSerial/#006e7d23b08a
diff -r 4f65ef8c6e3c -r 16106008960b DHT.lib
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DHT.lib	Mon Jan 30 21:49:58 2017 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/Wimpie/code/DHT/#9b5b3200688f
diff -r 4f65ef8c6e3c -r 16106008960b Sds021.lib
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Sds021.lib	Mon Jan 30 21:49:58 2017 +0000
@@ -0,0 +1,1 @@
+https://developer.mbed.org/users/abouillot/code/Sds021/#fd34f67797d9
diff -r 4f65ef8c6e3c -r 16106008960b app/Comissioning.h
--- a/app/Comissioning.h	Sat Jan 07 08:52:00 2017 +0000
+++ b/app/Comissioning.h	Mon Jan 30 21:49:58 2017 +0000
@@ -34,17 +34,18 @@
 /*!
  * Mote device IEEE EUI (big endian)
  */
-#define LORAWAN_DEVICE_EUI                          { IEEE_OUI, 0x44, 0x55, 0x66, 0x77, 0x88 }
+#define LORAWAN_DEVICE_EUI                          { 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x73 }
 
 /*!
  * Application IEEE EUI (big endian)
  */
-#define LORAWAN_APPLICATION_EUI                     { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
+//#define LORAWAN_APPLICATION_EUI                     { 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x73 }
+#define LORAWAN_APPLICATION_EUI                     { 0x70, 0xB3, 0xD5, 0x7E, 0xF0, 0x00, 0x36, 0x26 }
 
 /*!
  * AES encryption/decryption cipher application key
  */
-#define LORAWAN_APPLICATION_KEY                     { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C }
+#define LORAWAN_APPLICATION_KEY                     { 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
 
 /*!
  * Current network ID
diff -r 4f65ef8c6e3c -r 16106008960b app/SerialDisplay.cpp
--- a/app/SerialDisplay.cpp	Sat Jan 07 08:52:00 2017 +0000
+++ b/app/SerialDisplay.cpp	Mon Jan 30 21:49:58 2017 +0000
@@ -16,7 +16,9 @@
 #include "vt100.h"
 #include "SerialDisplay.h"
 
-VT100 vt( USBTX, USBRX );
+//VT100 vt( USBTX, USBRX );
+VT100 vt( PC_12, PD_2 );
+
 
 void SerialPrintCheckBox( bool activated, uint8_t color )
 {
diff -r 4f65ef8c6e3c -r 16106008960b app/main.cpp
--- 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 ) );
         }
     }
diff -r 4f65ef8c6e3c -r 16106008960b board/board.cpp
--- a/board/board.cpp	Sat Jan 07 08:52:00 2017 +0000
+++ b/board/board.cpp	Mon Jan 30 21:49:58 2017 +0000
@@ -17,12 +17,31 @@
 
 SX1272MB2xAS Radio( NULL );
 
+/*!
+ * BMP085 object to read presure and temperature
+ */
+//I2C i2c(D14, D15);
+BMP085 bmpSensor(D14, D15, BMP085_MODE_HIGH_RESOLUTION);
+//BMP085 bmpsensor(i2c, BMP085_MODE_HIGH_RESOLUTION);
+//BMP085 *bmpSensor;
+
+/*!
+ * DHT object to read humidity and temperature
+ */
+DHT dhtSensor(D7, 22);
+//DHT *dhtSensor;
+
+SDS021 sdsSensor(PC_10, PC_11);
+//SDS021 *sdsSensor;
+
 void BoardInit( void )
 {
-    TimerTimeCounterInit( );
+//    TimerTimeCounterInit( );
+//    sdsSensor = new SDS021(PC_10, PC_11);
+//    dhtSensor = new DHT(D7, 22);
+//    bmpSensor = new BMP085(D14, D15);
 }
 
-
 uint8_t BoardGetBatteryLevel( void ) 
 {
     return 0xFE;
diff -r 4f65ef8c6e3c -r 16106008960b board/board.h
--- a/board/board.h	Sat Jan 07 08:52:00 2017 +0000
+++ b/board/board.h	Mon Jan 30 21:49:58 2017 +0000
@@ -20,10 +20,20 @@
 #include "debug.h"
 #include "system/utilities.h"
 #include "sx1272-hal.h"
+#include "DHT.h"
+#include "BMP085.h"
+#include "Sds021.h"
 
 #define USE_BAND_868
 
 extern SX1272MB2xAS Radio;
+//extern BMP085 *bmpSensor;
+//extern DHT *dhtSensor;
+//extern SDS021 *sdsSensor;
+extern BMP085 bmpSensor;
+extern DHT dhtSensor;
+extern SDS021 sdsSensor;
+
 
 /*!
  * \brief Initializes the target board peripherals.