Factory firmware for the MultiTech Dotbox (MTDOT-BOX) and EVB (MTDOT-EVB) products.

Dependencies:   NCP5623B GpsParser ISL29011 libmDot-mbed5 MTS-Serial MMA845x DOGS102 MPL3115A2

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers ModeDemo.cpp Source File

ModeDemo.cpp

00001 /* Copyright (c) <2016> <MultiTech Systems>, MIT License
00002  *
00003  * Permission is hereby granted, free of charge, to any person obtaining a copy of this software 
00004  * and associated documentation files (the "Software"), to deal in the Software without restriction, 
00005  * including without limitation the rights to use, copy, modify, merge, publish, distribute, 
00006  * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is 
00007  * furnished to do so, subject to the following conditions:
00008  *
00009  * The above copyright notice and this permission notice shall be included in all copies or 
00010  * substantial portions of the Software.
00011  *
00012  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 
00013  * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 
00014  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 
00015  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 
00016  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00017  */
00018 
00019 #include "ModeDemo.h"
00020 #include "MTSLog.h"
00021 // 10 s, 30 s, 1 min, 5 min, 10 min, 15 min, 30 min 1 hour
00022 const uint32_t ModeDemo::_intervals[] = { 10, 30, 60, 5 * 60, 10 * 60, 15 * 60, 30 * 60 };
00023 
00024 ModeDemo::ModeDemo(DOGS102* lcd, ButtonHandler* buttons, mDot* dot, LoRaHandler* lora, GPSPARSER* gps, SensorHandler* sensors)
00025   : Mode(lcd, buttons, dot, lora, gps, sensors),
00026     _help(lcd),
00027     _sam(lcd),
00028     _interval(0)
00029 {}
00030 
00031 ModeDemo::~ModeDemo() {}
00032 
00033 bool ModeDemo::start() {
00034     bool send = false;
00035     bool no_channel = false;
00036 
00037     // clear any stale signals
00038     osSignalClear(_main_id, buttonSignal | loraSignal);
00039 
00040     _initial_data_rate = _dot->getTxDataRate();
00041     std::vector<uint8_t> s_data = formatSensorData(_data);
00042     for(int i = 0; i < _dot->getMaxDatarate(); i++) { 
00043             _dot->setTxDataRate(i);  
00044             if(s_data.size() < _dot->getMaxPacketLength()) {
00045                 i = _dot->getMaxDatarate();
00046             }
00047     }
00048 
00049     _state = show_help;
00050     displayHelp();
00051 
00052     while (true) {
00053         osEvent e = Thread::signal_wait(0, 250);
00054         if (e.status == osEventSignal) {
00055             if (e.value.signals & buttonSignal) {
00056                 _be = _buttons->getButtonEvent();
00057 
00058                 switch (_be) {
00059                     case ButtonHandler::sw1_press:
00060                         switch (_state) {
00061                             case show_help:
00062                                 _state = sampling;
00063                                 _mode = trigger;
00064                                 _sam.display();
00065                                 _sam.updateSw1("    Send");
00066                                 _sam.updateSw2("Back");
00067                                 break;
00068                             case sampling:
00069                                 if (_mode == trigger) {
00070                                     if (_dot->getNextTxMs() > 0)
00071                                         no_channel = true;
00072                                     else
00073                                         send = true;
00074                                 } else {
00075                                     _interval = (_interval + 1) % (sizeof(_intervals) / sizeof(uint32_t));
00076                                     _sam.updateInterval(_intervals[_interval]);
00077                                 }
00078                                 break;
00079                         }
00080                         break;
00081 
00082                     case ButtonHandler::sw2_press:
00083                         switch (_state) {
00084                             case show_help:
00085                                 _state = sampling;
00086                                 _mode = interval;
00087                                 _send_timer.start();
00088                                 _sam.display();
00089                                 _sam.updateSw1("Interval");
00090                                 _sam.updateSw2("Back");
00091                                 _sam.updateInterval(_intervals[_interval]);
00092                                 break;
00093                             case sampling:
00094                                 no_channel = false;
00095                                 send = false;
00096                                 _send_timer.stop();
00097                                 _send_timer.reset();
00098                                 _state = show_help;
00099                                 displayHelp();
00100                                 break;
00101                         }
00102                         break;
00103                     case ButtonHandler::sw1_hold:
00104                         _send_timer.stop();
00105                         _send_timer.reset();
00106                         if (lora::ChannelPlan::IsPlanFixed(_band)) {
00107                             _dot->setTxDataRate(_initial_data_rate);
00108                         }
00109                         return true;
00110                 }
00111             }
00112             if (e.value.signals & loraSignal) {
00113                 _ls = _lora->getStatus();
00114                 switch (_ls) {
00115                     case LoRaHandler::send_success:
00116                         switch (_state) {
00117                             case sampling:
00118                                 if (_mode == trigger) {
00119                                     _sam.updateSw1("    Send");
00120                                     _sam.updateInfo("                 ");
00121                                 } else {
00122                                     _sam.updateSw1("Interval");
00123                                     _sam.updateInterval(_intervals[_interval]);
00124                                 }
00125                                 _sam.updateSw2("Back");
00126                                 break;
00127                         }
00128                         break;
00129 
00130                     case LoRaHandler::send_failure:
00131                         switch (_state) {
00132                             case sampling:
00133                                 if (_mode == trigger) {
00134                                     _sam.updateSw1("    Send");
00135                                     _sam.updateInfo("                 ");
00136                                 } else {
00137                                     _sam.updateSw1("Interval");
00138                                     _sam.updateInterval(_intervals[_interval]);
00139                                 }
00140                                 _sam.updateSw2("Back");
00141                                 break;
00142                         }
00143                         break;
00144                 }
00145             }
00146         }
00147 
00148         if (_send_timer.read_ms() > _intervals[_interval] * 1000) {
00149             _send_timer.reset();
00150             if (_dot->getNextTxMs() > 0)
00151                 no_channel = true;
00152             else
00153                 send = true;
00154         }
00155         if (no_channel) {
00156             uint32_t t = _dot->getNextTxMs();
00157             if (t > 0) {
00158                 logInfo("next tx %lu ms", t);
00159                 _sam.updateCountdown(t / 1000);
00160             } else {
00161                 no_channel = false;
00162                 send = true;
00163             }
00164         }
00165         if (send) {
00166             s_data.clear();
00167             s_data = formatSensorData(_data);
00168             logInfo("sending data %s %d", _dot->DataRateStr(_dot->getTxDataRate()).c_str(), _dot->getTxPower());
00169             _sam.updateInfo("Sending...");
00170             _sam.updateSw1("        ");
00171             _sam.updateSw2("        ");
00172             send = false;
00173             // we don't care if the server actually gets this packet or not
00174             // we won't retry anyway
00175             _dot->setAck(0);
00176             _dot->setTxWait(false);
00177             _lora->send(s_data);
00178             osDelay(500);
00179         }
00180         if(_state != show_help){
00181             updateSensorData(_data);
00182             _sam.updateAccelerationX(_data.accel_data._x);
00183             _sam.updateAccelerationY(_data.accel_data._y);
00184             _sam.updateAccelerationZ(_data.accel_data._z);
00185             _sam.updatePressure(_data.pressure);
00186             _sam.updateAltitude(_data.altitude);
00187             _sam.updateTemperature(_data.temperature);
00188             _sam.updateLight(_data.light);        
00189         }
00190     }
00191 }
00192 
00193 void ModeDemo::displayHelp() {
00194     _help.display();
00195     _help.updateMode("LoRa Demo");
00196     _help.updateDescription("Select TX Method");
00197     _help.updateSw1(" Trigger");
00198     _help.updateSw2("Interval");
00199 }
00200