Etek EB-85A GPS Example Code

etekgps5hz-02-m.jpg

Here’s some example Arduino code for getting a Etek EB-85A module up and reading latitude and longitude (will probably work with most GPS modules). You can purchase a module from Sparkfun.

The module only needs power, ground, rx and tx. Most modules like the Etek start sending NMEA strings as soon as it has power. The Etek module takes a minute or two to get a satellite fix from a cold start in urban environments. Signals drop out once in a while between tall buildings at street level even with DGPS and SBAS. On a clear day, if you’re lucky, you can get a signal sitting by the window in urban canyons.

//Etek GPS EB-85A Module Example
//by Che-Wei Wang and Kristin O'Friel
//32 Channel etek GPS unit
//modified from original code by Igor González Martín. http://www.arduino.cc/playground/Tutorials/GPS
boolean startingUp=true;
boolean gpsConnected=false;
boolean satelliteLock=false;

long myLatitude,myLongitude;

//GPS
#include <string.h>
#include <ctype.h>
int rxPin = 0;                    // RX PIN 
int txPin = 1;                    // TX TX
int byteGPS=-1;
char linea[300] = "";
char comandoGPR[7] = "$GPRMC";
int cont=0;
int bien=0;
int conta=0;
int indices[13];

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void setup() {
  //GPS
  pinMode(rxPin, INPUT);
  pinMode(txPin, OUTPUT);

  for (int i=0;i<300;i++){       // Initialize a buffer for received data
    linea[i]=' ';
  }
    Serial.begin(4800);
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void printInfo(){

  Serial.print("myLat: ");
  Serial.println(myLatitude);
  Serial.print("myLong: ");
  Serial.println(myLongitude);

  if(gpsConnected==true){
    Serial.println("GPS connected");  
  }
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

//convert NMEA gps syntax of degrees and minutes to + or - decimal point degrees
long decimalMinutes( long l, char dir){ 
  //latitude ddmmmmmm
  //longitude dddmmmmmm
  long decimal;                 //ddmmmmmm
  float ll=(float)l/1000000.0;  //dd.mmmmmmm
  int dd=floor(ll);             //dd.mmmmmm
  float mmmmmm=(ll-dd);         //  .mmmmmm
  float dddddd=mmmmmm/6.0*10.0; //  .mmmmmm convert minutes to decimal degrees .dddddd
  decimal=(float)(dd+dddddd)*1000000.0;

  if(dir=='W'||dir=='S')decimal=decimal*-1.0;
  return decimal;
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void readGPS() {
  byteGPS=Serial.read();         // Read a byte of the serial port
  if (byteGPS == -1) {           // See if the port is empty yet
    //delay(100); 
    gpsConnected=false;
  } 
  else {
    gpsConnected=true;
    linea[conta]=byteGPS;        // If there is serial port data, it is put in the buffer
    conta++;                      

    //printByte(byteGPS); //print raw rx

    if (byteGPS==13){            // If the received byte is = to 13, end of transmission
      cont=0;
      bien=0;
      for (int i=1;i<7;i++){     // Verifies if the received command starts with $GPR
        if (linea[i]==comandoGPR[i-1]) bien++;
      }

      if(bien==6){               // If yes, continue and process the data
        for (int i=0;i<300;i++){
          if (linea[i]==','){    // check for the position of the  "," separator
            indices[cont]=i;
            cont++;
          }
          if (linea[i]=='*'){    // ... and the "*"
            indices[12]=i;
            cont++;
          }
        }

        //satellite lock
        char satLock;
        for (int j=indices[1];j<(indices[2]-1);j++){
          // Serial.print(linea[j+1]); 
          // Serial.println("");
          if(linea[j+1]=='V')satelliteLock=false;
          else satelliteLock=true;
          satLock=linea[j+1];
        }

        //latitude
        char NS;
        char tempLat[9];
        int tempLatCount=0;
        for (int j=indices[2];j<(indices[3]-1);j++){
          //print raw
          if(linea[j+1]!='.'){//remove decimal
            //Serial.print(linea[j+1]); 
            tempLat[tempLatCount]=linea[j+1];
            tempLatCount++;
          }
        }

        //Serial.println("");
        for (int j=indices[3];j<(indices[4]-1);j++){
          //Serial.println(linea[j+1]); 
          NS=linea[j+1];
        }

        // myLatitude=strtol(tempLat);
        long myLat=strtol(tempLat, NULL, 10);
        //convert degrees and minutes to decimal degrees
        myLatitude=decimalMinutes(myLat,NS); 

        //longitude
        char EW;
        char tempLong[10];
        int tempLongCount=0;

        for (int j=indices[4];j<(indices[5]-1);j++){
          //print raw
          if(linea[j+1]!='.'){//remove decimal
            //Serial.print(linea[j+1]); 
            tempLong[tempLongCount]=linea[j+1];
            tempLongCount++;
          }
        }
        //Serial.println("");

        for (int j=indices[5];j<(indices[6]-1);j++){
          // Serial.println(linea[j+1]); 
          EW=linea[j+1];
        }

        long myLong=strtol(tempLong, NULL, 10);
        //convert degrees and minutes to decimal degrees
        myLongitude=decimalMinutes(myLong,EW);

        if (startingUp){
          //gps setup strings for Etek GPS modul
          Serial.print("$PMTK501,2*28\r\n");//turn on dgps
          Serial.print("$PMTK313,1*2E\r\n");//turn on sbas
          Serial.print("$PMTK314,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0*29\r\n");//gprmc only
          startingUp=false;
        }
      }
      conta=0; // Reset the buffer
      for (int i=0;i<300;i++){  
        linea[i]=' ';       
      }                 
    }
  }
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void loop() {
  readGPS();
  printInfo();
  //do stuff here
  //myLatitude is a long like 40689667 which is 40.689667 degrees
  //or -73946641 which is -73.94641

}