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
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 }
Generated on Tue Jul 12 2022 13:07:49 by 1.7.2