Hex-current-measurements
Dependencies: mbed LoRaWAN-lib SX1276Lib
Diff: app/main.cpp
- Revision:
- 10:9a4efdd07a77
- Parent:
- 9:ee9dcbb9708d
- Child:
- 11:9e35ddff7ed8
diff -r ee9dcbb9708d -r 9a4efdd07a77 app/main.cpp --- 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: