work1

Dependencies:   mbed MAX44009 mbed-os Si7021

Committer:
danaeb
Date:
Thu May 28 07:31:51 2020 +0000
Revision:
2:25f27478fdf9
Parent:
1:3656b45f17a8
work

Who changed what in which revision?

UserRevisionLine numberNew contents of line
danaeb 0:d3e390d62607 1 #include "mbed.h"
danaeb 0:d3e390d62607 2 #include "mbed_mktime.h"
danaeb 0:d3e390d62607 3 #include "rtc_api_hal.h"
danaeb 0:d3e390d62607 4 #include "tools.h"
danaeb 0:d3e390d62607 5 #include "AppMain.h"
danaeb 0:d3e390d62607 6 #include "AppLora.h"
danaeb 0:d3e390d62607 7 #include "Button.h"
danaeb 0:d3e390d62607 8 #include "LedBlinker.h"
danaeb 0:d3e390d62607 9 //#include "SensorTag.h"
danaeb 0:d3e390d62607 10 #include "Sensor.h"
danaeb 0:d3e390d62607 11 #include "SensorManager.h"
danaeb 0:d3e390d62607 12 #include "CommandSample.h"
danaeb 0:d3e390d62607 13 #include "CommandSampleSelector.h"
danaeb 0:d3e390d62607 14 #include "CommandSampleBoard.h"
danaeb 0:d3e390d62607 15 #include "AppCommand.h"
danaeb 0:d3e390d62607 16 //#include "Latch.h"
danaeb 0:d3e390d62607 17 #include "MemoryDeviceEeprom.h"
danaeb 0:d3e390d62607 18 #include "Calendar.h"
danaeb 0:d3e390d62607 19 #include "mbed-trace/mbed_trace.h"
danaeb 0:d3e390d62607 20 #include "board/SensorBoard.h"
danaeb 0:d3e390d62607 21 #include "board/PowerManager.h"
danaeb 0:d3e390d62607 22 #include "rtc.h"
danaeb 0:d3e390d62607 23 #include "Si7021.h"
danaeb 0:d3e390d62607 24 #include "ProfileManager.h"
danaeb 0:d3e390d62607 25 #define MS_PER_SEC 1000
danaeb 0:d3e390d62607 26 #define MINUTES_PER_DAY 1440
danaeb 0:d3e390d62607 27
danaeb 0:d3e390d62607 28 #define JOIN_TRIES 3
danaeb 0:d3e390d62607 29
danaeb 0:d3e390d62607 30 #define LED_RUN_PERIOD 1000
danaeb 0:d3e390d62607 31 #define LED_RUN_COUNT 2
danaeb 0:d3e390d62607 32
danaeb 0:d3e390d62607 33 // no need to define join failed because
danaeb 0:d3e390d62607 34 // after all join tries failed the device go in stop mode
danaeb 0:d3e390d62607 35 // U
danaeb 0:d3e390d62607 36 // and advertise it
danaeb 0:d3e390d62607 37 //#define LED_JOIN_FAILED_PERIOD 1000
danaeb 0:d3e390d62607 38 //#define LED_JOIN_FAILED_COUNT 3
danaeb 0:d3e390d62607 39 //
danaeb 0:d3e390d62607 40 #define SENSOR_GROUP_MAIN 0x1
danaeb 0:d3e390d62607 41 #define SENSOR_GROUP_ALTERNATE 0x2
danaeb 0:d3e390d62607 42
danaeb 0:d3e390d62607 43 #define LED_JOIN_JOINING_PERIOD 100
danaeb 0:d3e390d62607 44 #define JOIN_RETRY_DELAY_MS 3000
danaeb 0:d3e390d62607 45
danaeb 0:d3e390d62607 46 #define LED_STOP_PERIOD 1000
danaeb 0:d3e390d62607 47 #define LED_STOP_COUNT 5
danaeb 0:d3e390d62607 48 #define COMMAND_TIMESTAMP_PORT 0x80
danaeb 0:d3e390d62607 49
danaeb 0:d3e390d62607 50 #define RUN_MODE_STANDARD 0x01
danaeb 0:d3e390d62607 51 #define RUN_MODE_TEST 0x02
danaeb 0:d3e390d62607 52 #define RUN_MODE_PRODUCTION_TEST 0x03
danaeb 0:d3e390d62607 53
danaeb 0:d3e390d62607 54 #ifdef MBED_CONF_APP_RUN_MODE
danaeb 0:d3e390d62607 55 #endif
danaeb 0:d3e390d62607 56 // TEST
danaeb 0:d3e390d62607 57 #if MBED_CONF_APP_RUN_MODE == RUN_MODE_STANDARD
danaeb 0:d3e390d62607 58 #define SAMPLING_PERIOD 5
danaeb 0:d3e390d62607 59 #define NUMBER_OF_SAMPLE_BEFORE_SEND 1
danaeb 0:d3e390d62607 60 #define NUMBER_OF_TRANSMIT_BEFORE_ALERNATE 1
danaeb 0:d3e390d62607 61 #elif MBED_CONF_APP_RUN_MODE == RUN_MODE_PRODUCTION_TEST
danaeb 0:d3e390d62607 62 #define SKIP_JOIN
danaeb 0:d3e390d62607 63 #define SAMPLING_PERIOD 1
danaeb 0:d3e390d62607 64 #define NUMBER_OF_SAMPLE_BEFORE_SEND 255
danaeb 0:d3e390d62607 65 #define NUMBER_OF_TRANSMIT_BEFORE_ALERNATE 1
danaeb 0:d3e390d62607 66 #elif MBED_CONF_APP_RUN_MODE == RUN_MODE_TEST
danaeb 0:d3e390d62607 67 #define SAMPLING_PERIOD 2
danaeb 0:d3e390d62607 68 #define NUMBER_OF_SAMPLE_BEFORE_SEND 1
danaeb 0:d3e390d62607 69 #define NUMBER_OF_TRANSMIT_BEFORE_ALERNATE 1
danaeb 0:d3e390d62607 70 #endif
danaeb 0:d3e390d62607 71 #define MAX_SEND_DELAY (SAMPLING_PERIOD*60-15)
danaeb 0:d3e390d62607 72
danaeb 0:d3e390d62607 73 #define SOFTWARE_WATCHDOG_TIMEOUT 12
danaeb 0:d3e390d62607 74
danaeb 0:d3e390d62607 75
danaeb 0:d3e390d62607 76 #define CALENDAR_CONFIGURATION_SIZE 1 // to save the start time offset
danaeb 0:d3e390d62607 77 #define CALENDAR_DAY_COUNT 32
danaeb 0:d3e390d62607 78 #define CALENDAR_TIME_SLOT_SIZE 5 // in minutes
danaeb 0:d3e390d62607 79 #define CALENDAR_TIME_SLOT_PER_DAY ((MINUTES_PER_DAY) / (CALENDAR_TIME_SLOT_SIZE))
danaeb 0:d3e390d62607 80
danaeb 0:d3e390d62607 81 #define CALENDAR_BIT_COUNT ((CALENDAR_TIME_SLOT_PER_DAY)*(CALENDAR_DAY_COUNT) + \
danaeb 0:d3e390d62607 82 CALENDAR_CONFIGURATION_SIZE*8)
danaeb 0:d3e390d62607 83
danaeb 0:d3e390d62607 84 // +7 for ceiling
danaeb 0:d3e390d62607 85 #define CALENDAR_BYTES_COUNT ((CALENDAR_BIT_COUNT+7)/8)
danaeb 0:d3e390d62607 86
danaeb 0:d3e390d62607 87
danaeb 0:d3e390d62607 88 #define LATCH_TRIGGER_VOLTAGE 12000 // 12 volt
danaeb 0:d3e390d62607 89 #define TRACE_GROUP "sm"
danaeb 0:d3e390d62607 90
danaeb 0:d3e390d62607 91
danaeb 0:d3e390d62607 92 using namespace events;
danaeb 0:d3e390d62607 93 using namespace liboo;
danaeb 0:d3e390d62607 94
danaeb 0:d3e390d62607 95 // TODO Too much code in this modules, it will need some refactoring
danaeb 0:d3e390d62607 96
danaeb 0:d3e390d62607 97
danaeb 0:d3e390d62607 98 Sensor *AppMain::_sensor_array[CONFIG_SENSOR_COUNT] = {0};
danaeb 0:d3e390d62607 99 SensorManager *AppMain::_sensor_manager = NULL;
danaeb 0:d3e390d62607 100 EventQueue *AppMain::_queue = NULL;
danaeb 0:d3e390d62607 101 LedBlinker *AppMain::_led_blinker = NULL;
danaeb 0:d3e390d62607 102 Button *AppMain::_button = NULL;
danaeb 0:d3e390d62607 103 //Calendar *AppMain::_calendar = NULL;
danaeb 0:d3e390d62607 104 //MemoryDeviceEeprom *AppMain::_memory_device_calendar = NULL;
danaeb 0:d3e390d62607 105 //Latch *AppMain::_latch = NULL;
danaeb 0:d3e390d62607 106
danaeb 0:d3e390d62607 107 I2C i2c(I2C_SDA, I2C_SCL);
danaeb 0:d3e390d62607 108 SensorData AppMain::_sensor_data;
danaeb 0:d3e390d62607 109
danaeb 0:d3e390d62607 110 AppMain::GLOBAL_STATE AppMain::_global_state;
danaeb 0:d3e390d62607 111 AppMain::RUN_STATE AppMain::_run_state;
danaeb 0:d3e390d62607 112
danaeb 0:d3e390d62607 113 u32 AppMain::_daily_send_s;
danaeb 0:d3e390d62607 114 u8 AppMain::_remaining_join_tries;
danaeb 0:d3e390d62607 115 u8 AppMain::_remaining_sample_before_send;
danaeb 0:d3e390d62607 116 u8 AppMain::_transmit_count_before_alternate;
danaeb 0:d3e390d62607 117 u8 AppMain::_send_delay;
danaeb 0:d3e390d62607 118 u8 AppMain::_history_size;
danaeb 0:d3e390d62607 119 //bool AppMain::_forced_timestamp;
danaeb 0:d3e390d62607 120 //bool AppMain::_next_frame_timestamped;
danaeb 0:d3e390d62607 121
danaeb 0:d3e390d62607 122 // buffer for uplink commands
danaeb 0:d3e390d62607 123 u8 AppMain::_command_payload[COMMAND_PAYLOAD_SIZE];
danaeb 0:d3e390d62607 124 char AppMain::_time_buffer[24];
danaeb 0:d3e390d62607 125
danaeb 0:d3e390d62607 126 u8 AppMain::_software_watchdog_time;
danaeb 0:d3e390d62607 127 bool AppMain::_software_watchdog_is_enable;
danaeb 0:d3e390d62607 128
danaeb 0:d3e390d62607 129 void AppMain::_software_watchdog_enable(){
danaeb 0:d3e390d62607 130 _software_watchdog_reset();
danaeb 0:d3e390d62607 131 _software_watchdog_is_enable = true;
danaeb 0:d3e390d62607 132 }
danaeb 0:d3e390d62607 133
danaeb 0:d3e390d62607 134 void AppMain::_software_watchdog_disable(){
danaeb 0:d3e390d62607 135 _software_watchdog_is_enable = false;
danaeb 0:d3e390d62607 136
danaeb 0:d3e390d62607 137 }
danaeb 0:d3e390d62607 138
danaeb 0:d3e390d62607 139 void AppMain::_software_watchdog_reset(){
danaeb 0:d3e390d62607 140 _software_watchdog_time = 0;
danaeb 0:d3e390d62607 141 }
danaeb 0:d3e390d62607 142
danaeb 0:d3e390d62607 143 void AppMain::_software_watchdog_increment(){
danaeb 0:d3e390d62607 144 if(!_software_watchdog_is_enable){
danaeb 0:d3e390d62607 145 return;
danaeb 0:d3e390d62607 146 }
danaeb 0:d3e390d62607 147 ++_software_watchdog_time;
danaeb 0:d3e390d62607 148 if(_software_watchdog_time >= SOFTWARE_WATCHDOG_TIMEOUT){
danaeb 0:d3e390d62607 149 tr_error("watchdog triggered, the system will restart");
danaeb 0:d3e390d62607 150 NVIC_SystemReset();
danaeb 0:d3e390d62607 151 //mbed_reset();
danaeb 0:d3e390d62607 152 }
danaeb 0:d3e390d62607 153 }
danaeb 0:d3e390d62607 154
danaeb 0:d3e390d62607 155 CommandSample *AppMain::_command_sample_array[COMMAND_COUNT] = {
danaeb 0:d3e390d62607 156 new CommandSampleCapacitive1(),
danaeb 0:d3e390d62607 157 new CommandSampleCapacitive2(),
danaeb 0:d3e390d62607 158 new CommandSampleCapacitive3(),
danaeb 0:d3e390d62607 159 new CommandSampleCapacitive4(),
danaeb 0:d3e390d62607 160 new CommandSampleCapacitive5(),
danaeb 0:d3e390d62607 161 //new CommandSampleTest(),
danaeb 0:d3e390d62607 162 /*
danaeb 0:d3e390d62607 163 new CommandSampleGenericTag1(),
danaeb 0:d3e390d62607 164 new CommandSample1Tag1(),
danaeb 0:d3e390d62607 165 new CommandSample2Tag1(),
danaeb 0:d3e390d62607 166 new CommandSample3Tag1(),
danaeb 0:d3e390d62607 167 new CommandSample4Tag1(),
danaeb 0:d3e390d62607 168 new CommandSample5Tag1(),
danaeb 0:d3e390d62607 169 new CommandSample6Tag1(),
danaeb 0:d3e390d62607 170 new CommandSample7Tag1(),
danaeb 0:d3e390d62607 171 new CommandSampleGenericAlternativeTag1(),
danaeb 0:d3e390d62607 172 new CommandSample1AlternativeTag1(),
danaeb 0:d3e390d62607 173 new CommandSample2AlternativeTag1(),
danaeb 0:d3e390d62607 174 new CommandSample3AlternativeTag1(),
danaeb 0:d3e390d62607 175 new CommandSample4AlternativeTag1(),
danaeb 0:d3e390d62607 176 new CommandSample5AlternativeTag1(),
danaeb 0:d3e390d62607 177 new CommandSample6AlternativeTag1(),
danaeb 0:d3e390d62607 178 new CommandSample7AlternativeTag1(),
danaeb 0:d3e390d62607 179 */
danaeb 0:d3e390d62607 180
danaeb 0:d3e390d62607 181 };
danaeb 0:d3e390d62607 182
danaeb 0:d3e390d62607 183 CommandSampleSelector AppMain::_command_selector(_command_sample_array, COMMAND_COUNT,
danaeb 0:d3e390d62607 184 &_sensor_data);
danaeb 0:d3e390d62607 185
danaeb 0:d3e390d62607 186 void AppMain::set_history_size(u8 history_size){
danaeb 0:d3e390d62607 187 if(history_size < 9){
danaeb 0:d3e390d62607 188 _history_size = history_size;
danaeb 0:d3e390d62607 189 tr_info("setting history size to %d", _history_size);
danaeb 0:d3e390d62607 190 }
danaeb 0:d3e390d62607 191 }
danaeb 0:d3e390d62607 192
danaeb 0:d3e390d62607 193 void AppMain::_minute_elapsed_callback_handler(void){
danaeb 0:d3e390d62607 194 tr_debug("one minute elapsed ");
danaeb 0:d3e390d62607 195
danaeb 0:d3e390d62607 196 Rtc::get_instance()->get_formatted_time(_time_buffer);
danaeb 0:d3e390d62607 197 //_write_time(_time_buffer);
danaeb 0:d3e390d62607 198 tr_info("time: %s", _time_buffer);
danaeb 0:d3e390d62607 199 _software_watchdog_increment();
danaeb 0:d3e390d62607 200 _queue->call(callback(_global_event_handler), EVENT_MINUTE_ELAPSED);
danaeb 0:d3e390d62607 201 }
danaeb 0:d3e390d62607 202
danaeb 0:d3e390d62607 203 void AppMain::_daily_send_callback_handler(void){
danaeb 0:d3e390d62607 204 tr_info("daily callback");
danaeb 0:d3e390d62607 205 Rtc::get_instance()->get_formatted_time(_time_buffer);
danaeb 0:d3e390d62607 206 //_write_time(_time_buffer);
danaeb 0:d3e390d62607 207 tr_debug("time: %s", _time_buffer);
danaeb 0:d3e390d62607 208 _queue->call(callback(_global_event_handler), EVENT_DAILY_SEND);
danaeb 0:d3e390d62607 209 }
danaeb 0:d3e390d62607 210
danaeb 0:d3e390d62607 211 void AppMain::_button_callback_handler(Button::ACTION action){
danaeb 0:d3e390d62607 212 tr_debug("button handler: ");
danaeb 0:d3e390d62607 213 switch(action){
danaeb 0:d3e390d62607 214 case Button::ACTION_SHORT:
danaeb 0:d3e390d62607 215 tr_debug("\tshort");
danaeb 0:d3e390d62607 216 _queue->call(callback(&AppMain::_global_event_handler),
danaeb 0:d3e390d62607 217 AppMain::EVENT_SHORT_PUSH);
danaeb 0:d3e390d62607 218 break;
danaeb 0:d3e390d62607 219 case Button::ACTION_LONG:
danaeb 0:d3e390d62607 220 tr_debug("\tshort");
danaeb 0:d3e390d62607 221 _queue->call(callback(&AppMain::_global_event_handler),
danaeb 0:d3e390d62607 222 AppMain::EVENT_LONG_PUSH);
danaeb 0:d3e390d62607 223 break;
danaeb 0:d3e390d62607 224 }
danaeb 0:d3e390d62607 225 }
danaeb 0:d3e390d62607 226
danaeb 0:d3e390d62607 227
danaeb 0:d3e390d62607 228 void AppMain::_lora_callback_handler(AppLora::EVENT lora_event){
danaeb 0:d3e390d62607 229 switch(lora_event){
danaeb 0:d3e390d62607 230 case AppLora::EVENT_CONNECTED:
danaeb 0:d3e390d62607 231 _global_event_handler(AppMain::EVENT_JOIN_SUCCESS);
danaeb 0:d3e390d62607 232 break;
danaeb 0:d3e390d62607 233 case AppLora::EVENT_DISCONNECTED:
danaeb 0:d3e390d62607 234 _global_event_handler(AppMain::EVENT_DISCONNECTED);
danaeb 0:d3e390d62607 235 break;
danaeb 0:d3e390d62607 236 case AppLora::EVENT_CONNECTION_ERROR:
danaeb 0:d3e390d62607 237 _global_event_handler(AppMain::EVENT_CONNECTION_ERROR);
danaeb 0:d3e390d62607 238 break;
danaeb 0:d3e390d62607 239 case AppLora::EVENT_JOIN_FAILURE:
danaeb 0:d3e390d62607 240 _global_event_handler(AppMain::EVENT_JOIN_FAILED);
danaeb 0:d3e390d62607 241 break;
danaeb 0:d3e390d62607 242 case AppLora::EVENT_TX_DONE:
danaeb 0:d3e390d62607 243 _global_event_handler(AppMain::EVENT_TX_DONE);
danaeb 0:d3e390d62607 244 tr_info("tx done");
danaeb 0:d3e390d62607 245 break;
danaeb 0:d3e390d62607 246 case AppLora::EVENT_TX_ERROR:
danaeb 0:d3e390d62607 247 _global_event_handler(AppMain::EVENT_TX_ERROR);
danaeb 0:d3e390d62607 248 tr_err("tx error");
danaeb 0:d3e390d62607 249 break;
danaeb 0:d3e390d62607 250 case AppLora::EVENT_RX_ERROR:
danaeb 0:d3e390d62607 251 _global_event_handler(AppMain::EVENT_RX_ERROR);
danaeb 0:d3e390d62607 252 tr_err("rx error");
danaeb 0:d3e390d62607 253 break;
danaeb 0:d3e390d62607 254 default:
danaeb 0:d3e390d62607 255 // nothing to do for now
danaeb 0:d3e390d62607 256 break;
danaeb 0:d3e390d62607 257 }
danaeb 0:d3e390d62607 258 }
danaeb 0:d3e390d62607 259 void AppMain::_global_event_handler_from_interrupt(AppMain::EVENT event){
danaeb 0:d3e390d62607 260 _queue->call(callback(&AppMain::_global_event_handler), event);
danaeb 0:d3e390d62607 261 }
danaeb 0:d3e390d62607 262
danaeb 0:d3e390d62607 263 void AppMain::_enter_global_state_stop(void){
danaeb 0:d3e390d62607 264 tr_info("enter stop mode");
danaeb 0:d3e390d62607 265 _software_watchdog_disable();
danaeb 0:d3e390d62607 266 _global_state = AppMain::GLOBAL_STATE_STOP;
danaeb 0:d3e390d62607 267 _remaining_join_tries = JOIN_TRIES;
danaeb 0:d3e390d62607 268
danaeb 0:d3e390d62607 269 // sensor manager allocated in create_sensors
danaeb 0:d3e390d62607 270 Rtc *rtc = Rtc::get_instance();
danaeb 0:d3e390d62607 271 // disable minutes callback
danaeb 0:d3e390d62607 272 rtc->disable_alarm(Rtc::ALARM_A);
danaeb 0:d3e390d62607 273 // disable daily callback
danaeb 0:d3e390d62607 274 rtc->disable_alarm(Rtc::ALARM_B);
danaeb 0:d3e390d62607 275 //_calendar->disable();
danaeb 0:d3e390d62607 276 PowerManager *pm= PowerManager::get_instance();
danaeb 0:d3e390d62607 277 pm->sleep_mode();
danaeb 0:d3e390d62607 278
danaeb 0:d3e390d62607 279 _led_blinker->blink(LED_STOP_PERIOD, LED_STOP_COUNT);
danaeb 0:d3e390d62607 280
danaeb 0:d3e390d62607 281
danaeb 0:d3e390d62607 282 // unlock latch
danaeb 0:d3e390d62607 283 }
danaeb 0:d3e390d62607 284
danaeb 0:d3e390d62607 285 void AppMain::_enter_global_state_disconnecting(void){
danaeb 0:d3e390d62607 286 tr_info("enter disconnecting mode");
danaeb 0:d3e390d62607 287 _global_state = AppMain::GLOBAL_STATE_DISCONNECTING;
danaeb 0:d3e390d62607 288 _queue->call(AppLora::disconnect);
danaeb 0:d3e390d62607 289 }
danaeb 0:d3e390d62607 290
danaeb 0:d3e390d62607 291 void AppMain::_enter_global_state_join(void){
danaeb 0:d3e390d62607 292 tr_info("enter join mode");
danaeb 0:d3e390d62607 293 _global_state = AppMain::GLOBAL_STATE_JOIN;
danaeb 0:d3e390d62607 294 _queue->call(AppLora::connect);
danaeb 0:d3e390d62607 295
danaeb 0:d3e390d62607 296 // this call can potentially make the rx window drifting
danaeb 0:d3e390d62607 297 // because the led is blinked through I2C, this takes time
danaeb 0:d3e390d62607 298 //_led_blinker->blink_from_interrupt(LED_JOIN_JOINING_PERIOD,
danaeb 0:d3e390d62607 299 //LedBlinker::COUNT_INFINITE);
danaeb 0:d3e390d62607 300 }
danaeb 0:d3e390d62607 301 #if 0
danaeb 0:d3e390d62607 302 void AppMain::_write_time(char* buffer){
danaeb 0:d3e390d62607 303 time_t time;
danaeb 0:d3e390d62607 304 tm time_info;
danaeb 0:d3e390d62607 305 Rtc &rtc = Rtc::get_instance();
danaeb 0:d3e390d62607 306 time = rtc.get_time();
danaeb 0:d3e390d62607 307 // epoch timestamp the 1 January 2018 0h00
danaeb 0:d3e390d62607 308 time += 1514764800;
danaeb 0:d3e390d62607 309 _rtc_localtime(time, &time_info, RTC_4_YEAR_LEAP_YEAR_SUPPORT);
danaeb 0:d3e390d62607 310 sprintf(buffer, "%d-%d-%d %d:%d:%d", time_info.tm_mday,
danaeb 0:d3e390d62607 311 time_info.tm_mon+1, time_info.tm_year+1900, time_info.tm_hour,
danaeb 0:d3e390d62607 312 time_info.tm_min, time_info.tm_sec);
danaeb 0:d3e390d62607 313 }
danaeb 0:d3e390d62607 314 #endif
danaeb 0:d3e390d62607 315
danaeb 0:d3e390d62607 316 void AppMain::_enter_global_state_run(void){
danaeb 0:d3e390d62607 317 tr_info("enter run mode");
danaeb 0:d3e390d62607 318 _software_watchdog_enable();
danaeb 0:d3e390d62607 319 _global_state = AppMain::GLOBAL_STATE_RUN;
danaeb 0:d3e390d62607 320 _transmit_count_before_alternate = 1; // first packet use alternate
danaeb 0:d3e390d62607 321
danaeb 0:d3e390d62607 322 // random number are recomputed at each restart
danaeb 0:d3e390d62607 323 AppMain::_compute_random_number();
danaeb 0:d3e390d62607 324
danaeb 0:d3e390d62607 325 Rtc *rtc = Rtc::get_instance();
danaeb 0:d3e390d62607 326 time_t time = _daily_send_s;
danaeb 0:d3e390d62607 327 tm time_info;
danaeb 0:d3e390d62607 328 _rtc_localtime(time, &time_info, RTC_4_YEAR_LEAP_YEAR_SUPPORT);
danaeb 0:d3e390d62607 329
danaeb 0:d3e390d62607 330 // schedule sampling, sending and calendar check
danaeb 0:d3e390d62607 331 rtc->set_alarm(Rtc::ALARM_A, Rtc::ALARM_FIELD_UNUSED,
danaeb 0:d3e390d62607 332 Rtc::ALARM_FIELD_UNUSED, 0x00);
danaeb 0:d3e390d62607 333
danaeb 0:d3e390d62607 334
danaeb 0:d3e390d62607 335 tr_info("setting daily send to %d:%d:%d", time_info.tm_hour,
danaeb 0:d3e390d62607 336 time_info.tm_min, time_info.tm_sec);
danaeb 0:d3e390d62607 337 //rtc.set_alarm(Rtc::ALARM_B, Rtc::ALARM_FIELD_UNUSED,
danaeb 0:d3e390d62607 338 //Rtc::ALARM_FIELD_UNUSED, time_info.tm_sec);
danaeb 0:d3e390d62607 339 rtc->set_alarm(Rtc::ALARM_B, time_info.tm_hour,
danaeb 0:d3e390d62607 340 time_info.tm_min, time_info.tm_sec);
danaeb 0:d3e390d62607 341
danaeb 0:d3e390d62607 342 _led_blinker->blink(LED_RUN_PERIOD, LED_RUN_COUNT);
danaeb 0:d3e390d62607 343
danaeb 0:d3e390d62607 344 // when start run mode check calendar
danaeb 0:d3e390d62607 345 // to check the latch is in correct state
danaeb 0:d3e390d62607 346 #if 0
danaeb 0:d3e390d62607 347 tr_debug("enable calendar");
danaeb 0:d3e390d62607 348 //_calendar->enable();
danaeb 0:d3e390d62607 349 tr_debug("checking calendar");
danaeb 0:d3e390d62607 350 //_calendar->check(rtc->get_time());
danaeb 0:d3e390d62607 351 tr_debug("check calendar done");
danaeb 0:d3e390d62607 352 //wait(5);
danaeb 0:d3e390d62607 353 #endif
danaeb 0:d3e390d62607 354 //_forced_timestamp = true;
danaeb 0:d3e390d62607 355
danaeb 0:d3e390d62607 356 // erase all old samples
danaeb 0:d3e390d62607 357 _sensor_data.reset();
danaeb 0:d3e390d62607 358 // send timestamped packet until answer
danaeb 0:d3e390d62607 359 //_forced_timestamp = true;
danaeb 0:d3e390d62607 360
danaeb 0:d3e390d62607 361 // send a first message at boot
danaeb 0:d3e390d62607 362 // It enable to get the next packet size
danaeb 0:d3e390d62607 363 #if 0
danaeb 0:d3e390d62607 364 if(_send_empty_timestamped() < 0){
danaeb 0:d3e390d62607 365 _run_state = AppMain::RUN_STATE_WAIT_SEND_COMPLETE;
danaeb 0:d3e390d62607 366 }
danaeb 0:d3e390d62607 367 else{
danaeb 0:d3e390d62607 368 _run_state = AppMain::RUN_STATE_READY;
danaeb 0:d3e390d62607 369 }
danaeb 0:d3e390d62607 370 #endif
danaeb 0:d3e390d62607 371
danaeb 0:d3e390d62607 372 }
danaeb 0:d3e390d62607 373
danaeb 0:d3e390d62607 374 void AppMain::_global_event_handler(AppMain::EVENT event){
danaeb 0:d3e390d62607 375 tr_debug("global_event_handler");
danaeb 0:d3e390d62607 376 tr_debug("\tglobal_state: %d", _global_state);
danaeb 0:d3e390d62607 377 tr_debug("\tevent : %d", event);
danaeb 0:d3e390d62607 378 switch(_global_state){
danaeb 0:d3e390d62607 379 case GLOBAL_STATE_STOP:
danaeb 0:d3e390d62607 380 if(event == AppMain::EVENT_SHORT_PUSH){
danaeb 0:d3e390d62607 381 _enter_global_state_join();
danaeb 0:d3e390d62607 382 }
danaeb 0:d3e390d62607 383 break;
danaeb 0:d3e390d62607 384 case GLOBAL_STATE_JOIN:
danaeb 0:d3e390d62607 385 if(event == AppMain::EVENT_JOIN_SUCCESS){
danaeb 0:d3e390d62607 386 _led_blinker->stop();
danaeb 0:d3e390d62607 387 _enter_global_state_run();
danaeb 0:d3e390d62607 388 }
danaeb 0:d3e390d62607 389 if(event == AppMain::EVENT_CONNECTION_ERROR ||
danaeb 0:d3e390d62607 390 event == AppMain::EVENT_TX_ERROR ||
danaeb 0:d3e390d62607 391 event == AppMain::EVENT_JOIN_FAILED){
danaeb 0:d3e390d62607 392 --_remaining_join_tries;
danaeb 0:d3e390d62607 393 if(_remaining_join_tries == 0){
danaeb 0:d3e390d62607 394 tr_err("join failed after %d tries", JOIN_TRIES);
danaeb 0:d3e390d62607 395 _enter_global_state_stop();
danaeb 0:d3e390d62607 396 }
danaeb 0:d3e390d62607 397 else{
danaeb 0:d3e390d62607 398 //retry join
danaeb 0:d3e390d62607 399 tr_warn("join failed, retry join in %dms", JOIN_RETRY_DELAY_MS);
danaeb 0:d3e390d62607 400 _led_blinker->stop();
danaeb 0:d3e390d62607 401 //wait_ms(JOIN_RETRY_DELAY_MS);
danaeb 0:d3e390d62607 402 //ThisThread::sleep_for(JOIN_RETRY_DELAY_MS);
danaeb 0:d3e390d62607 403 wait_us(JOIN_RETRY_DELAY_MS*1000);
danaeb 0:d3e390d62607 404 _enter_global_state_join();
danaeb 0:d3e390d62607 405 }
danaeb 0:d3e390d62607 406 }
danaeb 0:d3e390d62607 407
danaeb 0:d3e390d62607 408 break;
danaeb 0:d3e390d62607 409 case GLOBAL_STATE_RUN:
danaeb 0:d3e390d62607 410 if(event == AppMain::EVENT_SHORT_PUSH){
danaeb 0:d3e390d62607 411 _send_empty();
danaeb 0:d3e390d62607 412 //_write_time(_time_buffer);
danaeb 0:d3e390d62607 413 Rtc::get_instance()->get_formatted_time(_time_buffer);
danaeb 0:d3e390d62607 414 tr_info("time: %s", _time_buffer);
danaeb 0:d3e390d62607 415 //Rtc &rtc = Rtc::get_instance();
danaeb 0:d3e390d62607 416 //rtc.set_time(9537861);
danaeb 0:d3e390d62607 417
danaeb 0:d3e390d62607 418 }
danaeb 0:d3e390d62607 419 else if(event == AppMain::EVENT_LONG_PUSH){
danaeb 0:d3e390d62607 420 _enter_global_state_disconnecting();
danaeb 0:d3e390d62607 421 }
danaeb 0:d3e390d62607 422 else{
danaeb 0:d3e390d62607 423 _run_event_handler(event);
danaeb 0:d3e390d62607 424 }
danaeb 0:d3e390d62607 425 break;
danaeb 0:d3e390d62607 426 case GLOBAL_STATE_DISCONNECTING:
danaeb 0:d3e390d62607 427 if(event == AppMain::EVENT_DISCONNECTED){
danaeb 0:d3e390d62607 428 _enter_global_state_stop();
danaeb 0:d3e390d62607 429 }
danaeb 0:d3e390d62607 430 }
danaeb 0:d3e390d62607 431 }
danaeb 0:d3e390d62607 432
danaeb 0:d3e390d62607 433
danaeb 0:d3e390d62607 434 void AppMain::_run_event_handler(AppMain::EVENT event){
danaeb 0:d3e390d62607 435 switch(_run_state){
danaeb 0:d3e390d62607 436 case RUN_STATE_READY:
danaeb 0:d3e390d62607 437 if(event == AppMain::EVENT_MINUTE_ELAPSED){
danaeb 0:d3e390d62607 438 Rtc *rtc = Rtc::get_instance();
danaeb 0:d3e390d62607 439 time_t time = rtc->get_time();
danaeb 0:d3e390d62607 440 tm time_info;
danaeb 0:d3e390d62607 441 _rtc_localtime(time, &time_info, RTC_4_YEAR_LEAP_YEAR_SUPPORT);
danaeb 0:d3e390d62607 442
danaeb 0:d3e390d62607 443 if((time_info.tm_min % SAMPLING_PERIOD) == 0) // if minute is pair
danaeb 0:d3e390d62607 444 {
danaeb 0:d3e390d62607 445 bool is_hourly_send = false;
danaeb 0:d3e390d62607 446 // forbid latch operation to avoid wrong measure or degraded RF
danaeb 0:d3e390d62607 447 // this cannot protect against a latch which is already charging
danaeb 0:d3e390d62607 448 // it will forbid only trigger latch
danaeb 0:d3e390d62607 449 // TODO lock latch
danaeb 0:d3e390d62607 450 _sensor_manager->sample_all();
danaeb 0:d3e390d62607 451 --_remaining_sample_before_send;
danaeb 0:d3e390d62607 452
danaeb 0:d3e390d62607 453 tr_debug("remaining sampling before transmit: %d",
danaeb 0:d3e390d62607 454 _remaining_sample_before_send);
danaeb 0:d3e390d62607 455 if(_remaining_sample_before_send == 0){
danaeb 0:d3e390d62607 456 /*
danaeb 0:d3e390d62607 457 static u8 sample_id = 0;
danaeb 0:d3e390d62607 458 ++sample_id;
danaeb 0:d3e390d62607 459 */
danaeb 0:d3e390d62607 460 _remaining_sample_before_send = NUMBER_OF_SAMPLE_BEFORE_SEND;
danaeb 0:d3e390d62607 461 --_transmit_count_before_alternate;
danaeb 0:d3e390d62607 462 if(_transmit_count_before_alternate == 0){
danaeb 0:d3e390d62607 463 _transmit_count_before_alternate = NUMBER_OF_TRANSMIT_BEFORE_ALERNATE;
danaeb 0:d3e390d62607 464 is_hourly_send = 1;
danaeb 0:d3e390d62607 465 }
danaeb 0:d3e390d62607 466
danaeb 0:d3e390d62607 467 _sensor_manager->record_samples();
danaeb 0:d3e390d62607 468 if(!_sensor_manager->are_all_sensor_disabled()){
danaeb 0:d3e390d62607 469 tr_info(" Scheduling transmit in %d secondes", _send_delay);
danaeb 0:d3e390d62607 470 //_write_time(_time_buffer);
danaeb 0:d3e390d62607 471 Rtc::get_instance()->get_formatted_time(_time_buffer);
danaeb 0:d3e390d62607 472 tr_debug("time: %s", _time_buffer);
danaeb 0:d3e390d62607 473 _queue->call_in(_send_delay*1000,
danaeb 0:d3e390d62607 474 callback(_scheduled_send), is_hourly_send);
danaeb 0:d3e390d62607 475 }
danaeb 0:d3e390d62607 476 }
danaeb 0:d3e390d62607 477 else{
danaeb 0:d3e390d62607 478 // [TODO]unlock latch
danaeb 0:d3e390d62607 479 }
danaeb 0:d3e390d62607 480 //check calendar every minnutes
danaeb 0:d3e390d62607 481 #if 0
danaeb 0:d3e390d62607 482 Rtc *rtc = Rtc::get_instance();
danaeb 0:d3e390d62607 483 u32 time = rtc->get_time();
danaeb 0:d3e390d62607 484 _calendar->check(time);
danaeb 0:d3e390d62607 485 #endif
danaeb 0:d3e390d62607 486 }
danaeb 0:d3e390d62607 487
danaeb 0:d3e390d62607 488 #if MBED_CONF_APP_RUN_MODE == RUN_MODE_PRODUCTION_TEST
danaeb 0:d3e390d62607 489 tr_info("turn on pump");
danaeb 0:d3e390d62607 490 // toggle latch 10s
danaeb 0:d3e390d62607 491 PowerManager *pm= PowerManager::get_instance();
danaeb 0:d3e390d62607 492 pm->lock_and_turn_on_motor();
danaeb 0:d3e390d62607 493 wait_us(10*1000*1000);
danaeb 0:d3e390d62607 494 pm->unlock_and_turn_off_motor();
danaeb 0:d3e390d62607 495 tr_info("turn off pump");
danaeb 0:d3e390d62607 496 #endif
danaeb 0:d3e390d62607 497 }
danaeb 0:d3e390d62607 498 if(event == AppMain::EVENT_DAILY_SEND){
danaeb 0:d3e390d62607 499 // at least one packet is timestamped every days
danaeb 0:d3e390d62607 500 //_next_frame_timestamped = true;
danaeb 0:d3e390d62607 501 if(_sensor_manager->are_all_sensor_disabled()){
danaeb 0:d3e390d62607 502 if(_send_empty() < 0){
danaeb 0:d3e390d62607 503 _run_state = RUN_STATE_WAIT_SEND_COMPLETE;
danaeb 0:d3e390d62607 504 }
danaeb 0:d3e390d62607 505 }
danaeb 0:d3e390d62607 506 }
danaeb 0:d3e390d62607 507 break;
danaeb 0:d3e390d62607 508 case RUN_STATE_WAIT_SEND_COMPLETE:
danaeb 0:d3e390d62607 509 // other event like daily send or event minutes elapsed
danaeb 0:d3e390d62607 510 // doesnt need to be process together because
danaeb 0:d3e390d62607 511 // theses event are generated in two different mode.
danaeb 0:d3e390d62607 512 // One is when sensor are enable the other is when all sensor are disabled
danaeb 0:d3e390d62607 513 if( event == AppMain::EVENT_TX_DONE ||
danaeb 0:d3e390d62607 514 event == AppMain::EVENT_RX_ERROR ||
danaeb 0:d3e390d62607 515 event == AppMain::EVENT_TX_ERROR){
danaeb 0:d3e390d62607 516 // TODO unlock latch
danaeb 0:d3e390d62607 517 _run_state = AppMain::RUN_STATE_READY;
danaeb 0:d3e390d62607 518 }
danaeb 0:d3e390d62607 519 break;
danaeb 0:d3e390d62607 520 }
danaeb 0:d3e390d62607 521 }
danaeb 0:d3e390d62607 522
danaeb 0:d3e390d62607 523 void AppMain::_compute_random_number(void){
danaeb 0:d3e390d62607 524 u32 rand;
danaeb 0:d3e390d62607 525 //value between 0 and 4 which is the number of samples sinces the last
danaeb 0:d3e390d62607 526 //send
danaeb 0:d3e390d62607 527 rand = AppLora::get_random();
danaeb 0:d3e390d62607 528 _remaining_sample_before_send = (rand % NUMBER_OF_SAMPLE_BEFORE_SEND) + 1;
danaeb 0:d3e390d62607 529 //_remaining_sample_before_send = 1;
danaeb 0:d3e390d62607 530 tr_info("random: Transmit in %d sample", _remaining_sample_before_send);
danaeb 0:d3e390d62607 531
danaeb 0:d3e390d62607 532 // delay between the 5th sample and the send action
danaeb 0:d3e390d62607 533 // value between 0 and 90 seconds. The actual range could be 0-120 seconds
danaeb 0:d3e390d62607 534 // but in order to send the data before the next sample 30 secondes are removed.
danaeb 0:d3e390d62607 535 rand = AppLora::get_random();
danaeb 0:d3e390d62607 536 _send_delay = rand % MAX_SEND_DELAY;
danaeb 0:d3e390d62607 537 tr_info("random: Send delay %ds", _send_delay);
danaeb 0:d3e390d62607 538
danaeb 0:d3e390d62607 539 // hours in seconds for the dayli sent
danaeb 0:d3e390d62607 540 // this sending is done only when all sensors are deactivated
danaeb 0:d3e390d62607 541 rand = AppLora::get_random();
danaeb 0:d3e390d62607 542 _daily_send_s = rand % 86400; // 86400 number of seconds in one day
danaeb 0:d3e390d62607 543 tr_info("random: Daily send %lus", _daily_send_s);
danaeb 0:d3e390d62607 544
danaeb 0:d3e390d62607 545 }
danaeb 0:d3e390d62607 546
danaeb 0:d3e390d62607 547 // this function is called only once at start
danaeb 0:d3e390d62607 548 void AppMain::initialize(EventQueue *queue){
danaeb 0:d3e390d62607 549 tr_info("Main initialization");
danaeb 0:d3e390d62607 550 _queue = queue;
danaeb 0:d3e390d62607 551
danaeb 0:d3e390d62607 552 ProfileManager* profile_manager = ProfileManager::get_instance();
danaeb 0:d3e390d62607 553
danaeb 0:d3e390d62607 554 //CommandSample::set_endianness(CommandSample::EndiannessBig);
danaeb 0:d3e390d62607 555
danaeb 0:d3e390d62607 556 AppLora::set_lora_callback(_lora_callback_handler);
danaeb 0:d3e390d62607 557 //wait(0.05);
danaeb 0:d3e390d62607 558 wait_us(50000);
danaeb 0:d3e390d62607 559
danaeb 0:d3e390d62607 560 // sensor manager allocated in create_sensors
danaeb 0:d3e390d62607 561 Rtc *rtc = Rtc::get_instance();
danaeb 0:d3e390d62607 562 rtc->set_alarm_callback(Rtc::ALARM_B, _daily_send_callback_handler);
danaeb 0:d3e390d62607 563 rtc->set_alarm_callback(Rtc::ALARM_A, _minute_elapsed_callback_handler);
danaeb 0:d3e390d62607 564
danaeb 0:d3e390d62607 565 // set default time
danaeb 0:d3e390d62607 566 // set default time to delivery day: 2018/09/12 00:00
danaeb 0:d3e390d62607 567 rtc->set_rtc_time(22032000);
danaeb 0:d3e390d62607 568
danaeb 0:d3e390d62607 569 //pcal_i2c.frequency(100000);
danaeb 0:d3e390d62607 570 //_gpio_exp = new PCAL6416(pcal_i2c, 0x42);
danaeb 0:d3e390d62607 571 _led_blinker = new LedBlinker(AppMain::_queue, LED1);
danaeb 0:d3e390d62607 572 _button = new Button(_led_blinker, USER_BUTTON);
danaeb 0:d3e390d62607 573
danaeb 0:d3e390d62607 574 _history_size = 1;
danaeb 0:d3e390d62607 575 _create_sensors();
danaeb 0:d3e390d62607 576 _button->set_action_callback(_button_callback_handler);
danaeb 0:d3e390d62607 577 // sensor manager allocated in create_sensors
danaeb 0:d3e390d62607 578 //_memory_device_calendar = new MemoryDeviceEeprom(0, CALENDAR_BYTES_COUNT);
danaeb 0:d3e390d62607 579 //_latch = new Latch(LATCH_TRIGGER_VOLTAGE, _gpio_exp);
danaeb 0:d3e390d62607 580 #if 0
danaeb 0:d3e390d62607 581 _calendar = new Calendar(_memory_device_calendar,
danaeb 0:d3e390d62607 582 CALENDAR_DAY_COUNT,
danaeb 0:d3e390d62607 583 CALENDAR_TIME_SLOT_PER_DAY,
danaeb 0:d3e390d62607 584 _trigger_latch);
danaeb 0:d3e390d62607 585 #endif
danaeb 0:d3e390d62607 586 AppCommand::configure(_sensor_manager, NULL /* _calendar */);
danaeb 0:d3e390d62607 587
danaeb 0:d3e390d62607 588 // short wait to charge all capacitor before triggering latch
danaeb 0:d3e390d62607 589 //wait_ms(20);
danaeb 0:d3e390d62607 590 wait_us(20000);
danaeb 0:d3e390d62607 591 //_enter_global_state_stop();
danaeb 0:d3e390d62607 592 #ifdef SKIP_JOIN
danaeb 0:d3e390d62607 593 _enter_global_state_run();
danaeb 0:d3e390d62607 594 #else
danaeb 0:d3e390d62607 595 _enter_global_state_join();
danaeb 0:d3e390d62607 596 #endif
danaeb 0:d3e390d62607 597
danaeb 0:d3e390d62607 598 }
danaeb 0:d3e390d62607 599
danaeb 0:d3e390d62607 600 void AppMain::_trigger_latch(bool sens){
danaeb 0:d3e390d62607 601 if(sens){
danaeb 0:d3e390d62607 602 tr_debug("trigger latch forward");
danaeb 0:d3e390d62607 603 //_latch->trigger(Latch::TRIGGER_SENS_FORWARD);
danaeb 0:d3e390d62607 604 }
danaeb 0:d3e390d62607 605 else{
danaeb 0:d3e390d62607 606 tr_debug("trigger latch reverse");
danaeb 0:d3e390d62607 607 //_latch->trigger(Latch::TRIGGER_SENS_REVERSE);
danaeb 0:d3e390d62607 608 }
danaeb 0:d3e390d62607 609 }
danaeb 0:d3e390d62607 610
danaeb 0:d3e390d62607 611 void AppMain::_create_sensors(void){
danaeb 0:d3e390d62607 612
danaeb 0:d3e390d62607 613 PowerManager *pm= PowerManager::get_instance();
danaeb 0:d3e390d62607 614 pm->run_mode();
danaeb 0:d3e390d62607 615
danaeb 0:d3e390d62607 616 //TPS62740 *tps = TPS62740::get_instance();
danaeb 0:d3e390d62607 617 //tps->set_voltage(TPS62740::V3_0);
danaeb 0:d3e390d62607 618
danaeb 0:d3e390d62607 619 tr_info("initialize sensors");
danaeb 0:d3e390d62607 620 tr_debug("initialize battery");
danaeb 0:d3e390d62607 621 _sensor_array[0] = new SensorBoardBattery(SENSOR_ID_BOARD_BAT, SENSOR_GROUP_MAIN);
danaeb 0:d3e390d62607 622
danaeb 0:d3e390d62607 623 tr_debug("initialize SI7021");
danaeb 0:d3e390d62607 624 Si7021 *si = new Si7021(I2C_SDA, I2C_SCL);
danaeb 0:d3e390d62607 625 bool ping_success = si->check();
danaeb 0:d3e390d62607 626 if(ping_success){
danaeb 0:d3e390d62607 627 tr_debug("SI7021 detected");
danaeb 0:d3e390d62607 628 }
danaeb 0:d3e390d62607 629 else{
danaeb 0:d3e390d62607 630 tr_warn("couldn't communicate with SI7021");
danaeb 0:d3e390d62607 631 }
danaeb 0:d3e390d62607 632
danaeb 0:d3e390d62607 633 _sensor_array[1] = new SensorBoardTempRH(SENSOR_ID_BOARD_TEMPERATURE,
danaeb 0:d3e390d62607 634 SENSOR_GROUP_MAIN, si);
danaeb 0:d3e390d62607 635 _sensor_array[2] = new SensorBoardTempRH(SENSOR_ID_BOARD_HUMIDITY,
danaeb 0:d3e390d62607 636 SENSOR_GROUP_MAIN, si);
danaeb 0:d3e390d62607 637
danaeb 0:d3e390d62607 638 tr_debug("initialize MAX44009");
danaeb 0:d3e390d62607 639 MAX44009 *max44009 = new MAX44009(&i2c, 0x94);
danaeb 0:d3e390d62607 640 _sensor_array[3] = new SensorBoardIllumination(SENSOR_ID_BOARD_ILLUMINATION,
danaeb 0:d3e390d62607 641 SENSOR_GROUP_MAIN, max44009);
danaeb 0:d3e390d62607 642 tr_debug("initialize sensor board 1");
danaeb 0:d3e390d62607 643 _sensor_array[4] = new SensorBoardCapacitive(SENSOR_ID_BOARD_CAPACITIVE_0, SENSOR_GROUP_MAIN);
danaeb 0:d3e390d62607 644 tr_debug("initialize sensor board 2");
danaeb 0:d3e390d62607 645 _sensor_array[5] = new SensorBoardCapacitive(SENSOR_ID_BOARD_CAPACITIVE_1, SENSOR_GROUP_MAIN);
danaeb 0:d3e390d62607 646 tr_debug("initialize sensor board 3");
danaeb 0:d3e390d62607 647 _sensor_array[6] = new SensorBoardCapacitive(SENSOR_ID_BOARD_CAPACITIVE_2, SENSOR_GROUP_MAIN);
danaeb 0:d3e390d62607 648 tr_debug("initialize sensor board 4");
danaeb 0:d3e390d62607 649 _sensor_array[7] = new SensorBoardCapacitive(SENSOR_ID_BOARD_CAPACITIVE_3, SENSOR_GROUP_MAIN);
danaeb 0:d3e390d62607 650
danaeb 0:d3e390d62607 651 //_sensor_array[11] = new SensorImpulse(SENSOR_ID_IMPULSE);
danaeb 0:d3e390d62607 652
danaeb 0:d3e390d62607 653 //_sensor_array[11] = new SensorImpulse(SENSOR_ID_IMPULSE);
danaeb 0:d3e390d62607 654 //_sensor_data = new SensorData();
danaeb 0:d3e390d62607 655 //_sensor_manager = new SensorManager(_sensor_data, _sensor_array, 11);
danaeb 0:d3e390d62607 656 tr_debug("initialize sensor manager");
danaeb 0:d3e390d62607 657 _sensor_manager = SensorManager::get_instance();
danaeb 0:d3e390d62607 658 _sensor_manager->initialize(&_sensor_data, _sensor_array, CONFIG_SENSOR_COUNT);
danaeb 0:d3e390d62607 659 tr_info("initialization done");
danaeb 0:d3e390d62607 660 }
danaeb 0:d3e390d62607 661
danaeb 0:d3e390d62607 662 void AppMain::incoming_lora_message_callback(void){
danaeb 0:d3e390d62607 663 u8 app_port;
danaeb 0:d3e390d62607 664 u8 data[256];
danaeb 0:d3e390d62607 665 s16 received_size;
danaeb 0:d3e390d62607 666 u16 data_size = 256;
danaeb 0:d3e390d62607 667
danaeb 0:d3e390d62607 668 //_forced_timestamp = false;
danaeb 0:d3e390d62607 669 received_size = AppLora::get_rx_message(data, data_size, app_port);
danaeb 0:d3e390d62607 670 if(received_size >= 0){
danaeb 0:d3e390d62607 671 AppCommand::process_command(app_port, data, received_size);
danaeb 0:d3e390d62607 672 }
danaeb 0:d3e390d62607 673 // else it an error
danaeb 0:d3e390d62607 674 }
danaeb 0:d3e390d62607 675
danaeb 0:d3e390d62607 676 void AppMain::_scheduled_send(bool is_hourly_send){
danaeb 0:d3e390d62607 677 tr_info("proceed scheduled send");
danaeb 0:d3e390d62607 678 Rtc::get_instance()->get_formatted_time(_time_buffer);
danaeb 0:d3e390d62607 679
danaeb 0:d3e390d62607 680 //_write_time(_time_buffer);
danaeb 0:d3e390d62607 681 tr_debug("time: %s", _time_buffer);
danaeb 0:d3e390d62607 682 if(_send_samples(is_hourly_send) >= 0){
danaeb 0:d3e390d62607 683 _run_state = RUN_STATE_WAIT_SEND_COMPLETE;
danaeb 0:d3e390d62607 684 }
danaeb 0:d3e390d62607 685 }
danaeb 0:d3e390d62607 686
danaeb 0:d3e390d62607 687 s8 AppMain::_send_samples(bool is_hourly_send){
danaeb 0:d3e390d62607 688 CommandSample *selected_command;
danaeb 0:d3e390d62607 689 //command_field_t field;
danaeb 0:d3e390d62607 690 u32 timestamp;
danaeb 0:d3e390d62607 691 s16 retcode;
danaeb 0:d3e390d62607 692 u8 max_lora_payload;
danaeb 0:d3e390d62607 693 u8 command_payload_size = 0;
danaeb 0:d3e390d62607 694 u8 command_port = 0;
danaeb 0:d3e390d62607 695 //u8 history_size = _history_size;
danaeb 0:d3e390d62607 696 u8 history_size;
danaeb 0:d3e390d62607 697 u8 command_group = SENSOR_GROUP_MAIN;
danaeb 0:d3e390d62607 698 //bool _add_timestamp = false;
danaeb 0:d3e390d62607 699
danaeb 0:d3e390d62607 700 // select if the frame must be timestamped
danaeb 0:d3e390d62607 701 // not generic
danaeb 0:d3e390d62607 702 //if(_next_frame_timestamped || _forced_timestamp){
danaeb 0:d3e390d62607 703 //_add_timestamp = true;
danaeb 0:d3e390d62607 704 //}
danaeb 0:d3e390d62607 705
danaeb 0:d3e390d62607 706 // not generic
danaeb 0:d3e390d62607 707 if(is_hourly_send){
danaeb 0:d3e390d62607 708 // do nothing for now
danaeb 0:d3e390d62607 709 //history_size = _history_size;
danaeb 0:d3e390d62607 710 history_size = 1;
danaeb 0:d3e390d62607 711 command_group = SENSOR_GROUP_MAIN;
danaeb 0:d3e390d62607 712 }
danaeb 0:d3e390d62607 713 else {
danaeb 0:d3e390d62607 714 history_size = _history_size;
danaeb 0:d3e390d62607 715 }
danaeb 0:d3e390d62607 716 // get mask, it tells what are the sensor used which have set values
danaeb 0:d3e390d62607 717 // in memory for a given history size
danaeb 0:d3e390d62607 718
danaeb 0:d3e390d62607 719 //_command_selector.compute_requiered_field(&_sensor_data, history_size, &field);
danaeb 0:d3e390d62607 720
danaeb 0:d3e390d62607 721 #if 0
danaeb 0:d3e390d62607 722 if(!is_hourly_send){
danaeb 0:d3e390d62607 723 //these value are only set one time by hours
danaeb 0:d3e390d62607 724 field.battery = 0;
danaeb 0:d3e390d62607 725 field.board_temperature = 0;
danaeb 0:d3e390d62607 726 field.board_humidity = 0;
danaeb 0:d3e390d62607 727 }
danaeb 0:d3e390d62607 728 #endif
danaeb 0:d3e390d62607 729 /*
danaeb 0:d3e390d62607 730 else{
danaeb 0:d3e390d62607 731 // it is the hourly send
danaeb 0:d3e390d62607 732 // do not use history
danaeb 0:d3e390d62607 733 history_size = 1;
danaeb 0:d3e390d62607 734 }
danaeb 0:d3e390d62607 735 */
danaeb 0:d3e390d62607 736
danaeb 0:d3e390d62607 737 //tr_debug("requested fields: 0x%02u", field.bits);
danaeb 0:d3e390d62607 738 // the the mask is used to select the smallest command
danaeb 0:d3e390d62607 739 //selected_command = _command_selector.get_command_sample(&_sensor_data, &field, history_size);
danaeb 0:d3e390d62607 740 selected_command = _command_selector.get_command_sample(history_size, command_group);
danaeb 0:d3e390d62607 741
danaeb 0:d3e390d62607 742
danaeb 0:d3e390d62607 743 bool is_pump_on = AppCommand::get_pump_state();
danaeb 0:d3e390d62607 744 //tr_debug("requested fields: 0x%02u", field.bits);
danaeb 0:d3e390d62607 745 if(selected_command == NULL){
danaeb 0:d3e390d62607 746 tr_err("no matching command");
danaeb 0:d3e390d62607 747 return -1;
danaeb 0:d3e390d62607 748 }
danaeb 0:d3e390d62607 749 else{
danaeb 0:d3e390d62607 750 tr_info("command %d selected", selected_command->get_command_id(false,
danaeb 0:d3e390d62607 751 is_pump_on/*_calendar->is_enable()*/ ));
danaeb 0:d3e390d62607 752 }
danaeb 0:d3e390d62607 753 // get maxlora payload
danaeb 0:d3e390d62607 754 max_lora_payload = AppLora::get_next_transmission_max_size();
danaeb 0:d3e390d62607 755 tr_info("LoRa max packet %d", max_lora_payload);
danaeb 0:d3e390d62607 756
danaeb 0:d3e390d62607 757 // Decrement the size of history while the command is bigger than
danaeb 0:d3e390d62607 758 // the max lora payload size (for the current bandwith and sf)
danaeb 0:d3e390d62607 759
danaeb 0:d3e390d62607 760 // not completly optmised, changing the history size can also
danaeb 0:d3e390d62607 761 // change the command used. Here we keep using the same command
danaeb 0:d3e390d62607 762 tr_info("expected history size %d", history_size);
danaeb 0:d3e390d62607 763 while(selected_command->get_command_size(history_size, false) >
danaeb 0:d3e390d62607 764 max_lora_payload){
danaeb 0:d3e390d62607 765 --history_size;
danaeb 0:d3e390d62607 766
danaeb 0:d3e390d62607 767 // not sure it can happen but just in case
danaeb 0:d3e390d62607 768 // Doesnt try to send packet for history size of 0, this doesnt make sense
danaeb 0:d3e390d62607 769 tr_warn("history size too, using : %d instead", history_size);
danaeb 0:d3e390d62607 770 if(history_size == 0){
danaeb 0:d3e390d62607 771 tr_err("history size: 0\r\n");
danaeb 0:d3e390d62607 772 return -1;
danaeb 0:d3e390d62607 773 }
danaeb 0:d3e390d62607 774 }
danaeb 0:d3e390d62607 775 tr_info("selected history size %d", history_size);
danaeb 0:d3e390d62607 776 //
danaeb 0:d3e390d62607 777 // command id is different if timestamp is used
danaeb 0:d3e390d62607 778 command_port = selected_command->get_command_id(false,
danaeb 0:d3e390d62607 779 is_pump_on /* _calendar->is_enable() */);
danaeb 0:d3e390d62607 780
danaeb 0:d3e390d62607 781 tr_debug("using command port: %d", command_port);
danaeb 0:d3e390d62607 782 // get the timestamp at the last moment
danaeb 0:d3e390d62607 783 Rtc *rtc = Rtc::get_instance();
danaeb 0:d3e390d62607 784 timestamp = rtc->get_time();
danaeb 0:d3e390d62607 785
danaeb 0:d3e390d62607 786 command_payload_size = selected_command->generate_command(
danaeb 0:d3e390d62607 787 &_sensor_data, history_size,
danaeb 0:d3e390d62607 788 false, timestamp,
danaeb 0:d3e390d62607 789 _command_payload, COMMAND_PAYLOAD_SIZE);
danaeb 0:d3e390d62607 790
danaeb 0:d3e390d62607 791 tr_info("payload size : %d", command_payload_size);
danaeb 0:d3e390d62607 792 if(_global_state == GLOBAL_STATE_RUN){
danaeb 0:d3e390d62607 793 tr_info("sending samples");
danaeb 0:d3e390d62607 794 // acknowledged -> false
danaeb 0:d3e390d62607 795 retcode = AppLora::send_message(_command_payload,
danaeb 0:d3e390d62607 796 command_payload_size, command_port, false);
danaeb 0:d3e390d62607 797 if(retcode < 0){
danaeb 0:d3e390d62607 798 tr_err("send error %d\r\n", retcode);
danaeb 0:d3e390d62607 799 return -1;
danaeb 0:d3e390d62607 800 }
danaeb 0:d3e390d62607 801 else{
danaeb 0:d3e390d62607 802 _software_watchdog_reset();
danaeb 0:d3e390d62607 803 //_next_frame_timestamped = false;
danaeb 0:d3e390d62607 804 }
danaeb 0:d3e390d62607 805 }
danaeb 0:d3e390d62607 806 return 0;
danaeb 0:d3e390d62607 807 }
danaeb 0:d3e390d62607 808
danaeb 0:d3e390d62607 809 s8 AppMain::_send_empty(void){
danaeb 0:d3e390d62607 810 u16 command_size;
danaeb 0:d3e390d62607 811 u32 time;
danaeb 0:d3e390d62607 812
danaeb 0:d3e390d62607 813 Rtc *rtc = Rtc::get_instance();
danaeb 0:d3e390d62607 814 time = rtc->get_time();
danaeb 0:d3e390d62607 815 command_size = CommandSample::generate_raw_command(true, time, NULL, 0,
danaeb 0:d3e390d62607 816 _command_payload, COMMAND_PAYLOAD_SIZE);
danaeb 0:d3e390d62607 817 if(_global_state == GLOBAL_STATE_RUN){
danaeb 0:d3e390d62607 818 s16 retcode;
danaeb 0:d3e390d62607 819 tr_info("sending empty frame");
danaeb 0:d3e390d62607 820 // acknowledged -> false
danaeb 0:d3e390d62607 821 retcode = AppLora::send_message(_command_payload, command_size,
danaeb 0:d3e390d62607 822 COMMAND_TIMESTAMP_PORT, false);
danaeb 0:d3e390d62607 823 if(retcode < 0){
danaeb 0:d3e390d62607 824 tr_err("send error %d\r\n", retcode);
danaeb 0:d3e390d62607 825 return -1;
danaeb 0:d3e390d62607 826 }
danaeb 0:d3e390d62607 827 }
danaeb 0:d3e390d62607 828 return 0;
danaeb 0:d3e390d62607 829 }
danaeb 0:d3e390d62607 830
danaeb 0:d3e390d62607 831