Thursday, 6 February 2014

GPS with added Start record and distance travelled

And another update to my playing around with the GPS module. This code adds a more complex display with

Start Position - recorded when you press a button

Current Position, or "No Fix" if no valid satellite data received

Time and Date

Distance travelled from Start to Current in nm

2014 02 06 15 32 56

Here's the code:

// GPS with report of No Fix 
// and record/display of start position 
// and distance travelled

#include "SoftwareSerial.h"
#include "U8glib.h"

// GPS 11 RX, 10 TX
SoftwareSerial gps(10, 11);

// LCD 6 SCK(E), 5 MOSI(RW), 4 SS(RS)
U8GLIB_ST7920_128X64_1X lcd(6, 5, 4);

char gpsbuf[200]; // GPS output line
char temp[20] = "No Start posn";
char startlatdeg[20] = "--", startlatmin[20] = "", startlondeg[20] = "--", startlonmin[20] = "";
char startns[2] = "", startew[2] = "";
char curlatdeg[20] = "--", curlatmin[20] = "--", curlondeg[20] = "--", curlonmin[20] = "--";
char curns[2] = "-", curew[2] = "-";
char time[20] = "__", date[20] = "--";
char fix[5];
int startflag = false;

  
void setup()
{
    gps.begin(9600); // start GPS serial
    Serial.begin(9600);
    pinMode(2, INPUT_PULLUP); // LOW = read start position
}

void loop()
{
  float lat;
  float lon;
  float dist;
  
  do // get GPS output, look for $GPRMC
  {  
    getline(gpsbuf);
  } while(strncmp(gpsbuf, "$GPRMC", 6) != 0);
  Serial.println(gpsbuf);
  
  // button press records start position
  if(digitalRead(2) == LOW)
  {
    delay(5); // button bounce
    extfmt(3, "**", gpsbuf, startlatdeg); // read deg lat
    extfmt(3, "  *****", gpsbuf, startlatmin); // read min lat
    extfmt(4, "*", gpsbuf, startns); // NS
    extfmt(5, "***", gpsbuf, startlondeg); // read deg lon
    extfmt(5, "   *****", gpsbuf, startlonmin); // read min lon
    extfmt(6, "*", gpsbuf, startew); // EW
    startflag = true;   
  }
  
  
 // extract current position to cur*** arrays
  extfmt(2, "*", gpsbuf, fix);
  Serial.println(fix);
  
  if(fix[0] == 'A')
  {
  extfmt(3, "**", gpsbuf, curlatdeg); // read deg lat
  extfmt(3, "  *****", gpsbuf, curlatmin); // read min lat
  extfmt(4, "*", gpsbuf, curns); // NS
  extfmt(5, "***", gpsbuf, curlondeg); // read deg lon
  extfmt(5, "   *****", gpsbuf, curlonmin); // read min lon
  extfmt(6, "*", gpsbuf, curew); // EW
  extfmt(1, "**:**", gpsbuf, time);
  extfmt(9, "**-**-**", gpsbuf, date);
  }
  else strcpy(curlatdeg, "No Fix");
  
  
  if(startflag) // if there is a cstart position
  {
    
    lat = atof(startlatdeg) * 60 + atof(startlatmin);
    lat -= atof(curlatdeg) * 60 + atof(curlatmin); // lat in minutes
    lon = atof(startlondeg) * 60 + atof(startlonmin);
    lon -= atof(curlondeg) * 60 + atof(curlonmin); // lon in minutes
    dist = sqrt(lat * lat + lon * lon);
    sprintf(temp, "%d", dist); // print int into temp buffer
  }
   
   lcd.firstPage(); // prepare display
   
   do
   {
     lcd.setFont(u8g_font_helvR08);
     
     // 1st line
     lcd.drawStr(2, 8, "Start");
     
     lcd.drawStr(2, 17, startlatdeg);
     lcd.drawStr(20, 17, startlatmin);
     lcd.drawStr(48, 17, startns);
     
     lcd.drawStr(65, 17, startlondeg);
     lcd.drawStr(87, 17, startlonmin);
     lcd.drawStr(118, 17, startew);
     
     lcd.drawStr(2, 26, "Current");
     
     lcd.drawStr(2, 35, curlatdeg);
     lcd.drawStr(20, 35, curlatmin);
     lcd.drawStr(48, 35, curns);
     
     lcd.drawStr(65, 35, curlondeg);
     lcd.drawStr(88, 35, curlonmin);
     lcd.drawStr(118, 35, curew);
     
     lcd.drawStr(2, 44, "Time");
     lcd.drawStr(65, 44, "Date");
     lcd.drawStr(2, 53, time);
     lcd.drawStr(65, 53, date);
     
     lcd.drawStr(2, 62, "Dist nm");
     lcd.drawStr(44, 62, temp);
     
   } while(lcd.nextPage());   
}

// get a line from the GPS
void getline(char *buf)
{
  int bp = 0;
  char c;
  
  do
  {
    c = gps.read(); // -1 if no char available
    if(c == -1) continue;
    buf[bp++] = c;
  } while(c != '\n');
  buf[bp] = '\0';
}

// find field, extract in fmt from inbuf to outbuf
// fmt * = copy inbuf to outbuf, else copy fmt to outbuf
void extfmt(int field, char *fmt, char *inbuf, char *outbuf)
{
  int f = 0; // field count, common & input pointers
  int fp = 0;
  int op = 0;
  int ip = 0;
   
  // find field and ip start
  while(f != field)
  {
    while(inbuf[ip++] != ',');
    f++;
  }
  
 // format from ip
    while(fmt[fp] !='\0')
    {      
      if(fmt[fp] == ' ') ip++; // skip along
      else if(fmt[fp] == '*')
      {
        outbuf[op++] = inbuf[ip++]; // copy in to out
      }
      else
      {
        outbuf[op++] = fmt[fp]; // insert format
      }
      fp++;
    }
  outbuf[op] = '\0'; // add end of string
}
  

1 comment:

Unknown said...

Hello,

I like this project!

I have made it and it works prtey well :)

But can you tell me pleace where i can find the point that makes the distance in nm?
I dont understand it where it is :/ and what have i to do to make it in meters?

Greating

Georg