Custom Channel Plan version of MTDOT Box firmware

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

Fork of MTDOT-BOX-EVB-Factory-Firmware by MultiTech

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers ModeGps.cpp Source File

ModeGps.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 "ModeGps.h"
00020 #include "MTSLog.h"
00021 #include "rtos.h"
00022 #include "mbed.h"
00023 #include "limits.h"
00024 #define PACKETSIZE 11
00025 
00026 ModeGps::ModeGps(DOGS102* lcd, ButtonHandler* buttons, mDot* dot, LoRaHandler* lora, GPSPARSER* gps, SensorHandler* sensors, ModeJoin* join)
00027     : Mode(lcd, buttons, dot, lora, gps, sensors),
00028       _help(lcd),
00029       _sem(lcd, _band),
00030       _sem_join(lcd, _band),
00031       _join(join)
00032 {}
00033 
00034 string ModeGps::intToString(int num){
00035    char buf[3];
00036    snprintf(buf, sizeof(buf), "%d", num);
00037    return buf;
00038 }
00039 
00040 void ModeGps::init(){
00041     //resets all parameters when re-entering mode 
00042     _interval = 5;
00043     _padding = 0;
00044     _power = 20;
00045     _band = _dot->getFrequencyBand(); 
00046     _parameter = POWER;
00047     _drAll = false;
00048     _link_check = false;
00049     _GPS = false;
00050     _sub_band = _dot->getFrequencySubBand();
00051     _data_rate = mDot::DR0;
00052     _max_padding = _dot->getMaxPacketLength() - PACKETSIZE;
00053     _Sw2 = "Power";
00054     _Sw1 = intToString(_power);
00055     _help.display();
00056     osDelay(2000);
00057     
00058      _sem.display(_link_check, _snr, _rssi, _power, _sub_band, _padding, _data_rate);
00059      _sem.initial();
00060      _state = PARAMETERS;
00061      _send_timer.start();
00062 
00063 }
00064 
00065 void ModeGps::drIncrement(){
00066     _data_rate++;
00067     if (_data_rate > mDot::DR6) {
00068         _drAll = true;
00069         _data_rate = 0;
00070     }
00071     _dot->setTxDataRate(_data_rate);
00072     logInfo("new data rate %s, POWER %lu", mDot::DataRateStr(_data_rate).c_str(), _power);
00073     _max_padding = _dot->getMaxPacketLength() - PACKETSIZE;
00074 }
00075 
00076 void ModeGps::changeDataRate(){
00077     if(_drAll) {
00078         _data_rate = -1;
00079         _drAll = false;
00080     }
00081     drIncrement();
00082 }
00083 
00084 void ModeGps::changeParameter(){
00085     _parameter++;
00086     if(_parameter>INTERVAL){
00087     _parameter = 0;
00088     }
00089     switch(_parameter) {
00090         case DATA_RATE:
00091             _Sw2 = "Data Rate";
00092             _Sw1 = intToString(_data_rate);
00093             if(_drAll){
00094                 _Sw1 = "All";
00095             }
00096             break;
00097         case FSB:
00098             _Sw2 = "FSB";
00099             _Sw1 = intToString(_sub_band);
00100             break;
00101         case PADDING:
00102             _Sw2 = "Padding";
00103             _Sw1 = intToString(_padding);
00104             break;
00105         case POWER:
00106             _Sw2 = "Power";
00107             _Sw1 = intToString(_power);
00108             break;
00109         case INTERVAL:
00110             _Sw2 = "Interval";
00111             _Sw1 = intToString(_interval);
00112             break;
00113         default:
00114             break;
00115     }
00116 }
00117 
00118 void ModeGps::editParameter(){
00119     switch(_parameter) {
00120         case POWER:
00121             if(_power<20){
00122                 _power+=3;
00123             } else {
00124                 _power = 2;
00125             }
00126             _Sw1 = intToString(_power);
00127             _dot->setTxPower(_power);
00128             break;
00129             
00130         case DATA_RATE:
00131             changeDataRate();
00132             if(_drAll) {
00133                 _Sw1="All";
00134             } else {
00135                 _Sw1 = intToString(_data_rate);
00136             }
00137             break;
00138 
00139         case FSB:
00140             _send_timer.stop();
00141             _send_timer.reset();
00142             _state = BAND_CHANGE;
00143             _dot->resetNetworkSession();
00144             _lora->resetActivityLed();
00145             _sem_join.displayEditFsb(mDot::DR0, 20, _sub_band, _dot->getNetworkName(), _dot->getNetworkPassphrase());
00146             break;
00147 
00148         case PADDING:
00149             if(_padding<_max_padding){
00150                 _padding += 10 - (_padding % 10);
00151             } else {
00152                  _padding = 0;
00153             }
00154             if(_padding>_max_padding){
00155                 _padding = _max_padding;
00156             }
00157             _Sw1 = intToString(_padding);
00158             break;
00159 
00160         default:
00161             if(_interval<60){
00162                 _interval += 5;
00163             } else {
00164                 _interval = 5;
00165             }
00166             _Sw1 = intToString(_interval);
00167             break;
00168     }
00169 }
00170 
00171 void ModeGps::formatData(){
00172     _send_data.clear();
00173     uint32_t lat = 0;
00174     uint32_t lng = 0;
00175     double degrees = 0;
00176     double minutes = 0;
00177     double seconds = 0;
00178     _temp_C += 0.5;
00179 
00180     if(_GPS) {
00181         degrees = _latitude.degrees;
00182         minutes = _latitude.minutes;
00183         seconds = _latitude.seconds;
00184         if(degrees<0) {
00185               lat = ~(int)((degrees - minutes/60.0 - seconds/600000.0)*(-INT_MAX/90.0 + 1.5));
00186         } else {
00187             lat =  (int)((degrees + minutes/60.0 + seconds/600000.0)*(INT_MAX/90.0 + 0.5));
00188             }
00189         degrees = _longitude.degrees;
00190         minutes = _longitude.minutes;
00191         seconds = _longitude.seconds;
00192         if(degrees<0) {
00193              lng = ~(int)((degrees - minutes/60.0 - seconds/600000.0)*(-INT_MAX/180.0 + 1.5));
00194         } else { 
00195         lng =  (int)((degrees + minutes/60.0 + seconds/600000.0)*(INT_MAX/180.0 + 0.5));
00196         }
00197     }
00198     _send_data.push_back(0);
00199     _send_data.push_back((int8_t) _temp_C);
00200     _send_data.push_back(0);
00201     for(int i=24; i>=0; i-=8){
00202         _send_data.push_back((lat>>i)&0xFF);
00203     }
00204     for(int i=24; i>=0; i-=8){
00205         _send_data.push_back((lng>>i)&0xFF);
00206     }
00207     for(int i=0; i<(_padding>_max_padding ? _max_padding:_padding); i++){
00208          _send_data.push_back(0);
00209     }
00210 }
00211 
00212 void ModeGps::setBand(){
00213     _sub_band++;
00214     if(_sub_band > mDot::FSB_8) _sub_band = mDot::FSB_ALL;
00215     _dot->setFrequencySubBand(_sub_band);
00216 }
00217 
00218 void ModeGps::updateScreen(){
00219     _temp_C = _sensors->getTemp(SensorHandler::CELSIUS);
00220     if(_gps->getLockStatus() && _gps_available) {
00221         _GPS = true;
00222         _latitude = _gps->getLatitude();
00223         _longitude = _gps->getLongitude();
00224         _time = _gps->getTimestamp();
00225     } else {
00226          _GPS = false;
00227     }
00228     _sem.updateStats( _GPS, _longitude, _latitude, _time, _temp_C);
00229     _sem.updateSw1(_Sw1, _Sw2);
00230     _sem.updateSw2(_Sw2);
00231 }
00232 
00233 void ModeGps::send(){   
00234     _state = SENDING;
00235     _send_timer.stop();
00236     while(_dot->getNextTxMs()>0) {
00237         _sem.updateNextCh((int)(_dot->getNextTxMs()/1000));
00238         osDelay(250);
00239     }
00240 
00241     formatData();
00242     _sem.sending();
00243     _send_timer.reset();
00244     _send_timer.start();
00245     _lora->send(_send_data);
00246     osDelay(500);
00247 }
00248 
00249 bool ModeGps::start(){
00250     init();
00251     _button_timer.start();
00252     ButtonHandler::ButtonEvent be;
00253     osSignalClear(_main_id, buttonSignal | loraSignal);
00254     while (true) {
00255         if(_state==PARAMETERS){
00256             updateScreen();
00257         }
00258         osEvent e = Thread::signal_wait(0, 250);
00259         if (e.status == osEventSignal) {
00260             if (e.value.signals & buttonSignal) {
00261                 _button_timer.reset();
00262                 be = _buttons->getButtonEvent();
00263 
00264                 switch(be) {
00265                     case ButtonHandler::sw1_press:
00266                         switch(_state) {
00267                             case BAND_CHANGE:
00268                                 setBand();
00269                                 _sem_join.updateJoinFsb(_sub_band);
00270                                 break;
00271                                 
00272                             case PARAMETERS:
00273                                 editParameter();
00274                                 break;
00275                                 
00276                             default:
00277                                 break;
00278                         }
00279                         break;
00280                     case ButtonHandler::sw2_press:
00281                         switch(_state) {
00282                             case BAND_CHANGE:
00283                                 if(_join->start()){
00284                                     _state = PARAMETERS;
00285                                     _send_timer.start();
00286                                     _sem.display(_link_check, _snr, _rssi, _power, _sub_band, _padding, DATA_RATE);
00287                                     _sem.initial();
00288                                     _dot->setTxDataRate(_data_rate);
00289                                 } else _sem_join.displayEditFsb(mDot::DR0, 20, _sub_band, _dot->getNetworkName(), _dot->getNetworkPassphrase());
00290                                 break;
00291                                 
00292                             case PARAMETERS:
00293                                 changeParameter();
00294                                 break;
00295                                 
00296                             default:
00297                                 break;
00298                         }
00299                         break;
00300                         
00301                     case ButtonHandler::sw1_hold:
00302                         _send_timer.stop();
00303                         _send_timer.reset();
00304                         return true;
00305 
00306                     default:
00307                         break;
00308                 }
00309             }
00310         }
00311         if (e.value.signals & loraSignal) {
00312             _ls = _lora->getStatus();
00313             switch (_ls) {
00314 
00315                 case LoRaHandler::send_success:
00316                     _sem.sendResult("   Send Sucess!");
00317                     osDelay(500);
00318                     _link_check = true;
00319                     _snr = _dot->getSnrStats();
00320                     _rssi = _dot->getRssiStats();
00321                     _button_timer.reset();
00322                     _state = PARAMETERS;
00323                     _sem.display(_link_check, _snr, _rssi, _power, _sub_band, _padding, _data_rate);
00324                     if(_drAll){
00325                         drIncrement();
00326                     }
00327                     break;
00328 
00329                 case LoRaHandler::send_failure:
00330                     _sem.sendResult("   Send Failed.");
00331                     osDelay(500);
00332                     _link_check = false;
00333                     _button_timer.reset();
00334                     _state = PARAMETERS;
00335                     _sem.display(_link_check, _snr, _rssi, _power, _sub_band, _padding, _data_rate);
00336                      if(_drAll){
00337                         drIncrement();
00338                     }
00339                     break;
00340 
00341                 default:
00342                     break;
00343             }
00344         }
00345         if(_send_timer.read_ms() > _interval*1000 && _button_timer.read_ms() > 3000){
00346              send();
00347         }
00348     }
00349 }