Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: aconno_I2C Lis2dh12 WatchdogTimer
modem.cpp@27:fa76f5a08195, 2018-12-23 (annotated)
- Committer:
- pathfindr
- Date:
- Sun Dec 23 22:37:25 2018 +0000
- Revision:
- 27:fa76f5a08195
- Parent:
- 26:fa3579737329
- Child:
- 30:7e90ddd7ed12
fds
Who changed what in which revision?
| User | Revision | Line number | New contents of line |
|---|---|---|---|
| pathfindr | 7:e9a19750700d | 1 | #include "modem.h" |
| pathfindr | 7:e9a19750700d | 2 | |
| pathfindr | 21:e0b866630c27 | 3 | Modem::Modem(PinName tx, PinName rx, PinName cts, PinName rts, PinName pwrkey, PinName vreg_en, PinName w_disable): _uart(tx,rx,115200), _pwrkey(pwrkey), _vreg_en(vreg_en), _w_disable(w_disable) |
| pathfindr | 7:e9a19750700d | 4 | { |
| pathfindr | 13:29f67f256709 | 5 | GLOBAL_requireSoftReset = true; //TODO: this can be removed when uart sleep issue resolved |
| pathfindr | 7:e9a19750700d | 6 | } |
| pathfindr | 7:e9a19750700d | 7 | |
| pathfindr | 7:e9a19750700d | 8 | void Modem::flushSerial(void) |
| pathfindr | 7:e9a19750700d | 9 | { |
| pathfindr | 7:e9a19750700d | 10 | char char1 = 0; |
| pathfindr | 7:e9a19750700d | 11 | while (_uart.readable()) { |
| pathfindr | 7:e9a19750700d | 12 | char1 = _uart.getc(); |
| pathfindr | 7:e9a19750700d | 13 | } |
| pathfindr | 7:e9a19750700d | 14 | return; |
| pathfindr | 7:e9a19750700d | 15 | } |
| pathfindr | 7:e9a19750700d | 16 | |
| pathfindr | 7:e9a19750700d | 17 | void Modem::ATsendCMD(char* cmd) |
| pathfindr | 7:e9a19750700d | 18 | { |
| pathfindr | 7:e9a19750700d | 19 | flushSerial(); |
| pathfindr | 7:e9a19750700d | 20 | _uart.puts(cmd); |
| pathfindr | 7:e9a19750700d | 21 | _uart.puts("\r"); |
| pathfindr | 7:e9a19750700d | 22 | } |
| pathfindr | 7:e9a19750700d | 23 | |
| pathfindr | 12:8345612bf867 | 24 | bool Modem::ATwaitForWord(char* word, uint32_t timeout) |
| pathfindr | 7:e9a19750700d | 25 | { |
| pathfindr | 7:e9a19750700d | 26 | int targetIndex = 0; |
| pathfindr | 7:e9a19750700d | 27 | bool havefullmatch = false; |
| pathfindr | 7:e9a19750700d | 28 | char captured[32]; |
| pathfindr | 7:e9a19750700d | 29 | memset (captured,0,sizeof(captured)); |
| pathfindr | 7:e9a19750700d | 30 | Timer t; |
| pathfindr | 7:e9a19750700d | 31 | t.start(); |
| pathfindr | 12:8345612bf867 | 32 | uint32_t startmillis = t.read_ms(); |
| pathfindr | 12:8345612bf867 | 33 | uint32_t runtime = 0; |
| pathfindr | 7:e9a19750700d | 34 | while(!havefullmatch && runtime < timeout) { |
| pathfindr | 7:e9a19750700d | 35 | runtime = (t.read_ms() - startmillis); |
| pathfindr | 7:e9a19750700d | 36 | if(_uart.readable()) { |
| pathfindr | 7:e9a19750700d | 37 | char c = _uart.getc(); |
| pathfindr | 7:e9a19750700d | 38 | if (c != word[targetIndex]) { //no match, reset |
| pathfindr | 7:e9a19750700d | 39 | targetIndex = 0; |
| pathfindr | 7:e9a19750700d | 40 | } |
| pathfindr | 7:e9a19750700d | 41 | if (c == word[targetIndex]) { //we have a match |
| pathfindr | 7:e9a19750700d | 42 | captured[targetIndex] = c; |
| pathfindr | 7:e9a19750700d | 43 | targetIndex ++; |
| pathfindr | 7:e9a19750700d | 44 | //check for full match |
| pathfindr | 7:e9a19750700d | 45 | if ( strcmp(word, captured) == 0 ) { |
| pathfindr | 7:e9a19750700d | 46 | havefullmatch = true; |
| pathfindr | 7:e9a19750700d | 47 | } |
| pathfindr | 7:e9a19750700d | 48 | } |
| pathfindr | 12:8345612bf867 | 49 | } |
| pathfindr | 7:e9a19750700d | 50 | } |
| pathfindr | 7:e9a19750700d | 51 | t.stop(); |
| pathfindr | 7:e9a19750700d | 52 | t.reset(); |
| pathfindr | 22:810425eb76e1 | 53 | ThisThread::sleep_for(250); |
| pathfindr | 7:e9a19750700d | 54 | if (havefullmatch) { |
| pathfindr | 7:e9a19750700d | 55 | return true; |
| pathfindr | 7:e9a19750700d | 56 | } else { |
| pathfindr | 7:e9a19750700d | 57 | return false; |
| pathfindr | 7:e9a19750700d | 58 | } |
| pathfindr | 7:e9a19750700d | 59 | } |
| pathfindr | 7:e9a19750700d | 60 | |
| pathfindr | 12:8345612bf867 | 61 | bool Modem::on(void) |
| pathfindr | 12:8345612bf867 | 62 | { |
| pathfindr | 23:a3b0ccf75ca5 | 63 | if (!GLOBAL_modemOn) { |
| pathfindr | 23:a3b0ccf75ca5 | 64 | _w_disable = 0; // this sets the modem to airplane mode |
| pathfindr | 23:a3b0ccf75ca5 | 65 | _vreg_en = 1; |
| pathfindr | 23:a3b0ccf75ca5 | 66 | Thread::wait(200); |
| pathfindr | 23:a3b0ccf75ca5 | 67 | _pwrkey = 0; |
| pathfindr | 23:a3b0ccf75ca5 | 68 | Thread::wait(200); |
| pathfindr | 23:a3b0ccf75ca5 | 69 | _pwrkey = 1; |
| pathfindr | 23:a3b0ccf75ca5 | 70 | |
| pathfindr | 23:a3b0ccf75ca5 | 71 | GLOBAL_modemOn = true; |
| pathfindr | 22:810425eb76e1 | 72 | |
| pathfindr | 23:a3b0ccf75ca5 | 73 | //CONFIGURE |
| pathfindr | 23:a3b0ccf75ca5 | 74 | if (ATwaitForWord("RDY",ATTIMEOUT_MED)) { |
| pathfindr | 23:a3b0ccf75ca5 | 75 | //TURN OFF ECHO |
| pathfindr | 23:a3b0ccf75ca5 | 76 | ATsendCMD("ATE0"); |
| pathfindr | 23:a3b0ccf75ca5 | 77 | ATwaitForWord("OK",ATTIMEOUT_SHORT); |
| pathfindr | 23:a3b0ccf75ca5 | 78 | |
| pathfindr | 23:a3b0ccf75ca5 | 79 | //ENABLE AIRPLANE MODE CONTROL WITH PIN |
| pathfindr | 23:a3b0ccf75ca5 | 80 | ATsendCMD("AT+QCFG=\"airplanecontrol\",1"); |
| pathfindr | 23:a3b0ccf75ca5 | 81 | ATwaitForWord("OK",ATTIMEOUT_SHORT); |
| pathfindr | 23:a3b0ccf75ca5 | 82 | |
| pathfindr | 23:a3b0ccf75ca5 | 83 | //PRIORITISE 2G connection (reason being uses less power in some instances and can get cell tower tirangulation) |
| pathfindr | 27:fa76f5a08195 | 84 | ATsendCMD("AT+QCFG=\"nwscanseq\",1"); //2G priority |
| pathfindr | 27:fa76f5a08195 | 85 | //ATsendCMD("AT+QCFG=\"nwscanseq\",2"); //3G priority |
| pathfindr | 27:fa76f5a08195 | 86 | //ATsendCMD("AT+QCFG=\"nwscanseq\",0"); //AUTO |
| pathfindr | 23:a3b0ccf75ca5 | 87 | ATwaitForWord("OK",ATTIMEOUT_SHORT); |
| pathfindr | 23:a3b0ccf75ca5 | 88 | |
| pathfindr | 27:fa76f5a08195 | 89 | //CONNECTION TYPE |
| pathfindr | 27:fa76f5a08195 | 90 | //ATsendCMD("AT+QCFG=\"nwscanmode\",1"); //2G only connection |
| pathfindr | 27:fa76f5a08195 | 91 | //ATsendCMD("AT+QCFG=\"nwscanmode\",2"); //3G only connection |
| pathfindr | 23:a3b0ccf75ca5 | 92 | //ATwaitForWord("OK",ATTIMEOUT_SHORT); |
| pathfindr | 23:a3b0ccf75ca5 | 93 | |
| pathfindr | 23:a3b0ccf75ca5 | 94 | return true; |
| pathfindr | 23:a3b0ccf75ca5 | 95 | } else { |
| pathfindr | 23:a3b0ccf75ca5 | 96 | return false; |
| pathfindr | 23:a3b0ccf75ca5 | 97 | } |
| pathfindr | 12:8345612bf867 | 98 | } else { |
| pathfindr | 23:a3b0ccf75ca5 | 99 | return true; |
| pathfindr | 12:8345612bf867 | 100 | } |
| pathfindr | 12:8345612bf867 | 101 | } |
| pathfindr | 12:8345612bf867 | 102 | |
| pathfindr | 12:8345612bf867 | 103 | void Modem::off(bool soft) |
| pathfindr | 12:8345612bf867 | 104 | { |
| pathfindr | 12:8345612bf867 | 105 | if (soft) { |
| pathfindr | 23:a3b0ccf75ca5 | 106 | //ATsendCMD("AT+QPOWD"); |
| pathfindr | 24:c161db07557f | 107 | //_pwrkey = 0; |
| pathfindr | 24:c161db07557f | 108 | //Thread::wait(800); |
| pathfindr | 24:c161db07557f | 109 | //_pwrkey = 1; |
| pathfindr | 23:a3b0ccf75ca5 | 110 | //ATwaitForWord("POWERED DOWN",ATTIMEOUT_SHORT); |
| pathfindr | 12:8345612bf867 | 111 | } |
| pathfindr | 22:810425eb76e1 | 112 | GLOBAL_registeredOnNetwork = false; |
| pathfindr | 12:8345612bf867 | 113 | _vreg_en = 0; |
| pathfindr | 12:8345612bf867 | 114 | } |
| pathfindr | 12:8345612bf867 | 115 | |
| pathfindr | 13:29f67f256709 | 116 | long long Modem::getIMEI() |
| pathfindr | 13:29f67f256709 | 117 | { |
| pathfindr | 13:29f67f256709 | 118 | long long imei = 0; |
| pathfindr | 23:a3b0ccf75ca5 | 119 | char* ATinBuffer; |
| pathfindr | 13:29f67f256709 | 120 | ATsendCMD("AT+GSN"); |
| pathfindr | 22:810425eb76e1 | 121 | ATwaitForWord("\n",ATTIMEOUT_SHORT); |
| pathfindr | 13:29f67f256709 | 122 | _uart.scanf("%s", ATinBuffer); |
| pathfindr | 13:29f67f256709 | 123 | imei = atoll(ATinBuffer); |
| pathfindr | 13:29f67f256709 | 124 | flushSerial(); |
| pathfindr | 13:29f67f256709 | 125 | return imei; |
| pathfindr | 13:29f67f256709 | 126 | } |
| pathfindr | 13:29f67f256709 | 127 | |
| pathfindr | 23:a3b0ccf75ca5 | 128 | char* Modem::getModemModel() |
| pathfindr | 23:a3b0ccf75ca5 | 129 | { |
| pathfindr | 23:a3b0ccf75ca5 | 130 | char* modemModel; |
| pathfindr | 23:a3b0ccf75ca5 | 131 | ATsendCMD("AT+GMM"); |
| pathfindr | 23:a3b0ccf75ca5 | 132 | ATwaitForWord("\n",ATTIMEOUT_SHORT); |
| pathfindr | 23:a3b0ccf75ca5 | 133 | _uart.scanf("%s", modemModel); |
| pathfindr | 23:a3b0ccf75ca5 | 134 | flushSerial(); |
| pathfindr | 23:a3b0ccf75ca5 | 135 | return modemModel; |
| pathfindr | 23:a3b0ccf75ca5 | 136 | } |
| pathfindr | 23:a3b0ccf75ca5 | 137 | |
| pathfindr | 12:8345612bf867 | 138 | bool Modem::registerOnNetwork(int maxAttempts, uint32_t timeout) |
| pathfindr | 12:8345612bf867 | 139 | { |
| pathfindr | 22:810425eb76e1 | 140 | //CHECK WE ARE NOT ALREADY ON NETOWRK |
| pathfindr | 22:810425eb76e1 | 141 | if (!GLOBAL_registeredOnNetwork) { |
| pathfindr | 22:810425eb76e1 | 142 | int attempt = 0; |
| pathfindr | 22:810425eb76e1 | 143 | Timer t; |
| pathfindr | 22:810425eb76e1 | 144 | t.start(); |
| pathfindr | 22:810425eb76e1 | 145 | //DISABLE AIRPLANE MODE |
| pathfindr | 22:810425eb76e1 | 146 | _w_disable = 1; |
| pathfindr | 22:810425eb76e1 | 147 | flushSerial(); |
| pathfindr | 26:fa3579737329 | 148 | while (attempt < maxAttempts) { |
| pathfindr | 22:810425eb76e1 | 149 | watchdogKick(); |
| pathfindr | 22:810425eb76e1 | 150 | t.reset(); |
| pathfindr | 22:810425eb76e1 | 151 | uint32_t startmillis = t.read_ms(); |
| pathfindr | 22:810425eb76e1 | 152 | uint32_t runtime = 0; |
| pathfindr | 22:810425eb76e1 | 153 | while(!GLOBAL_registeredOnNetwork && runtime < timeout) { |
| pathfindr | 22:810425eb76e1 | 154 | runtime = (t.read_ms() - startmillis); |
| pathfindr | 22:810425eb76e1 | 155 | Thread::wait(1000); |
| pathfindr | 22:810425eb76e1 | 156 | ATsendCMD("AT+CREG?"); |
| pathfindr | 22:810425eb76e1 | 157 | if (ATwaitForWord("+CREG: 0,5",3000)) { |
| pathfindr | 22:810425eb76e1 | 158 | flushSerial(); |
| pathfindr | 22:810425eb76e1 | 159 | GLOBAL_registeredOnNetwork = true; |
| pathfindr | 22:810425eb76e1 | 160 | }; |
| pathfindr | 22:810425eb76e1 | 161 | } |
| pathfindr | 22:810425eb76e1 | 162 | if (!GLOBAL_registeredOnNetwork) { |
| pathfindr | 22:810425eb76e1 | 163 | off(true); |
| pathfindr | 23:a3b0ccf75ca5 | 164 | Thread::wait(500); |
| pathfindr | 22:810425eb76e1 | 165 | on(); |
| pathfindr | 22:810425eb76e1 | 166 | } |
| pathfindr | 26:fa3579737329 | 167 | attempt ++; |
| pathfindr | 12:8345612bf867 | 168 | } |
| pathfindr | 22:810425eb76e1 | 169 | t.stop(); |
| pathfindr | 12:8345612bf867 | 170 | } |
| pathfindr | 14:9a54b1b65bc8 | 171 | flushSerial(); |
| pathfindr | 13:29f67f256709 | 172 | if (GLOBAL_registeredOnNetwork) { |
| pathfindr | 12:8345612bf867 | 173 | return true; |
| pathfindr | 12:8345612bf867 | 174 | } else { |
| pathfindr | 12:8345612bf867 | 175 | return false; |
| pathfindr | 12:8345612bf867 | 176 | } |
| pathfindr | 12:8345612bf867 | 177 | } |
| pathfindr | 12:8345612bf867 | 178 | |
| pathfindr | 12:8345612bf867 | 179 | bool Modem::USSDsend(char* message, int maxAttempts) |
| pathfindr | 12:8345612bf867 | 180 | { |
| pathfindr | 12:8345612bf867 | 181 | bool sent = false; |
| pathfindr | 12:8345612bf867 | 182 | int attempt = 0; |
| pathfindr | 12:8345612bf867 | 183 | //TRY X NUMBER OF TIMES |
| pathfindr | 26:fa3579737329 | 184 | while (!sent && attempt < maxAttempts) { |
| pathfindr | 12:8345612bf867 | 185 | char bytestosend[160]; |
| pathfindr | 13:29f67f256709 | 186 | snprintf(bytestosend, sizeof(bytestosend), "AT+CUSD=1,\"#469*%s#\"", message); |
| pathfindr | 12:8345612bf867 | 187 | ATsendCMD(bytestosend); |
| pathfindr | 22:810425eb76e1 | 188 | if (ATwaitForWord("+CUSD: 0",ATTIMEOUT_MED)) { |
| pathfindr | 12:8345612bf867 | 189 | flushSerial(); |
| pathfindr | 12:8345612bf867 | 190 | sent = true; |
| pathfindr | 12:8345612bf867 | 191 | }; |
| pathfindr | 26:fa3579737329 | 192 | attempt ++; |
| pathfindr | 12:8345612bf867 | 193 | } |
| pathfindr | 12:8345612bf867 | 194 | if (sent) { |
| pathfindr | 12:8345612bf867 | 195 | return true; |
| pathfindr | 12:8345612bf867 | 196 | } else { |
| pathfindr | 12:8345612bf867 | 197 | return false; |
| pathfindr | 12:8345612bf867 | 198 | } |
| pathfindr | 12:8345612bf867 | 199 | } |
| pathfindr | 12:8345612bf867 | 200 | |
| pathfindr | 14:9a54b1b65bc8 | 201 | char* Modem::USSDreceive(int messageIndex) |
| pathfindr | 12:8345612bf867 | 202 | { |
| pathfindr | 12:8345612bf867 | 203 | bool received = false; |
| pathfindr | 22:810425eb76e1 | 204 | uint32_t timeout = ATTIMEOUT_MED; |
| pathfindr | 14:9a54b1b65bc8 | 205 | int USSDmessageIndex = 0; |
| pathfindr | 17:ba55c026b1d6 | 206 | char ATinBuffer[180]; |
| pathfindr | 14:9a54b1b65bc8 | 207 | int matchCount = 0; |
| pathfindr | 12:8345612bf867 | 208 | Timer t; |
| pathfindr | 12:8345612bf867 | 209 | t.start(); |
| pathfindr | 12:8345612bf867 | 210 | //TRY UNTIL TIMEOUT |
| pathfindr | 12:8345612bf867 | 211 | uint32_t startmillis = t.read_ms(); |
| pathfindr | 12:8345612bf867 | 212 | uint32_t runtime = 0; |
| pathfindr | 12:8345612bf867 | 213 | while(!received && runtime < timeout) { |
| pathfindr | 13:29f67f256709 | 214 | runtime = (t.read_ms() - startmillis); |
| pathfindr | 22:810425eb76e1 | 215 | if (ATwaitForWord("+CUSD: 0",ATTIMEOUT_SHORT)) { |
| pathfindr | 12:8345612bf867 | 216 | led1 = 0; |
| pathfindr | 14:9a54b1b65bc8 | 217 | if ( (matchCount = _uart.scanf(",\"%d#%[^#]",USSDmessageIndex,ATinBuffer) ) > 0 ) { |
| pathfindr | 14:9a54b1b65bc8 | 218 | if (USSDmessageIndex == messageIndex) { |
| pathfindr | 14:9a54b1b65bc8 | 219 | //NEED TO GET THIS WORKING SO WE KNOW WE ARE DEALING WITH THE RIGT MESSAGE |
| pathfindr | 14:9a54b1b65bc8 | 220 | //MOVE THE BELOW INTO THIS IF STAEMEBNTS |
| pathfindr | 12:8345612bf867 | 221 | } |
| pathfindr | 14:9a54b1b65bc8 | 222 | led1 = 1; |
| pathfindr | 14:9a54b1b65bc8 | 223 | received = true; |
| pathfindr | 12:8345612bf867 | 224 | } |
| pathfindr | 12:8345612bf867 | 225 | } |
| pathfindr | 12:8345612bf867 | 226 | } |
| pathfindr | 14:9a54b1b65bc8 | 227 | flushSerial(); |
| pathfindr | 12:8345612bf867 | 228 | if (received) { |
| pathfindr | 12:8345612bf867 | 229 | return ATinBuffer; |
| pathfindr | 12:8345612bf867 | 230 | } else { |
| pathfindr | 14:9a54b1b65bc8 | 231 | return "err"; |
| pathfindr | 12:8345612bf867 | 232 | } |
| pathfindr | 12:8345612bf867 | 233 | } |
| pathfindr | 12:8345612bf867 | 234 | |
| pathfindr | 12:8345612bf867 | 235 | |
| pathfindr | 15:7aad9a7f970c | 236 | char* Modem::USSDmessage(char* message, bool needResponse, int maxAttempts, char* api) |
| pathfindr | 16:3bf5f1a5f869 | 237 | { |
| pathfindr | 15:7aad9a7f970c | 238 | uint8_t messageIndex = 1; |
| pathfindr | 16:3bf5f1a5f869 | 239 | bool result; |
| pathfindr | 13:29f67f256709 | 240 | int messageLength = strlen(message); |
| pathfindr | 13:29f67f256709 | 241 | if (messageLength > USSD_MAXLENGTH) { |
| pathfindr | 17:ba55c026b1d6 | 242 | char message_failsafe[100]; |
| pathfindr | 25:7adeb1a53360 | 243 | snprintf(message_failsafe,sizeof(message_failsafe),"(%s,z:TOOBIG,c:%d)\0",api,messageIndex); |
| pathfindr | 16:3bf5f1a5f869 | 244 | result = USSDsend(message_failsafe, maxAttempts); |
| pathfindr | 15:7aad9a7f970c | 245 | } else { |
| pathfindr | 16:3bf5f1a5f869 | 246 | result = USSDsend(message, maxAttempts); |
| pathfindr | 13:29f67f256709 | 247 | } |
| pathfindr | 16:3bf5f1a5f869 | 248 | if (result) { |
| pathfindr | 14:9a54b1b65bc8 | 249 | if (needResponse) { |
| pathfindr | 14:9a54b1b65bc8 | 250 | char* response = USSDreceive(messageIndex); |
| pathfindr | 14:9a54b1b65bc8 | 251 | if (response != "err") { |
| pathfindr | 14:9a54b1b65bc8 | 252 | return response; |
| pathfindr | 14:9a54b1b65bc8 | 253 | } else { |
| pathfindr | 15:7aad9a7f970c | 254 | return "sendonly"; |
| pathfindr | 14:9a54b1b65bc8 | 255 | } |
| pathfindr | 14:9a54b1b65bc8 | 256 | } else { |
| pathfindr | 14:9a54b1b65bc8 | 257 | return "ok"; |
| pathfindr | 14:9a54b1b65bc8 | 258 | } |
| pathfindr | 13:29f67f256709 | 259 | } else { |
| pathfindr | 14:9a54b1b65bc8 | 260 | return "err"; |
| pathfindr | 13:29f67f256709 | 261 | } |
| pathfindr | 13:29f67f256709 | 262 | } |
| pathfindr | 13:29f67f256709 | 263 | |
| pathfindr | 20:5404841fdd2b | 264 | |
| pathfindr | 22:810425eb76e1 | 265 | char* Modem::getLocation(uint8_t accuracy, uint16_t timeout_seconds) |
| pathfindr | 20:5404841fdd2b | 266 | { |
| pathfindr | 20:5404841fdd2b | 267 | flushSerial(); |
| pathfindr | 20:5404841fdd2b | 268 | bool haveGPSFix = false; |
| pathfindr | 23:a3b0ccf75ca5 | 269 | bool haveCellFix = false; |
| pathfindr | 20:5404841fdd2b | 270 | |
| pathfindr | 23:a3b0ccf75ca5 | 271 | char locDataOut[100]; |
| pathfindr | 22:810425eb76e1 | 272 | |
| pathfindr | 22:810425eb76e1 | 273 | if (accuracy >= 2) { |
| pathfindr | 20:5404841fdd2b | 274 | //Enable External LNA power - IS DISABLED BY DEFAULT |
| pathfindr | 20:5404841fdd2b | 275 | ATsendCMD("AT+QGPSCFG=\"lnacontrol\",1"); |
| pathfindr | 20:5404841fdd2b | 276 | ATwaitForWord("OK",5000); |
| pathfindr | 20:5404841fdd2b | 277 | |
| pathfindr | 22:810425eb76e1 | 278 | //TURN ON GPS |
| pathfindr | 22:810425eb76e1 | 279 | ATsendCMD("AT+QGPS=1"); |
| pathfindr | 22:810425eb76e1 | 280 | ATwaitForWord("OK",ATTIMEOUT_SHORT); |
| pathfindr | 22:810425eb76e1 | 281 | |
| pathfindr | 20:5404841fdd2b | 282 | Timer t; |
| pathfindr | 20:5404841fdd2b | 283 | t.start(); |
| pathfindr | 20:5404841fdd2b | 284 | //TRY UNTIL TIMEOUT |
| pathfindr | 20:5404841fdd2b | 285 | uint8_t GPS_fixstage = 0; |
| pathfindr | 20:5404841fdd2b | 286 | uint8_t GPS_fixcount = 0; |
| pathfindr | 20:5404841fdd2b | 287 | uint32_t startmillis = t.read_ms(); |
| pathfindr | 20:5404841fdd2b | 288 | uint32_t runtime = 0; |
| pathfindr | 20:5404841fdd2b | 289 | while(!haveGPSFix && runtime < (timeout_seconds*1000)) { |
| pathfindr | 22:810425eb76e1 | 290 | watchdogKick(); |
| pathfindr | 21:e0b866630c27 | 291 | Thread::wait(5000); //this goes first |
| pathfindr | 20:5404841fdd2b | 292 | runtime = (t.read_ms() - startmillis); |
| pathfindr | 20:5404841fdd2b | 293 | ATsendCMD("AT+QGPSLOC=2"); |
| pathfindr | 22:810425eb76e1 | 294 | if (ATwaitForWord("+QGPSLOC: ",ATTIMEOUT_SHORT)) { |
| pathfindr | 20:5404841fdd2b | 295 | GPS_fixstage = 1; |
| pathfindr | 20:5404841fdd2b | 296 | GPS_fixcount ++; |
| pathfindr | 21:e0b866630c27 | 297 | if (GPS_fixcount == 2) { //wait 10 seconds to get a better fix // need to improve this logic |
| pathfindr | 20:5404841fdd2b | 298 | haveGPSFix = true; |
| pathfindr | 22:810425eb76e1 | 299 | } else { |
| pathfindr | 22:810425eb76e1 | 300 | flushSerial(); |
| pathfindr | 22:810425eb76e1 | 301 | } |
| pathfindr | 22:810425eb76e1 | 302 | } else { |
| pathfindr | 22:810425eb76e1 | 303 | flushSerial(); |
| pathfindr | 22:810425eb76e1 | 304 | } |
| pathfindr | 22:810425eb76e1 | 305 | if (haveGPSFix) { |
| pathfindr | 22:810425eb76e1 | 306 | //+QGPSLOC: 233510.0,52.55415,1.24021,1.2,59.2,2,0.00,0.0,0.0,201218,05 |
| pathfindr | 22:810425eb76e1 | 307 | int matchCount = 0; |
| pathfindr | 22:810425eb76e1 | 308 | float utc; |
| pathfindr | 22:810425eb76e1 | 309 | float lat; |
| pathfindr | 22:810425eb76e1 | 310 | float lng; |
| pathfindr | 22:810425eb76e1 | 311 | float hdp; |
| pathfindr | 22:810425eb76e1 | 312 | float alt; |
| pathfindr | 22:810425eb76e1 | 313 | uint8_t fix; |
| pathfindr | 22:810425eb76e1 | 314 | float cog; |
| pathfindr | 22:810425eb76e1 | 315 | float spkm; |
| pathfindr | 22:810425eb76e1 | 316 | float spkn; |
| pathfindr | 22:810425eb76e1 | 317 | uint32_t date; |
| pathfindr | 22:810425eb76e1 | 318 | uint8_t sat; |
| pathfindr | 22:810425eb76e1 | 319 | |
| pathfindr | 23:a3b0ccf75ca5 | 320 | //Example data |
| pathfindr | 23:a3b0ccf75ca5 | 321 | //115757.0,52.62091,1.29536,0.8,58.2,2,0.00,0.0,0.0,211218,07 |
| pathfindr | 23:a3b0ccf75ca5 | 322 | if ((matchCount = _uart.scanf("%f,%f,%f,%f,%f,%d,%f,%f,%f,%d,%d",&utc,&lat,&lng,&hdp,&alt,&fix,&cog,&spkm,&spkn,&date,&sat)) == 11 ) { |
| pathfindr | 23:a3b0ccf75ca5 | 323 | //{“fix”:“GPS”,“sat”:“9",“lat”:“52.913254",“lng”:“-1.455289",“hdp”:“89.0",“spd”:“0.0"} |
| pathfindr | 26:fa3579737329 | 324 | sprintf(locDataOut,",g:(fix:GPS,sat:%d,lat:%.6f,lng:%.6f,hdp:%.1f,spd:%.1f)\0",sat,lat,lng,hdp,spkm); |
| pathfindr | 23:a3b0ccf75ca5 | 325 | //DEBUG("\nGPSOut:%s\n",locDataOut); |
| pathfindr | 20:5404841fdd2b | 326 | } |
| pathfindr | 20:5404841fdd2b | 327 | } |
| pathfindr | 20:5404841fdd2b | 328 | } |
| pathfindr | 20:5404841fdd2b | 329 | //TURN OFF GPS |
| pathfindr | 20:5404841fdd2b | 330 | ATsendCMD("AT+QGPSEND"); |
| pathfindr | 22:810425eb76e1 | 331 | ATwaitForWord("OK",ATTIMEOUT_SHORT); |
| pathfindr | 20:5404841fdd2b | 332 | } |
| pathfindr | 22:810425eb76e1 | 333 | |
| pathfindr | 22:810425eb76e1 | 334 | //SHALL WE GET CELL LOCATION |
| pathfindr | 22:810425eb76e1 | 335 | if (!haveGPSFix && accuracy >= 1) { |
| pathfindr | 22:810425eb76e1 | 336 | //PRIORITISE 2G connection (reason being uses less power in some instances and can get cell tower tirangulation) |
| pathfindr | 23:a3b0ccf75ca5 | 337 | //ATsendCMD("AT+QCFG=\"nwscanseq\",0"); // 0 - auto, 1 - 2g priority, 2 - 3g priority |
| pathfindr | 23:a3b0ccf75ca5 | 338 | //ATwaitForWord("OK",ATTIMEOUT_SHORT); |
| pathfindr | 22:810425eb76e1 | 339 | //ATsendCMD("AT+QCFG=\"nwscanmode\",1"); // 0 - auto, 1 - 2g, 2 - 3g |
| pathfindr | 22:810425eb76e1 | 340 | //ATwaitForWord("OK",ATTIMEOUT_SHORT); |
| pathfindr | 22:810425eb76e1 | 341 | |
| pathfindr | 23:a3b0ccf75ca5 | 342 | _w_disable = 1; //turn off airplane mode |
| pathfindr | 23:a3b0ccf75ca5 | 343 | registerOnNetwork(2, 90000); |
| pathfindr | 22:810425eb76e1 | 344 | |
| pathfindr | 23:a3b0ccf75ca5 | 345 | int matchCount; |
| pathfindr | 23:a3b0ccf75ca5 | 346 | char type[6]; |
| pathfindr | 23:a3b0ccf75ca5 | 347 | char cellID[6]; |
| pathfindr | 23:a3b0ccf75ca5 | 348 | char lac[6]; |
| pathfindr | 23:a3b0ccf75ca5 | 349 | int mcc; |
| pathfindr | 23:a3b0ccf75ca5 | 350 | int mnc; |
| pathfindr | 23:a3b0ccf75ca5 | 351 | |
| pathfindr | 23:a3b0ccf75ca5 | 352 | ATsendCMD("AT+QENG=\"servingcell\""); |
| pathfindr | 23:a3b0ccf75ca5 | 353 | ATwaitForWord("+QENG: \"servingcell\"",ATTIMEOUT_SHORT); |
| pathfindr | 23:a3b0ccf75ca5 | 354 | |
| pathfindr | 23:a3b0ccf75ca5 | 355 | if ((matchCount = _uart.scanf(",\"NOCONN\",\"%[^\"]\",%d,%d,%[^,],%[^,]",&type,&mcc,&mnc,&lac,&cellID)) == 5 ) { |
| pathfindr | 23:a3b0ccf75ca5 | 356 | //sprintf(locDataOut,",h:%d.%d.%s.%s\0",mcc,mnc,lac,cellID); |
| pathfindr | 23:a3b0ccf75ca5 | 357 | sprintf(locDataOut,",h:41806.2252.234.30\0"); |
| pathfindr | 23:a3b0ccf75ca5 | 358 | haveCellFix = true; |
| pathfindr | 23:a3b0ccf75ca5 | 359 | //DEBUG("\ncellOut:%s\n",locDataOut); |
| pathfindr | 23:a3b0ccf75ca5 | 360 | } |
| pathfindr | 23:a3b0ccf75ca5 | 361 | |
| pathfindr | 23:a3b0ccf75ca5 | 362 | //example from mulbs |
| pathfindr | 22:810425eb76e1 | 363 | /* |
| pathfindr | 22:810425eb76e1 | 364 | +QENG: "servingcell","NOCONN","2G",234,30,8CC,A34E,20,668,0,-80,0,5,4,26,26,1,-,-,-,-,-,-,-,-,-,"-" |
| pathfindr | 22:810425eb76e1 | 365 | +QENG: "neighbourcell","2G",234,30,8CC,A34D,20,656,-89,17,17,0,0 |
| pathfindr | 22:810425eb76e1 | 366 | +QENG: "neighbourcell","2G",234,30,8CC,678,61,686,-104,2,2,0,0 |
| pathfindr | 22:810425eb76e1 | 367 | +QENG: "neighbourcell","2G",234,30,8CC,4303,32,676,-104,2,2,0,0 |
| pathfindr | 22:810425eb76e1 | 368 | +QENG: "neighbourcell","2G",234,30,8CC,B2B2,16,692,-107,-1,-1,0,0 |
| pathfindr | 22:810425eb76e1 | 369 | https://www.neilson.co.za/mobile-network-geolocation-obtaining-the-cell-ids-the-signal-strength-of-surrounding-towers-from-a-gsm-modem/ |
| pathfindr | 22:810425eb76e1 | 370 | */ |
| pathfindr | 22:810425eb76e1 | 371 | |
| pathfindr | 23:a3b0ccf75ca5 | 372 | //ATsendCMD("AT+QENG=\"neighbourcell\""); |
| pathfindr | 23:a3b0ccf75ca5 | 373 | //ATwaitForWord("OK",ATTIMEOUT_LONG); |
| pathfindr | 20:5404841fdd2b | 374 | } |
| pathfindr | 22:810425eb76e1 | 375 | |
| pathfindr | 22:810425eb76e1 | 376 | //RETURN |
| pathfindr | 23:a3b0ccf75ca5 | 377 | return locDataOut; |
| pathfindr | 20:5404841fdd2b | 378 | } |
| pathfindr | 20:5404841fdd2b | 379 | |
| pathfindr | 7:e9a19750700d | 380 | Modem::~Modem(){}; |