Hex-current-measurements

Dependencies:   mbed LoRaWAN-lib SX1276Lib

Revision:
10:9a4efdd07a77
Parent:
9:ee9dcbb9708d
Child:
11:9e35ddff7ed8
--- a/app/main.cpp	Mon Apr 24 13:38:31 2017 +0000
+++ b/app/main.cpp	Fri Dec 07 13:25:30 2018 +0000
@@ -83,13 +83,7 @@
 /*!
  * User application data buffer size
  */
-#if ( LORAWAN_CONFIRMED_MSG_ON == 1 )
-#define LORAWAN_APP_DATA_SIZE                       6
-
-#else
-#define LORAWAN_APP_DATA_SIZE                       1
-
-#endif
+#define LORAWAN_APP_DATA_SIZE                       41
 
 static uint8_t DevEui[] = LORAWAN_DEVICE_EUI;
 static uint8_t AppEui[] = LORAWAN_APPLICATION_EUI;
@@ -143,6 +137,54 @@
 static TimerEvent_t TxNextPacketTimer;
 
 /*!
+ * SOME APPLICATION PARAMETERS
+ */
+
+DigitalOut myled(D7);
+
+DigitalOut relayPin(D6);
+AnalogIn BAT_PIN(A1);
+AnalogIn LIGHT_1_PIN(A2);
+AnalogIn LIGHT_2_PIN(A5);
+AnalogIn VCE_PIN(PB_1);
+
+unsigned int time_window = 5; // Default 3600 seconds in an hour
+unsigned long long_interval = 604800; // Default 31557600 seconds in a year
+unsigned int hb_interval = 3600; // Default 86400 seconds in a day
+unsigned long test_interval = 86400; // Default 2592000 seconds in a month
+
+time_t next_stest;
+time_t next_ltest;
+
+uint8_t hb_data[5];
+uint8_t short_tdata[14];
+uint8_t long_tdata[41];
+
+uint8_t received_data[28];
+
+uint8_t *data;
+uint8_t data_len;
+
+bool running_test;
+bool joining;
+bool received_downlink;
+
+time_t current_time;
+
+unsigned long last_measurement;
+unsigned long last_hb;
+unsigned long test_start;
+
+int measureCount;
+uint8_t s_measurements[4];
+uint8_t l_measurements[22];
+uint8_t *measurements;
+int available_slots = 9;
+
+unsigned long measurement_interval;
+unsigned long test_duration;
+
+/*!
  * Specifies the state of the application LED
  */
 static bool AppLedStateOn = false;
@@ -177,6 +219,13 @@
     DEVICE_STATE_SLEEP
 }DeviceState;
 
+static enum eMessageType
+{
+    MESSAGE_TYPE_HB,
+    MESSAGE_TYPE_SHORT_TEST,
+    MESSAGE_TYPE_LONG_TEST
+}MessageType;
+
 /*!
  * LoRaWAN compliance tests support data
  */
@@ -281,6 +330,36 @@
     }
 }
 
+void flash_builtin() {
+    myled = 1;   // turn the LED on (HIGH is the voltage level)
+    wait(2);                       // wait for a second
+    myled = 0;    // turn the LED off by making the voltage LOW
+    wait(1);                       // wait for a second
+}
+
+// ****************************    COMMUNICATION PACKET DEFINITION METHODS   ********************************   //
+
+void heartbeat_message(uint8_t *hb_data, uint8_t *current_date) {
+    hb_data[0] = 0xD2;
+    memcpy(hb_data+1, current_date, 4);
+}
+
+void short_test_result(uint8_t *short_tdata, uint8_t *test_start_date, uint8_t *next_test_date, uint8_t *measurements) {
+    short_tdata[0] = 0xD7;
+    memcpy(short_tdata+1, test_start_date, 4);
+    memcpy(short_tdata+5, next_test_date, 4);
+    short_tdata[9] = (uint8_t) 2;
+    memcpy(short_tdata+10, measurements, 4);
+}
+
+void long_test_result(uint8_t *long_tdata, uint8_t *test_start_date, uint8_t *next_test_date, uint8_t *measurements) {
+    long_tdata[0] = 0xD8;
+    memcpy(long_tdata+1, test_start_date, 4);
+    memcpy(long_tdata+5, next_test_date, 4);
+    long_tdata[9] = (uint8_t) 2;
+    memcpy(long_tdata+10, measurements, 31);
+}
+
 /*!
  * \brief   Prepares the payload of the frame
  */
@@ -289,15 +368,33 @@
     switch( port )
     {
     case 15:
-        {
-            AppData[0] = AppLedStateOn;
-            if( IsTxConfirmed == true )
+        {   
+            switch ( MessageType ) 
             {
-                AppData[1] = LoRaMacDownlinkStatus.DownlinkCounter >> 8;
-                AppData[2] = LoRaMacDownlinkStatus.DownlinkCounter;
-                AppData[3] = LoRaMacDownlinkStatus.Rssi >> 8;
-                AppData[4] = LoRaMacDownlinkStatus.Rssi;
-                AppData[5] = LoRaMacDownlinkStatus.Snr;
+                case MESSAGE_TYPE_HB:
+                {
+                    AppDataSize = 5;
+                    heartbeat_message(AppData, (uint8_t *)&current_time);
+                    break;
+                }
+                case MESSAGE_TYPE_SHORT_TEST:
+                {
+                    AppDataSize = 14;
+                    short_test_result(AppData, (uint8_t *)&current_time, (uint8_t *)&next_stest, s_measurements);
+                    break;
+                }
+                case MESSAGE_TYPE_LONG_TEST:
+                {
+                    AppDataSize = 32;
+                    long_test_result(AppData, (uint8_t *)&current_time, (uint8_t *)&next_ltest, l_measurements);
+                    break;
+                }
+                default:
+                {
+                    AppDataSize = 5;
+                    heartbeat_message(AppData, (uint8_t *)&current_time);
+                    break;
+                }
             }
         }
         break;
@@ -726,6 +823,12 @@
                 // Status is OK, node has joined the network
                 IsNetworkJoinedStatusUpdate = true;
                 DeviceState = DEVICE_STATE_SEND;
+                
+            
+                MessageType = MESSAGE_TYPE_HB;
+                joining = false;
+                next_stest = current_time + 5;
+                next_ltest = current_time + long_interval;
             }
             else
             {
@@ -756,6 +859,84 @@
     UplinkStatusUpdated = true;
 }
 
+
+// ****************************    TEST METHODS   ********************************   //
+
+int takeMeasurement(uint8_t *measurements, int count) {
+  // This method should only run for long tests
+  int battery_reading = BAT_PIN.read()*1000;
+  int vce_reading = VCE_PIN.read()*1000;
+  int light_1_reading = LIGHT_1_PIN.read()*1000 - vce_reading;
+  int light_2_reading = LIGHT_2_PIN.read()*1000 - vce_reading;
+
+  int index = count;
+  
+  measurements[(uint8_t)index] = (uint8_t) (battery_reading/10);
+  measurements[(uint8_t)index+10] = (uint8_t) light_1_reading;
+  measurements[(uint8_t)index+20] = (uint8_t) light_2_reading;
+  return index+1;
+}
+
+void startTest(uint8_t *measurements) {
+  // Signal that test is running
+    flash_builtin();
+    flash_builtin();
+    
+    // Determine test length & measurement interval
+    switch (MessageType)
+    {
+        case MESSAGE_TYPE_SHORT_TEST:
+            test_duration = 30;
+            // set interval to twice the test length so that it never happens
+            measurement_interval = 2*test_duration;
+            break;
+        case MESSAGE_TYPE_LONG_TEST:
+            test_duration = 5400;
+            // interval is divided by two longer than available measurement 
+            // slots so that it completes before the end of the test
+            measurement_interval = test_duration/(available_slots + 2);
+            break;
+        default:
+            test_duration = 0;
+            break;
+    }
+    
+    // Measure voltage preval
+    measurements[0] = (uint8_t) (BAT_PIN.read()*1000)/10;
+
+    // Set measurement count to 1
+    measureCount = 1;
+    
+    // Start test
+    relayPin = 1;
+}
+
+void endTest(uint8_t *measurements) {
+    // Measure endvals
+    int battery_reading = BAT_PIN.read()*1000;
+    int vce_reading = VCE_PIN.read()*1000;
+    int light_1_reading = LIGHT_1_PIN.read()*1000 - vce_reading;
+    int light_2_reading = LIGHT_2_PIN.read()*1000 - vce_reading;
+    
+    switch (MessageType)
+    {
+        case MESSAGE_TYPE_SHORT_TEST:
+            measurements[1] = (uint8_t) (battery_reading/10);
+            measurements[2] = (uint8_t) light_1_reading;
+            measurements[3] = (uint8_t) light_2_reading;
+            break;
+        default:
+            measurements[10] = (uint8_t) (battery_reading/10);
+            measurements[20] = (uint8_t) light_1_reading;
+            measurements[30] = (uint8_t) light_2_reading;
+            break;
+    }
+    
+    // End test
+    relayPin = 0;
+}
+
+
 /**
  * Main application entry point.
  */
@@ -780,9 +961,25 @@
 #endif
 
     DeviceState = DEVICE_STATE_INIT;
+    set_time(1514764800);
+    relayPin = 0;
+    
+    flash_builtin();
+    flash_builtin();
+    flash_builtin();
+    flash_builtin();
+    
+    running_test = false;
+    joining = true;
+    received_downlink = false;
+    time_t start_time = time(NULL);
+  
+    last_hb = start_time;
+    last_measurement = start_time;
 
     while( 1 )
     {
+        current_time = time(NULL);
         SerialRxProcess( );
         if( IsNetworkJoinedStatusUpdate == true )
         {
@@ -943,11 +1140,90 @@
             }
             case DEVICE_STATE_CYCLE:
             {
-                DeviceState = DEVICE_STATE_SLEEP;
+                // DeviceState = DEVICE_STATE_SLEEP;
 
                 // Schedule next packet transmission
-                TimerSetValue( &TxNextPacketTimer, TxDutyCycleTime );
-                TimerStart( &TxNextPacketTimer );
+                // TimerSetValue( &TxNextPacketTimer, TxDutyCycleTime );
+                // TimerStart( &TxNextPacketTimer );
+                
+                
+                
+                // Is a test is running
+                if (running_test) {
+                  // If it is 
+                  //check if it's time to take the next interval measurement
+                  if (current_time - last_measurement >= measurement_interval) {
+                    if (measureCount <= available_slots) {
+                      measureCount = takeMeasurement(measurements, measureCount);
+                    }
+                    last_measurement = current_time;
+                  }
+              
+                  //check if it's time to end the test
+                  if (current_time - test_start >= test_duration) {
+                    endTest(measurements);
+                    // sendResult(measurements, ttype);
+                    DeviceState = DEVICE_STATE_SEND;
+                    last_hb = current_time;
+              
+                    // Set the times for the next tests
+                    switch ( MessageType )
+                    {
+                        case MESSAGE_TYPE_SHORT_TEST:
+                        {
+                            next_stest = test_start + test_interval;
+                            break;
+                        }
+                        default:
+                        {
+                            // If long test, reset both test types, 
+                            // to prevent two tests at the same time
+                            next_stest = test_start + test_interval;
+                            next_ltest = test_start + long_interval;
+                            break;
+                        }  
+                    }
+                    
+                    running_test = false;
+                  }
+                } else {
+                  // If it isn't
+                  
+                  // check if downlink action is required
+            
+                  //if (received_downlink == true) {
+                  //  dl_handler(received_data);
+                  //}
+                  
+                  //check if it's time to run a test
+                  if (current_time >= next_stest || current_time >= next_ltest) {
+              
+                    // Check what kind of test to run
+                    if (current_time >= next_ltest) {
+                      MessageType = MESSAGE_TYPE_LONG_TEST;
+                      measurements = l_measurements;
+                    } else {
+                      MessageType = MESSAGE_TYPE_SHORT_TEST;
+                      measurements = s_measurements;
+                    }
+            
+                    startTest(measurements);
+                    
+                    running_test = true;
+                    test_start = current_time;
+                    last_measurement = current_time;
+              
+                    
+                  //check if it's time for a heartbeat
+                  } else if (current_time - last_hb >= hb_interval) { 
+                    // sendHb();
+                    DeviceState = DEVICE_STATE_SEND;
+                    MessageType = MESSAGE_TYPE_HB;
+                    last_hb = current_time;
+                  }
+                }
+                
+                
                 break;
             }
             case DEVICE_STATE_SLEEP: