Scott Hoppe / Mbed OS 4_Ecolab_RSSI_Checker

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

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