Snorktracker
 All Data Structures Files Functions Variables Macros Pages
GsmGps.h
Go to the documentation of this file.
1 /*
2  Copyright (C) 2018 SFini
3 
4  This program is free software: you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation, either version 3 of the License, or
7  (at your option) any later version.
8 
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU General Public License for more details.
13 
14  You should have received a copy of the GNU General Public License
15  along with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
24 #define TINY_GSM_YIELD() { MyDelay(1); }
25 #include "Sim808.h"
26 #include "Serial.h"
27 
31 class MyGsmGps
32 {
33 protected:
37 
38 public:
41  TinyGsmClient gsmClient;
42 
45 
46 protected:
47  void enableGps(bool enable);
48  bool getGps();
49  bool getGpsFromGsm();
50  bool sleepMode2();
51 
52 public:
53  MyGsmGps(MyOptions &options, MyData &data, short pinRx, short pinTx);
54 
55  bool begin();
56  void handleClient();
57  bool stop();
58  bool waitingForGps();
59 
60  bool sendAT(String cmd);
61 
62  bool getSMS(SmsData &sms);
63  bool sendSMS(String phoneNumber, String message);
64  bool deleteSMS(long index);
65 };
66 
67 /* ******************************************** */
68 
70 MyGsmGps::MyGsmGps(MyOptions &options, MyData &data, short pinRx, short pinTx)
71  : gsmSerial(data.logInfos, options.isDebugActive, pinRx, pinTx)
72  , gsmSim808(gsmSerial)
73  , gsmClient(gsmSim808)
74  , myOptions(options)
75  , myData(data)
76  , lastGsmChecSec(0)
77  , lastGpsCheckSec(0)
78  , startGpsCheck(0)
79 {
80  gsmSerial.begin(9600);
81 }
82 
85 {
86  if (!myOptions.powerOn) {
87  MyDbg(F("sim808 has no power!"));
88  return false;
89  }
90 
91  if (!myData.isGsmActive) {
92  MyDbg(F("MyGsmGps::begin"));
93  myData.status = F("Sim808 Initializing...");
95  for (int i = 0; !gsmSim808.restart() && i <= 5; i++) {
96  if (!myOptions.powerOn) {
97  MyDbg(F("Sim808 Initializing ... canceled"));
98  return false;
99  }
100  if (i == 5) { // not working!
101  myData.status = F("Sim808 restart failed");
103  return false;
104  }
105  MyDbg(F("."), false, false);
106  MyDelay(500);
107  }
108  myData.status = F("Sim808 connected");
110 
111  gsmSim808.setBaud(9600);
112 
113  myData.status = F("Sim808 Waiting for network...");
115  for (int i = 0; !gsmSim808.waitForNetwork() && i <= 5; i++) {
116  if (!myOptions.powerOn) {
117  MyDbg(F("Sim808 Waiting for network... canceled"));
118  return false;
119  }
120  if (i == 5) { // not working!
121  myData.status = F("Sim808 network failed");
123  return false;
124  }
125  MyDbg(F("."), false, false);
126  MyDelay(500);
127  }
128  if (!gsmSim808.isNetworkConnected()) {
129  myData.status = F("Sim808 network failed");
131  } else {
132  myData.status = F("Sim808 network connected");
134 
135  MyDbg((String) F("GPRS: ") + myOptions.gprsAP +
136  F(" User: ") + myOptions.gprsUser + F(" Password: ") + myOptions.gprsPassword);
137  if (!gsmSim808.gprsConnect(myOptions.gprsAP.c_str(), myOptions.gprsUser.c_str(), myOptions.gprsPassword.c_str())) {
138  myData.status = F("Sim808 gprs connection failed!");
140  return false;
141  }
142  myData.status = F("Sim808 gsm connected");
144 
145  myData.modemInfo = gsmSim808.getModemInfo();
146  MyDbg((String) F("Modem info: ") + myData.modemInfo);
147 
148  myData.modemIP = gsmSim808.getLocalIP();
149  MyDbg((String) F("Modem IP: ") + myData.modemIP);
150 
151  myData.imei = gsmSim808.getIMEI();
152  MyDbg((String) F("sim808: ") + myData.modemInfo);
153 
154  myData.cop = gsmSim808.getOperator();
155  MyDbg((String) F("cop: ") + myData.modemInfo);
156  }
157  myData.isGsmActive = true;
158  }
159 
161  enableGps(true);
162  }
163 
164  return true;
165 }
166 
169 {
170  if (!myData.isGsmActive) {
171  return;
172  }
173 
174  if (secondsElapsedAndUpdate(lastGsmChecSec, 60000)) { // Check every minute
175  myData.signalQuality = String(gsmSim808.getSignalQuality());
176  myData.batteryLevel = String(gsmSim808.getBattPercent());
177  myData.batteryVolt = String(gsmSim808.getBattVoltage() / 1000.0F, 2);
178 
179  MyDbg((String) F("(sim808) signalQuality: ") + myData.signalQuality);
180  MyDbg((String) F("(sim808) batteryLevel: ") + myData.batteryLevel);
181  MyDbg((String) F("(sim808) batteryVolt: ") + myData.batteryVolt);
182  }
183 
184  if (secondsElapsedAndUpdate(lastGpsCheckSec, 10)) { // Wait 10 sec between retries
186  if (!myData.isGpsActive) {
187  enableGps(true);
188  }
189  MyDbg(F("getGPS"));
190  if (startGpsCheck == 0) {
192  }
193  if (getGps()) {
194  MyDbg(F(" -> ok"));
195  startGpsCheck = 0;
197  } else {
198  long waitForGpsTime = secondsSincePowerOn() - startGpsCheck;
199 
200  // Ignore gps if we cannot get a position in X minutes.
201  if (waitForGpsTime > myOptions.gpsTimeoutSec) {
202  getGpsFromGsm(); // fallback from gsm
203 
204  MyDbg(F(" -> gps timeout!"));
205  startGpsCheck = 0;
206  myData.waitingForGps = false;
208  } else {
209  if (myOptions.gpsTimeoutSec - waitForGpsTime > 0) {
210  MyDbg((String) F(" -> no gps fix (timeout in ") + String(myOptions.gpsTimeoutSec - waitForGpsTime) + F(" seconds!)"));
211  }
212  }
213  }
214  }
215  }
216 }
217 
220 {
221  bool ret = true;
222 
223  MyDbg(F("gprs gps stopping"));
224  enableGps(false);
225  if (gsmSim808.isGprsConnected()) {
226  ret = gsmSim808.gprsDisconnect();
227  }
228  if (ret) {
229  myData.isGsmActive = false;
230  MyDbg(F("gprs gps stopped"));
231  myData.status = F("Sim808 stopped!");
232  sleepMode2();
233  }
234  return ret;
235 }
236 
239 {
241 }
242 
244 bool MyGsmGps::sendAT(String cmd)
245 {
246  if (!myData.isGsmActive) {
247  MyDbg(F("sim808 not active!"));
248  return false;
249  }
250 
251  String response;
252 
253  gsmSerial.print(cmd);
254  gsmSerial.print(F("\r\n"));
255  gsmSim808.waitResponse(1000, response);
256  MyDbg(response);
257  return true;
258 }
259 
262 {
263  MyDbg(F("Entering gsm sleep mode 2"));
264  return sendAT(GF("+CSCLK=2"));
265 }
266 
269 {
270  if (!myData.isGsmActive) {
271  MyDbg(F("gsm not active!"));
272  return false;
273  }
274 
275  MyDbg(F("getSMS"));
276  return gsmSim808.getSMS(sms);
277 }
278 
280 bool MyGsmGps::sendSMS(String phoneNumber, String message)
281 {
282  if (!myData.isGsmActive) {
283  MyDbg(F("gsm not active!"));
284  return false;
285  }
286 
287  MyDbg((String) F("sendSMS: ") + message);
288  return gsmSim808.sendSMS(phoneNumber, message);
289 }
290 
292 bool MyGsmGps::deleteSMS(long index)
293 {
294  if (!myData.isGsmActive) {
295  MyDbg(F("gsm not active!"));
296  return false;
297  }
298 
299  MyDbg((String) F("deleteSMS: ") + String(index));
300  return gsmSim808.deleteSMS(index);
301 }
302 
304 void MyGsmGps::enableGps(bool enable)
305 {
306  if (!myData.isGsmActive) {
307  MyDbg(F("sim808 gsm not active!"));
308  return;
309  }
310 
311  if (enable) {
312  gsmSim808.enableGPS();
313  myData.status = F("Sim808 gps enabled!");
315  myData.isGpsActive = true;
316  } else {
317  gsmSim808.disableGPS();
318  myData.status = F("Sim808 gps disabled!");
320  myData.isGpsActive = false;
321  }
322 }
323 
326 {
327  if (!myData.isGsmActive) {
328  MyDbg(F("sim808 gsm not active!"));
329  return false;
330  }
331 
332  bool ret = false;
333 
334  if (myData.isGpsActive) {
335  MyGps gps;
336 
337  myData.waitingForGps = true;
338  if (gsmSim808.getGps(gps)) {
340 
341  MyDbg((String) F("(gps) longitude: ") + gps.longitudeString());
342  MyDbg((String) F("(gps) latitude: ") + gps.latitudeString());
343  MyDbg((String) F("(gps) altitude: ") + gps.altitudeString());
344  MyDbg((String) F("(gps) kmph: ") + gps.kmphString());
345  MyDbg((String) F("(gps) satellites: ") + gps.satellitesString());
346  MyDbg((String) F("(gps) course: ") + gps.courseString());
347  MyDbg((String) F("(gps) gpsDate: ") + gps.date.dateString());
348  MyDbg((String) F("(gps) gpsTime: ") + gps.time.timeString());
349 
350  if (myData.rtcData.lastGps.location.latitude() != 0) {
353  }
354  myData.rtcData.lastGps = gps;
355  myData.waitingForGps = false;
356  ret = true;
357  } else {
358  MyDbg(F(" -> GPS timeout!"));
359  }
360  }
361  return ret;
362 }
363 
366 {
367  if (!myData.isGsmActive) {
368  MyDbg(F("sim808 gsm not active!"));
369  return false;
370  }
371 
372  MyGps gps;
373 
374  // Get the GPS position as fallback from the GSM modul.
375  MyDbg(F("getGsmGps"));
376  if (gsmSim808.getGsmGps(gps)) {
378 
379  MyDbg((String) F("(gsmGps) longitude: ") + gps.longitudeString());
380  MyDbg((String) F("(gsmGps) latitude: ") + gps.latitudeString());
381  MyDbg((String) F("(gsmGps) gpsDate: ") + gps.date.dateString());
382  MyDbg((String) F("(gsmGps) gpsTime: ") + gps.time.timeString());
383 
384  if (myData.rtcData.lastGps.location.latitude() != 0) {
387  }
388  myData.rtcData.lastGps = gps;
389  return true;
390  } else {
391  MyDbg(F(" -> GsmGPS timeout!"));
392  }
393  return false;
394 }
bool isGpsEnabled
Is the gps part of the sim808 active?
Definition: Options.h:43
bool sendAT(String cmd)
Definition: GsmGps.h:244
long lastGpsCheckSec
GPS Check intervall.
Definition: GsmGps.h:35
long lastGsmChecSec
Check intervall for signal and battery quality.
Definition: GsmGps.h:34
TinyGsmClient gsmClient
Gsm client interface.
Definition: GsmGps.h:41
String status
Status information.
Definition: Data.h:63
class MyData::RtcData rtcData
Data to store in the RTC memory.
MyOptions myOptions
The global options.
Definition: tracker.ino:57
bool stop()
Definition: GsmGps.h:219
long gpsCheckIntervalSec
Time interval to check the gps position.
Definition: Options.h:45
bool getGsmGps(MyGps &gps)
Definition: Sim808.h:102
void enableGps(bool enable)
Definition: GsmGps.h:304
Definition: Data.h:27
bool waitingForGps
We are trying to get a location.
Definition: Data.h:92
bool waitingForGps()
Definition: GsmGps.h:238
void MyDbg(String info, bool fromWebServer=false, bool newline=true)
Definition: Utils.h:94
MyOptions & myOptions
Reference to the options.
Definition: GsmGps.h:43
void handleClient()
Definition: GsmGps.h:168
String imei
IMEI of the sim card.
Definition: Data.h:85
bool powerOn
Is the GSM power from the DC-DC modul switched on?
Definition: Options.h:41
long gpsTimeoutSec
Timeout for waiting for gps position.
Definition: Options.h:44
bool sendSMS(String phoneNumber, String message)
Definition: GsmGps.h:280
MyGps lastGps
Last known gps location without timeout.
Definition: Data.h:35
String altitudeString()
Definition: Gps.h:552
bool isGpsActive
Is the gs part of the sim808 activated?
Definition: Data.h:69
String satellitesString()
Definition: Gps.h:564
void MyDelay(long millisDelay)
Definition: Utils.h:104
bool deleteSMS(long index)
Definition: Sim808.h:164
bool deleteSMS(long index)
Definition: GsmGps.h:292
String dateString()
Definition: Gps.h:355
String signalQuality
Quality of the signal.
Definition: Data.h:87
bool getGpsFromGsm()
Definition: GsmGps.h:365
bool getSMS(SmsData &sms)
Definition: Sim808.h:136
double latitude()
Definition: Gps.h:295
String courseString()
Definition: Gps.h:570
String gprsUser
GRPS access point User.
Definition: Options.h:34
String longitudeString()
Definition: Gps.h:540
String kmphString()
Definition: Gps.h:558
String batteryVolt
Battery volt of the sim808 module.
Definition: Data.h:89
double distanceTo(MyLocation &location)
Definition: Gps.h:319
MyLocation location
The gps position.
Definition: Gps.h:136
String cop
Operator selection.
Definition: Data.h:86
long secondsSincePowerOn()
Definition: tracker.ino:132
bool isMoving
Is moving recognized.
Definition: Data.h:94
String gprsPassword
GRPS access point Password.
Definition: Options.h:35
String batteryLevel
Battery level of the sim808 module.
Definition: Data.h:88
MyDate date
The received gps utc date.
Definition: Gps.h:134
long startGpsCheck
Timstamp of first getGps try.
Definition: GsmGps.h:36
String modemInfo
Information from SIM808.
Definition: Data.h:83
String latitudeString()
Definition: Gps.h:546
String modemIP
registered modem ip
Definition: Data.h:84
String gprsAP
GRPS access point of the sim card supplier.
Definition: Options.h:33
MyData & myData
Reference to the data.
Definition: GsmGps.h:44
bool getGps(MyGps &gps)
Definition: Sim808.h:67
MyGsmSim808 gsmSim808
SIM808 interface class.
Definition: GsmGps.h:40
bool begin()
Definition: GsmGps.h:84
bool getGps()
Definition: GsmGps.h:325
bool isGsmActive
Is the sim808 modul connected to a gsm network?
Definition: Data.h:68
MyTime time
The received gps utc time.
Definition: Gps.h:135
long lastGpsUpdateSec
Elapsed Time of last read.
Definition: Data.h:91
bool secondsElapsed(long &lastCheckSec, const long &intervalSec)
Definition: Utils.h:52
MyData myData
The global collected data.
Definition: tracker.ino:58
bool secondsElapsedAndUpdate(long &lastCheckSec, const long &intervalSec)
Definition: Utils.h:63
MyGsmGps(MyOptions &options, MyData &data, short pinRx, short pinTx)
Definition: GsmGps.h:70
Definition: Sim808.h:32
bool sleepMode2()
Definition: GsmGps.h:261
long lastGpsReadSec
Timestamp of the last gps read.
Definition: Data.h:47
bool getSMS(SmsData &sms)
Definition: GsmGps.h:268
String timeString()
Definition: Gps.h:385
Definition: Gps.h:129
MySerial gsmSerial
Serial interface to the sim808 modul.
Definition: GsmGps.h:39
double movingDistance
Minimum distance for moving flag.
Definition: Data.h:95
long minMovingDistance
Minimum distance to accept as moving or not.
Definition: Options.h:46