SNOCC / GPS

Fork of GPS by Simon Ford

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers GPS.cpp Source File

GPS.cpp

00001 /* mbed EM-406 GPS Module Library
00002  * Copyright (c) 2008-2010, sford
00003  *
00004  * Permission is hereby granted, free of charge, to any person obtaining a copy
00005  * of this software and associated documentation files (the "Software"), to deal
00006  * in the Software without restriction, including without limitation the rights
00007  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
00008  * copies of the Software, and to permit persons to whom the Software is
00009  * furnished to do so, subject to the following conditions:
00010  *
00011  * The above copyright notice and this permission notice shall be included in
00012  * all copies or substantial portions of the Software.
00013  *
00014  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00015  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00016  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
00017  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00018  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
00019  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
00020  * THE SOFTWARE.
00021  */
00022  
00023 #include "GPS.h"
00024 
00025 GPS::GPS(PinName tx, PinName rx) : _gps(tx, rx) {
00026     _gps.baud(9600);                                // Cambio baudrate a 9600
00027     longitude = 0.0;
00028     latitude = 0.0; 
00029        
00030 }
00031 
00032 int GPS::sample() {
00033     float time;
00034     char ns, ew, signal;  // Agrego signal para parsear el campo NMEA que indica es estado de señal.
00035     int lock;
00036     
00037 
00038     while(1) {        
00039         getline();
00040         
00041         
00042 
00043         /*
00044         GGA - essential fix data which provide 3D location and accuracy data.
00045 
00046  $GPGGA,123519,4807.038,N,01131.000,E,1,08,0.9,545.4,M,46.9,M,,*47
00047 
00048 Where:
00049      GGA          Global Positioning System Fix Data
00050      123519       Fix taken at 12:35:19 UTC
00051      4807.038,N   Latitude 48 deg 07.038' N
00052      01131.000,E  Longitude 11 deg 31.000' E
00053      1            Fix quality: 0 = invalid
00054                                1 = GPS fix (SPS)
00055                                2 = DGPS fix
00056                                3 = PPS fix
00057                    4 = Real Time Kinematic
00058                    5 = Float RTK
00059                                6 = estimated (dead reckoning) (2.3 feature)
00060                    7 = Manual input mode
00061                    8 = Simulation mode
00062      08           Number of satellites being tracked
00063      0.9          Horizontal dilution of position
00064      545.4,M      Altitude, Meters, above mean sea level
00065      46.9,M       Height of geoid (mean sea level) above WGS84
00066                       ellipsoid
00067      (empty field) time in seconds since last DGPS update
00068      (empty field) DGPS station ID number
00069      *47          the checksum data, always begins with *
00070      */
00071         
00072        
00073      /* 
00074        sscanf(msg, "GN %s",mensaje1);
00075        sscanf(msg, "GP,%s", mensaje2);
00076        sscanf(msg, "GSV,%s", mensaje3);
00077        sscanf(msg, "G,%s", mensaje4);
00078        */
00079        //              $GPRMC,194530.000,A,3051.8007,N,10035.9989,W,1.49,111.67,310714,,,A*74      Esta es la trama GP. En nuestro caso es GN:
00080 
00081        if(sscanf(msg, "GNRMC, %f,%c,%f,%c,%f,%c,%f", &time, &signal, &latitude, &ns, &longitude, &ew, &speed) >=1){
00082        // Agrego las siguientes lineas porque originalmente se analizaba el mensaje GGA y se evaluaba "lock" para saber si habia datos validos
00083        // y ahora evaluo si la señal (signal) está Available (A) o Void (V). Lo dejo asi por si se retorna a GGA.
00084            
00085             if(signal == 'A'){
00086                 lock = 1;
00087                 }
00088             else {
00089                 lock = 0;
00090                 }
00091               
00092      // if(sscanf(msg, "GNGGA,%f,%f,%c,%f,%c,%d", &time, &latitude, &ns, &longitude, &ew, &lock) >= 1) { 
00093         
00094            
00095             
00096              if(!lock) { 
00097                
00098                 longitude = 0.0;
00099                 latitude = 0.0;    
00100                 speed = 0.0;    // 
00101                 return 0;
00102             } 
00103           
00104             else {
00105                 if(ns == 'S') {    latitude  *= -1.0; }
00106                 if(ew == 'W') {    longitude *= -1.0; }
00107                 float degrees = trunc(latitude / 100.0f);      // El formato del campo es GGMM.MMMM: Divido por 100 y tomo parte entera para los grados.
00108                 float minutes = latitude - (degrees * 100.0f); // Resto los grados y me quedo con los minutos
00109                 latitude = degrees + minutes / 60.0f;          // Convierto a decimal sumando grados y dividiendo entre 60 los minutos 
00110                 //degrees = trunc(longitude / 100.0f * 0.01f); // Corrijo esta linea porque es como dividir por 10000.
00111                 degrees = trunc(longitude / 100.0f);           // Repito para la latitud.
00112                 minutes = longitude - (degrees * 100.0f);
00113                 longitude = degrees + minutes / 60.0f;
00114                 speed *= 1.852000f;                            // Convierto nudos  a km/h
00115   
00116                 return 1;
00117                 
00118             }
00119         }
00120          
00121     }
00122 }
00123 
00124 float GPS::trunc(float v) {
00125     if(v < 0.0) {
00126         v*= -1.0;
00127         v = floor(v);
00128         v*=-1.0;
00129     } else {
00130         v = floor(v);
00131     }
00132     return v;
00133 }
00134 
00135 void GPS::getline() {
00136     while(_gps.getc() != '$');    // wait for the start of a line
00137     for(int i=0; i<256; i++) {
00138         msg[i] = _gps.getc();
00139         if(msg[i] == '\r') {
00140             msg[i] = 0;
00141             return;
00142         }
00143     }
00144     error("Overflowed message limit");
00145 }