Cellular library for MTS Socket Modem Arduino Shield devices from Multi-Tech Systems

Dependents:   mtsas mtsas mtsas mtsas

Files at this revision

API Documentation at this revision

Comitter:
mfiore
Date:
Mon Aug 17 21:05:41 2015 +0000
Parent:
77:82c0ec0f73ba
Child:
79:da70f86996a1
Commit message:
add GPS support for EasyIP models

Changed in this revision

Cellular/Cellular.cpp Show annotated file Show diff for this revision Revisions of this file
Cellular/Cellular.h Show annotated file Show diff for this revision Revisions of this file
Cellular/EasyIP.cpp Show annotated file Show diff for this revision Revisions of this file
Cellular/EasyIP.h Show annotated file Show diff for this revision Revisions of this file
--- a/Cellular/Cellular.cpp	Tue Jul 28 16:18:45 2015 +0000
+++ b/Cellular/Cellular.cpp	Mon Aug 17 21:05:41 2015 +0000
@@ -247,7 +247,7 @@
             done = true;
         }
     } while (!done);
-    
+   
     return result;
 }
 
@@ -515,3 +515,23 @@
     return true;
 }
 
+bool Cellular::GPSenable(){
+    return true;
+}
+
+bool Cellular::GPSdisable(){
+    return true;
+}
+
+bool Cellular::GPSenabled(){
+    return true;
+}
+Cellular::gpsData Cellular::GPSgetPosition(){
+    gpsData response;
+    response.success = true;
+    return response;
+}
+
+bool Cellular::GPSgotFix(){
+    return true;    
+}
\ No newline at end of file
--- a/Cellular/Cellular.h	Tue Jul 28 16:18:45 2015 +0000
+++ b/Cellular/Cellular.h	Mon Aug 17 21:05:41 2015 +0000
@@ -264,6 +264,32 @@
         std::string timestamp;
     };
 
+    /** This structure contains the data for GPS position.
+    */
+    struct gpsData {
+        bool success;
+        /// Format is ddmm.mmmm N/S. Where: dd - degrees 00..90; mm.mmmm - minutes 00.0000..59.9999; N/S: North/South.
+        std::string latitude;
+        /// Format is dddmm.mmmm E/W. Where: ddd - degrees 000..180; mm.mmmm - minutes 00.0000..59.9999; E/W: East/West.
+        std::string longitude;
+        /// Horizontal Diluition of Precision.
+        float hdop;
+        /// Altitude - mean-sea-level (geoid) in meters.
+        float altitude;
+        /// 0 or 1 - Invalid Fix; 2 - 2D fix; 3 - 3D fix.
+        int fix;
+        /// Format is ddd.mm - Course over Ground. Where: ddd - degrees 000..360; mm - minutes 00..59.
+        std::string cog;
+        /// Speed over ground (Km/hr).
+        float kmhr;
+        /// Speed over ground (knots).
+        float knots;
+        /// Total number of satellites in use.
+        int satellites;
+        /// Date and time in the format YY/MM/DD,HH:MM:SS.
+        std::string timestamp;
+    };
+    
     /** This method initializes the object with the underlying radio
     * interface to use. Note that this function MUST be called before
     * any other calls will function correctly on a Cellular object. Also
@@ -473,10 +499,37 @@
     */
     std::string getRadioType();
 
+    /** Enables GPS.
+    * @returns true if GPS is enabled, false if GPS is not supported.
+    */
+    virtual bool GPSenable();
+
+    /** Disables GPS.
+    * @returns true if GPS is disabled, false if GPS does not disable.
+    */
+    virtual bool GPSdisable();
+
+    /** Checks if GPS is enabled.
+    * @returns true if GPS is enabled, false if GPS is disabled.
+    */
+    virtual bool GPSenabled();
+        
+    /** Get GPS position.
+    * @returns a structure containing the GPS data field information.
+    */
+    virtual gpsData GPSgetPosition();
+
+    /** Check for GPS fix.
+    * @returns true if there is a fix and false otherwise.
+    */
+    virtual bool GPSgotFix();
+            
 protected:
     MTSBufferedIO* io; //IO interface obect that the radio is accessed through.
     bool echoMode; //Specifies if the echo mode is currently enabled.
 
+    bool gpsEnabled;    //true if GPS is enabled, else false.
+        
     bool pppConnected; //Specifies if a PPP session is currently connected.
     std::string apn; //A string that holds the APN for the radio.
 
@@ -497,4 +550,4 @@
 
 }
 
-#endif /* CELLULAR_H */
+#endif /* CELLULAR_H */
\ No newline at end of file
--- a/Cellular/EasyIP.cpp	Tue Jul 28 16:18:45 2015 +0000
+++ b/Cellular/EasyIP.cpp	Mon Aug 17 21:05:41 2015 +0000
@@ -3,6 +3,7 @@
 #include "MTSText.h"
 #include "MTSLog.h"
 #include "CellUtils.h"
+#include <string>
 
 using namespace mts;
 
@@ -14,6 +15,7 @@
     dtr = NULL;
     resetLine = NULL;
     echoMode = true;
+    gpsEnabled = false;
     pppConnected = false;
     socketMode = TCP;
     socketOpened = false;
@@ -680,3 +682,126 @@
     }
     return status;
 }
+
+bool EasyIP::GPSenable() {
+//The HE910 returns an ERROR if you try to enable when it is already enabled.
+// That's why we need to check if GPS is enabled before enabling it.
+    if(GPSenabled()) {
+        logInfo("GPS was already enabled.");
+        return true;
+    }
+//The LE910-NAG requires AT$GPSSLSR=2,3 to enable GPS but can use AT$GPSP=0 to disable it.    
+    if(type == MTSMC_LAT1){
+        Code code = sendBasicCommand("AT$GPSSLSR=2,3", 2000);
+        if (code == MTS_SUCCESS) {
+            gpsEnabled = true;        
+            logInfo("GPS enabled.");
+            return true;
+        } else {
+            logError("Enable GPS failed!");        
+            return false;
+        }        
+    } else {
+        Code code = sendBasicCommand("AT$GPSP=1", 2000);
+        if (code == MTS_SUCCESS) {
+            gpsEnabled = true;        
+            logInfo("GPS enabled.");
+            return true;
+        } else {
+            logError("Enable GPS failed.");
+            return false;
+        }
+    }
+}
+
+bool EasyIP::GPSdisable() {
+// The HE910 returns an ERROR if you try to disable when it is already disabled.
+// That's why we need to check if GPS is disabled before disabling it.
+    if(!GPSenabled()) {
+        logInfo("GPS was already disabled.");
+        return true;
+    }
+    Code code = sendBasicCommand("AT$GPSP=0", 2000);
+    if (code == MTS_SUCCESS) {
+        gpsEnabled = false;        
+        logInfo("GPS disabled.");
+        return true;
+    } else {
+        logError("Disable GPS failed.");
+        return false;
+    }
+}
+
+bool EasyIP::GPSenabled() {
+    std::string reply = sendCommand("AT$GPSP?", 1000);
+    if(reply.find("1") != std::string::npos) {
+        gpsEnabled = true;
+        return true;
+    } else {
+        gpsEnabled = false;
+        return false;
+    }
+}
+
+Cellular::gpsData EasyIP::GPSgetPosition(){
+    enum gpsFields{time, latitude, longitude, hdop, altitude, fix, cog, kmhr, knots, date, satellites, numOfFields };
+    Cellular::gpsData position;
+    if(!gpsEnabled) {
+        logError("GPS is disabled... can't get position.");
+        position.success = false;
+        return position;
+    }
+    // Get the position information in string format.
+    std::string gps = sendCommand("AT$GPSACP?", 1000);
+    if(gps.find("OK") != std::string::npos) {
+        position.success = true;
+        // Remove echoed AT$GPSACP and leading non position characters.
+        gps.erase(0,22);
+        // Remove trailing CR/LF, CR/LF, OK and CR/LF.
+        gps.erase(gps.end()-8, gps.end());
+        // Split remaining data and load into corresponding structure fields.
+        std::vector<std::string> gpsParts = Text::split(gps, ',');
+        // Check size.
+        if(gpsParts.size() != numOfFields) {
+            logError("Expected %d fields but there are %d fields in \"%s\"", numOfFields, gpsParts.size(), gps.c_str());
+            position.success = false;
+            return position; 
+        }
+        position.latitude = gpsParts[latitude];
+        position.longitude = gpsParts[longitude];
+        position.hdop = atof(gpsParts[hdop].c_str());
+        position.altitude = atof(gpsParts[altitude].c_str());
+        position.fix = atoi(gpsParts[fix].c_str());
+        position.cog = gpsParts[cog];
+        position.kmhr = atof(gpsParts[kmhr].c_str());
+        position.knots = atof(gpsParts[knots].c_str());
+        position.satellites = atoi(gpsParts[satellites].c_str());
+        if((gpsParts[date].size() == 6) && (gpsParts[time].size() == 10)) {
+            position.timestamp = gpsParts[date].substr(4,2) + "/" + gpsParts[date].substr(2,2) + 
+            "/" + gpsParts[date].substr(0,2) + ", " + gpsParts[time].substr(0,2) + 
+            ":" + gpsParts[time].substr(2,2) + ":" + gpsParts[time].substr(4,6);        
+        }
+        return position;     
+    } else {
+        position.success = false;
+        logError("NO \"OK\" returned from GPS position command \"AT$GPSACP?\".");
+        return position;
+    }
+}   
+    
+bool EasyIP::GPSgotFix() {
+    if(!gpsEnabled) {
+        logError("GPS is disabled... can't get fix.");
+        return false;
+    }
+    Cellular::gpsData position = GPSgetPosition();
+    if(!position.success) {
+        return false;
+    } else if(position.fix < 2){
+        logWarning("No GPS fix. GPS fix can take a few minutes. Check GPS antenna attachment and placement.");
+        return false;
+    } else {
+        logInfo("Got GPS fix.");
+        return true;
+    }
+}
\ No newline at end of file
--- a/Cellular/EasyIP.h	Tue Jul 28 16:18:45 2015 +0000
+++ b/Cellular/EasyIP.h	Mon Aug 17 21:05:41 2015 +0000
@@ -104,6 +104,31 @@
     */
     virtual Code setApn(const std::string& apn);
     
+    /** Enables GPS.
+    * @returns true if GPS gets or is enabled, false if GPS is not supported.
+    */
+    virtual bool GPSenable();
+
+    /** Disables GPS.
+    * @returns true if GPS gets or is disabled, false if GPS failed to disable.
+    */
+    virtual bool GPSdisable();
+
+    /** Checks if GPS is enabled.
+    * @returns true if GPS is enabled, false if GPS is disabled.
+    */
+    virtual bool GPSenabled();
+        
+    /** Get GPS position.
+    * @returns a string containing the GPS position.
+    */
+    virtual Cellular::gpsData GPSgetPosition();
+
+    /** Check for GPS fix.
+    * @returns true if there is a fix and false otherwise.
+    */
+    virtual bool GPSgotFix();
+        
 private:
     /** Function that sends +++ to the radio to exit data mode
     * returns true if it successfully exits from online mode, else
@@ -126,4 +151,4 @@
 
 }
 
-#endif /* EASYIP_H */
+#endif /* EASYIP_H */
\ No newline at end of file