application layer with: button, LED, pot, tempSense

Dependencies:   mbed SX1272Lib

Fork of LoRaWAN-demo-72-bootcamp by Semtech

Use with sx1272 shield with grove peripherals connected:

D8 D9: ButtonRX TXA3 A4: TempSense
D6 D7:SCL SDA : LEDA1 A2: Pot

Button

Sends to different payloads: short press (under 1 sec)
long press: held down > 1 sec.

serial console keys

115200bps, 8N1
Enter key not used
Keys '0' to '3': cayenne channel number
'0': pot (rotary sensor)
'1': temperature
' 2': digital out
'3': analog out

Revision:
11:018e7e28161d
Parent:
10:52810ecbd83b
Child:
12:662ff73ce484
--- a/app/main.cpp	Tue Jan 30 22:49:12 2018 +0000
+++ b/app/main.cpp	Sat Feb 03 00:44:16 2018 +0000
@@ -115,7 +115,7 @@
 /*!
  * User application data size
  */
-static uint8_t AppDataSize = LORAWAN_APP_DATA_SIZE;
+static uint8_t gAppDataSize = LORAWAN_APP_DATA_SIZE;
 
 /*!
  * User application data buffer size
@@ -130,7 +130,7 @@
 /*!
  * Indicates if the node is sending confirmed or unconfirmed messages
  */
-static uint8_t IsTxConfirmed = LORAWAN_CONFIRMED_MSG_ON;
+static uint8_t gIsTxConfirmed = LORAWAN_CONFIRMED_MSG_ON;
 
 /*!
  * Device states
@@ -222,13 +222,101 @@
     //SerialDisplayUpdateLedState( 3, AppLedStateOn );
 }
 
+
+void LoRaMacStatus_toString(LoRaMacStatus_t s, char* out)
+{
+    switch (s) {
+        case LORAMAC_STATUS_PARAMETER_INVALID:
+            strcpy(out, "PARAMTER_INVALID");
+            break;
+        case LORAMAC_STATUS_BUSY:
+            strcpy(out, "BUSY");
+            break;
+        default:
+            sprintf(out, "<%u>", s);
+            break;
+    }
+}
+
+volatile unsigned sendCnt = 0;
+/*!
+ * \brief   Prepares the payload of the frame
+ *
+ * \retval  [0: frame could be send, 1: error]
+ */
+static bool SendFrame( uint8_t len, bool conf )
+{
+    char str[48];
+    LoRaMacStatus_t status;
+    McpsReq_t mcpsReq;
+    LoRaMacTxInfo_t txInfo;
+
+    if( LoRaMacQueryTxPossible( len, &txInfo ) != LORAMAC_STATUS_OK ) {
+        // Send empty frame in order to flush MAC commands
+        mcpsReq.Type = MCPS_UNCONFIRMED;
+        mcpsReq.Req.Unconfirmed.fBuffer = NULL;
+        mcpsReq.Req.Unconfirmed.fBufferSize = 0;
+        mcpsReq.Req.Unconfirmed.Datarate = LORAWAN_DEFAULT_DATARATE;
+
+        LoRaMacUplinkStatus.Acked = false;
+        LoRaMacUplinkStatus.Port = 0;
+        LoRaMacUplinkStatus.Buffer = NULL;
+        LoRaMacUplinkStatus.BufferSize = 0;
+        SerialDisplayUpdateFrameType( false );
+    } else {
+        LoRaMacUplinkStatus.Acked = false;
+        LoRaMacUplinkStatus.Port = AppPort;
+        LoRaMacUplinkStatus.Buffer = AppData;
+        LoRaMacUplinkStatus.BufferSize = len;//AppDataSize;
+        SerialDisplayUpdateFrameType( conf/*IsTxConfirmed*/ );
+
+        if( conf == false ) {
+            mcpsReq.Type = MCPS_UNCONFIRMED;
+            mcpsReq.Req.Unconfirmed.fPort = AppPort;
+            mcpsReq.Req.Unconfirmed.fBuffer = AppData;
+            mcpsReq.Req.Unconfirmed.fBufferSize = len;
+            mcpsReq.Req.Unconfirmed.Datarate = LORAWAN_DEFAULT_DATARATE;
+        } else {
+            mcpsReq.Type = MCPS_CONFIRMED;
+            mcpsReq.Req.Confirmed.fPort = AppPort;
+            mcpsReq.Req.Confirmed.fBuffer = AppData;
+            mcpsReq.Req.Confirmed.fBufferSize = len;
+            mcpsReq.Req.Confirmed.NbTrials = 8;
+            mcpsReq.Req.Confirmed.Datarate = LORAWAN_DEFAULT_DATARATE;
+        }
+    }
+
+    sendCnt++;
+    status = LoRaMacMcpsRequest( &mcpsReq );
+    if (status == LORAMAC_STATUS_OK) {
+        vt.SetCursorPos( 44, 1 );
+        vt.printf("%u sendFrame() OK\e[K", sendCnt);
+        SerialDisplayUpdateUplink(
+            LoRaMacUplinkStatus.Acked,
+            LoRaMacUplinkStatus.Datarate,
+            LoRaMacUplinkStatus.UplinkCounter,
+            LoRaMacUplinkStatus.Port,
+            LoRaMacUplinkStatus.Buffer,
+            LoRaMacUplinkStatus.BufferSize
+        );
+        return false;
+    }
+    LoRaMacStatus_toString(status, str);
+    vt.SetCursorPos( 44, 1 );
+    vt.printf("%u sendFrame() %s\e[K", sendCnt, str);
+    return true;
+}
+
 uint8_t c_ch;
 
 void SerialRxProcess( void )
 {
+    LoRaMacStatus_t status;
+    MlmeReq_t mlmeReq;
+    
     if( SerialDisplayReadable( ) == true ) {
         char ch = SerialDisplayGetChar();
-        if ( ch >= '0' || ch <= '9') {
+        if ( ch >= '0' && ch <= '9') {
             c_ch = ch - '0';
             DeviceState = DEVICE_STATE_SEND;
             return;
@@ -239,6 +327,12 @@
                 // Refresh Serial screen
                 SerialDisplayRefresh( );
                 break;
+            case 'L':
+                mlmeReq.Type = MLME_LINK_CHECK;
+                status = LoRaMacMlmeRequest( &mlmeReq );
+                if (status == LORAMAC_STATUS_OK)
+                    SendFrame(0, false);
+                break;
             default:
                 break;
         }
@@ -285,6 +379,7 @@
 const unsigned R0 = 100000;
 const unsigned B = 4275;
 
+
 volatile TimerTime_t buttonStartAt;
 DigitalIn d8(D8);
 DigitalOut extLed(D15);
@@ -299,50 +394,50 @@
     float t, f, R;
 
     if (c_ch != 0xff) {
-        AppDataSize = 0;
-        AppData[AppDataSize++] = c_ch;
+        gAppDataSize = 0;
+        AppData[gAppDataSize++] = c_ch;
         switch (c_ch) {
             case CAYENNE_CH_TEMP:
-                AppData[AppDataSize++] = LPP_TEMPERATURE;
-                u16 = a3.read_u16();
-                R = 65535 / u16 - 1.0;
+                AppData[gAppDataSize++] = LPP_TEMPERATURE;
+                u16 = a3.read_u16() >> 4;
+                R = 4096.0 / u16 - 1.0;
                 R = R0 * R;
                 t = 1.0/(log(R/R0)/B+1/298.15)-273.15;
                 u16 = t * 10;  // 0.1C per bit
-                AppData[AppDataSize++] = u16 >> 8;
-                AppData[AppDataSize++] = u16;
+                AppData[gAppDataSize++] = u16 >> 8;
+                AppData[gAppDataSize++] = u16;
                 break;
             case CAYENNE_CH_POT:
-                AppData[AppDataSize++] = LPP_ANALOG_INPUT;
+                AppData[gAppDataSize++] = LPP_ANALOG_INPUT;
                 u16 = a1.read_u16();    // pot (rotary angle)
                 f = u16 / 198.6;    // scale 65535/3.3 to 0.01v per bit
                 rot = (uint16_t) f;
-                AppData[AppDataSize++] = rot >> 8;
-                AppData[AppDataSize++] = rot;
+                AppData[gAppDataSize++] = rot >> 8;
+                AppData[gAppDataSize++] = rot;
                 break;
             case CAYENNE_CH_DOUT:
-                AppData[AppDataSize++] = LPP_DIGITAL_OUTPUT;
-                AppData[AppDataSize++] = extLed.read();
+                AppData[gAppDataSize++] = LPP_DIGITAL_OUTPUT;
+                AppData[gAppDataSize++] = extLed.read();
                 break;
             case CAYENNE_CH_AOUT:
-                AppData[AppDataSize++] = LPP_ANALOG_OUTPUT;
+                AppData[gAppDataSize++] = LPP_ANALOG_OUTPUT;
                 u16 = pwm.read() * 100;
-                AppData[AppDataSize++] = u16 >> 8;
-                AppData[AppDataSize++] = u16;
+                AppData[gAppDataSize++] = u16 >> 8;
+                AppData[gAppDataSize++] = u16;
                 break;
         }
         return;
     } else if (cayenne_ack_ch != -1) {
         switch (cayenne_ack_ch) {
             case CAYENNE_CH_DOUT:
-                AppData[AppDataSize++] = LPP_DIGITAL_OUTPUT;
-                AppData[AppDataSize++] = extLed.read();
+                AppData[gAppDataSize++] = LPP_DIGITAL_OUTPUT;
+                AppData[gAppDataSize++] = extLed.read();
                 break;
             case CAYENNE_CH_AOUT:
-                AppData[AppDataSize++] = LPP_ANALOG_OUTPUT;
+                AppData[gAppDataSize++] = LPP_ANALOG_OUTPUT;
                 u16 = pwm.read() * 100;
-                AppData[AppDataSize++] = u16 >> 8;
-                AppData[AppDataSize++] = u16;
+                AppData[gAppDataSize++] = u16 >> 8;
+                AppData[gAppDataSize++] = u16;
                 break;
         }
         cayenne_ack_ch = -1;
@@ -352,10 +447,10 @@
         TimerTime_t duration = TimerGetCurrentTime() - buttonStartAt;
         vt.SetCursorPos( 41, 1 );
         if (duration > 1000) {
-            AppDataSize = 0;
-            AppData[AppDataSize++] = CAYENNE_CH_DOUT;
-            AppData[AppDataSize++] = LPP_DIGITAL_OUTPUT;
-            AppData[AppDataSize++] = extLed.read();
+            gAppDataSize = 0;
+            AppData[gAppDataSize++] = CAYENNE_CH_DOUT;
+            AppData[gAppDataSize++] = LPP_DIGITAL_OUTPUT;
+            AppData[gAppDataSize++] = extLed.read();
             vt.printf("send outputs           ", duration);
             return;
         } else
@@ -364,34 +459,34 @@
 
     switch( port ) {
         case LORAWAN_APP_PORT:
-            AppDataSize = 0;
-            AppData[AppDataSize++] = CAYENNE_CH_TEMP;
-            AppData[AppDataSize++] = LPP_TEMPERATURE;
-            u16 = a3.read_u16();
-            R = 65535 / u16 - 1.0;
+            gAppDataSize = 0;
+            AppData[gAppDataSize++] = CAYENNE_CH_TEMP;
+            AppData[gAppDataSize++] = LPP_TEMPERATURE;
+            u16 = a3.read_u16() >> 4;
+            R = 4096.0 / u16 - 1.0;
             R = R0 * R;
             t = 1.0/(log(R/R0)/B+1/298.15)-273.15;
             u16 = t * 10;  // 0.1C per bit
-            AppData[AppDataSize++] = u16 >> 8;
-            AppData[AppDataSize++] = u16;
-            AppData[AppDataSize++] = CAYENNE_CH_POT;
-            AppData[AppDataSize++] = LPP_ANALOG_INPUT;
+            AppData[gAppDataSize++] = u16 >> 8;
+            AppData[gAppDataSize++] = u16;
+            AppData[gAppDataSize++] = CAYENNE_CH_POT;
+            AppData[gAppDataSize++] = LPP_ANALOG_INPUT;
             u16 = a1.read_u16();    // pot (rotary angle)
             f = u16 / 198.6;    // scale 65535/3.3 to 0.01v per bit
             rot = (uint16_t) f;
-            AppData[AppDataSize++] = rot >> 8;
-            AppData[AppDataSize++] = rot;
+            AppData[gAppDataSize++] = rot >> 8;
+            AppData[gAppDataSize++] = rot;
 
-            AppData[AppDataSize++] = CAYENNE_CH_DOUT;
-            AppData[AppDataSize++] = LPP_DIGITAL_OUTPUT;
-            AppData[AppDataSize++] = extLed.read();
+            AppData[gAppDataSize++] = CAYENNE_CH_DOUT;
+            AppData[gAppDataSize++] = LPP_DIGITAL_OUTPUT;
+            AppData[gAppDataSize++] = extLed.read();
             vt.SetCursorPos( 41, 1 );
             vt.printf("u16:%u, f:%f, rot:%u t:%.1f\e[K", u16, f, rot, t);
             break;
         case 224:
             if( ComplianceTest.LinkCheck == true ) {
                 ComplianceTest.LinkCheck = false;
-                AppDataSize = 3;
+                gAppDataSize = 3;
                 AppData[0] = 5;
                 AppData[1] = ComplianceTest.DemodMargin;
                 AppData[2] = ComplianceTest.NbGateways;
@@ -402,7 +497,7 @@
                         ComplianceTest.State = 1;
                         break;
                     case 1:
-                        AppDataSize = 2;
+                        gAppDataSize = 2;
                         AppData[0] = ComplianceTest.DownLinkCounter >> 8;
                         AppData[1] = ComplianceTest.DownLinkCounter;
                         break;
@@ -414,89 +509,6 @@
     }
 }
 
-void LoRaMacStatus_toString(LoRaMacStatus_t s, char* out)
-{
-    switch (s) {
-        case LORAMAC_STATUS_PARAMETER_INVALID:
-            strcpy(out, "PARAMTER_INVALID");
-            break;
-        case LORAMAC_STATUS_BUSY:
-            strcpy(out, "BUSY");
-            break;
-        default:
-            sprintf(out, "<%u>", s);
-            break;
-    }
-}
-
-volatile unsigned sendCnt = 0;
-/*!
- * \brief   Prepares the payload of the frame
- *
- * \retval  [0: frame could be send, 1: error]
- */
-static bool SendFrame( void )
-{
-    char str[48];
-    LoRaMacStatus_t status;
-    McpsReq_t mcpsReq;
-    LoRaMacTxInfo_t txInfo;
-
-    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;
-        mcpsReq.Req.Unconfirmed.fBufferSize = 0;
-        mcpsReq.Req.Unconfirmed.Datarate = LORAWAN_DEFAULT_DATARATE;
-
-        LoRaMacUplinkStatus.Acked = false;
-        LoRaMacUplinkStatus.Port = 0;
-        LoRaMacUplinkStatus.Buffer = NULL;
-        LoRaMacUplinkStatus.BufferSize = 0;
-        SerialDisplayUpdateFrameType( false );
-    } else {
-        LoRaMacUplinkStatus.Acked = false;
-        LoRaMacUplinkStatus.Port = AppPort;
-        LoRaMacUplinkStatus.Buffer = AppData;
-        LoRaMacUplinkStatus.BufferSize = AppDataSize;
-        SerialDisplayUpdateFrameType( IsTxConfirmed );
-
-        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 {
-            mcpsReq.Type = MCPS_CONFIRMED;
-            mcpsReq.Req.Confirmed.fPort = AppPort;
-            mcpsReq.Req.Confirmed.fBuffer = AppData;
-            mcpsReq.Req.Confirmed.fBufferSize = AppDataSize;
-            mcpsReq.Req.Confirmed.NbTrials = 8;
-            mcpsReq.Req.Confirmed.Datarate = LORAWAN_DEFAULT_DATARATE;
-        }
-    }
-
-    sendCnt++;
-    status = LoRaMacMcpsRequest( &mcpsReq );
-    if (status == LORAMAC_STATUS_OK) {
-        vt.SetCursorPos( 44, 1 );
-        vt.printf("%u sendFrame() OK\e[K", sendCnt);
-        SerialDisplayUpdateUplink(
-            LoRaMacUplinkStatus.Acked,
-            LoRaMacUplinkStatus.Datarate,
-            LoRaMacUplinkStatus.UplinkCounter,
-            LoRaMacUplinkStatus.Port,
-            LoRaMacUplinkStatus.Buffer,
-            LoRaMacUplinkStatus.BufferSize
-        );
-        return false;
-    }
-    LoRaMacStatus_toString(status, str);
-    vt.SetCursorPos( 44, 1 );
-    vt.printf("%u sendFrame() %s\e[K", sendCnt, str);
-    return true;
-}
 
 void LoRaMacEventInfoStatus_toString(LoRaMacEventInfoStatus_t s, char* out)
 {
@@ -597,7 +609,7 @@
         char str[48];
         LoRaMacEventInfoStatus_toString(mcpsIndication->Status, str);
         vt.SetCursorPos( 44, 1 );
-        vt.printf("mcpsInd %s", str);
+        vt.printf("mcpsInd %s\e[K", str);
         return;
     }
 
@@ -680,9 +692,9 @@
                             ( mcpsIndication->Buffer[1] == 0x01 ) &&
                             ( mcpsIndication->Buffer[2] == 0x01 ) &&
                             ( mcpsIndication->Buffer[3] == 0x01 ) ) {
-                        IsTxConfirmed = false;
+                        gIsTxConfirmed = false;
                         AppPort = 224;
-                        AppDataSize = 2;
+                        gAppDataSize = 2;
                         ComplianceTest.DownLinkCounter = 0;
                         ComplianceTest.LinkCheck = false;
                         ComplianceTest.DemodMargin = 0;
@@ -703,9 +715,9 @@
                     ComplianceTest.State = mcpsIndication->Buffer[0];
                     switch( ComplianceTest.State ) {
                         case 0: // Check compliance test disable command (ii)
-                            IsTxConfirmed = LORAWAN_CONFIRMED_MSG_ON;
+                            gIsTxConfirmed = LORAWAN_CONFIRMED_MSG_ON;
                             AppPort = LORAWAN_APP_PORT;
-                            AppDataSize = LORAWAN_APP_DATA_SIZE;
+                            gAppDataSize = LORAWAN_APP_DATA_SIZE;
                             ComplianceTest.DownLinkCounter = 0;
                             ComplianceTest.Running = false;
 
@@ -718,21 +730,21 @@
 #endif
                             break;
                         case 1: // (iii, iv)
-                            AppDataSize = 2;
+                            gAppDataSize = 2;
                             break;
                         case 2: // Enable confirmed messages (v)
-                            IsTxConfirmed = true;
+                            gIsTxConfirmed = true;
                             ComplianceTest.State = 1;
                             break;
                         case 3:  // Disable confirmed messages (vi)
-                            IsTxConfirmed = false;
+                            gIsTxConfirmed = false;
                             ComplianceTest.State = 1;
                             break;
                         case 4: // (vii)
-                            AppDataSize = mcpsIndication->BufferSize;
+                            gAppDataSize = mcpsIndication->BufferSize;
 
                             AppData[0] = 4;
-                            for( uint8_t i = 1; i < AppDataSize; i++ ) {
+                            for( uint8_t i = 1; i < gAppDataSize; i++ ) {
                                 AppData[i] = mcpsIndication->Buffer[i] + 1;
                             }
                             break;
@@ -746,9 +758,9 @@
                             MlmeReq_t mlmeReq;
 
                             // Disable TestMode and revert back to normal operation
-                            IsTxConfirmed = LORAWAN_CONFIRMED_MSG_ON;
+                            gIsTxConfirmed = LORAWAN_CONFIRMED_MSG_ON;
                             AppPort = LORAWAN_APP_PORT;
-                            AppDataSize = LORAWAN_APP_DATA_SIZE;
+                            gAppDataSize = LORAWAN_APP_DATA_SIZE;
                             ComplianceTest.DownLinkCounter = 0;
                             ComplianceTest.Running = false;
 
@@ -852,8 +864,17 @@
 
 void foo()
 {
+    float R, temp;
+    uint16_t u16;
+    
     vt.SetCursorPos( 43, 1 );
-    vt.printf("%u d9:%u (%04x %04x %04x %04x)\e[K", DeviceState, d8.read(), a1.read_u16(), a2.read_u16(), a3.read_u16(), a4.read_u16());
+    
+    u16 = a3.read_u16() >> 4;
+    R = 4096.0 / u16 - 1.0;
+    R = R0 * R;
+    temp = 1.0/(log(R/R0)/B+1/298.15)-273.15;
+    
+    vt.printf("%u d9:%u (%03x %03x %03x %03x) %.2fC\e[K\r\n", DeviceState, d8.read() >> 4, a1.read_u16() >> 4, a2.read_u16() >> 4, a3.read_u16() >> 4, a4.read_u16(), temp);
 }
 
 const LoRaMacPrimitives_t LoRaMacPrimitives = {
@@ -1018,7 +1039,7 @@
                 SerialDisplayUpdateDonwlinkRxData( false );
                 PrepareTxFrame( AppPort );
 
-                SendFrame( );
+                SendFrame(gAppDataSize, gIsTxConfirmed);
 
                 DeviceState = DEVICE_STATE_SLEEP;
                 break;