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