Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: mbed LoRaWAN-lib SX1276Lib
Diff: app/main.cpp
- 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 *)¤t_time);
+ break;
+ }
+ case MESSAGE_TYPE_SHORT_TEST:
+ {
+ AppDataSize = 14;
+ short_test_result(AppData, (uint8_t *)¤t_time, (uint8_t *)&next_stest, s_measurements);
+ break;
+ }
+ case MESSAGE_TYPE_LONG_TEST:
+ {
+ AppDataSize = 32;
+ long_test_result(AppData, (uint8_t *)¤t_time, (uint8_t *)&next_ltest, l_measurements);
+ break;
+ }
+ default:
+ {
+ AppDataSize = 5;
+ heartbeat_message(AppData, (uint8_t *)¤t_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: