GPS and trying to move a decimal point
I have a GPS and am using the library NewSoftSerial. Using the example code, it prints the latitude and longitude in degrees, minutes and seconds but i want just degrees out to the normal 6 decimal places for the GPS. So i just printed the latitude to see what it comes out as. I get 281848348. But i need it to equal 28.184348 which would be the correct degrees. So i thought i would try and just multiply by E^-7 to move the decimal point. But that gives me 28.18 and gets rid of the rest. I am just trying to get the correct degrees out to the 6 decimal places. But i do not know how to shift this decimal place correctly it seems. Here is the code:
#include <NewSoftSerial.h>
NewSoftSerial mySerial = NewSoftSerial(0, 1);
#define powerpin 4
#define GPSRATE 4800
//#define GPSRATE 38400
// GPS parser for 406a
#define BUFFSIZ 90 // plenty big
char buffer[BUFFSIZ];
char *parseptr;
char buffidx;
uint8_t hour, minute, second, year, month, date;
uint32_t latitude, longitude;
uint8_t groundspeed, trackangle;
char latdir, longdir;
char status;
void setup()
{
if (powerpin) {
pinMode(powerpin, OUTPUT);
}
pinMode(13, OUTPUT);
Serial.begin(GPSRATE);
mySerial.begin(GPSRATE);
// prints title with ending line break
Serial.println("GPS parser");
digitalWrite(powerpin, LOW); // pull low to turn on!
}
void loop()
{
uint32_t tmp;
Serial.print("\n\rread: ");
readline();
// check if $GPRMC (global positioning fixed data)
if (strncmp(buffer, "$GPRMC",6) == 0) {
// hhmmss time data
parseptr = buffer+7;
tmp = parsedecimal(parseptr);
hour = tmp / 10000;
minute = (tmp / 100) % 100;
second = tmp % 100;
parseptr = strchr(parseptr, ',') + 1;
status = parseptr[0];
parseptr += 2;
// grab latitude & long data
// latitude
latitude = parsedecimal(parseptr);
if (latitude != 0) {
latitude *= 10000;
parseptr = strchr(parseptr, '.')+1;
latitude += parsedecimal(parseptr);
}
parseptr = strchr(parseptr, ',') + 1;
// read latitude N/S data
if (parseptr[0] != ',') {
latdir = parseptr[0];
}
//Serial.println(latdir);
// longitude
parseptr = strchr(parseptr, ',')+1;
longitude = parsedecimal(parseptr);
if (longitude != 0) {
longitude *= 10000;
parseptr = strchr(parseptr, '.')+1;
longitude += parsedecimal(parseptr);
}
parseptr = strchr(parseptr, ',')+1;
// read longitude E/W data
if (parseptr[0] != ',') {
longdir = parseptr[0];
}
// groundspeed
parseptr = strchr(parseptr, ',')+1;
groundspeed = parsedecimal(parseptr);
// track angle
parseptr = strchr(parseptr, ',')+1;
trackangle = parsedecimal(parseptr);
// date
parseptr = strchr(parseptr, ',')+1;
tmp = parsedecimal(parseptr);
date = tmp / 10000;
month = (tmp / 100) % 100;
year = tmp % 100;
Serial.print("\nTime: ");
Serial.print(hour, DEC); Serial.print(':');
Serial.print(minute, DEC); Serial.print(':');
Serial.println(second, DEC);
Serial.print("Date: ");
Serial.print(month, DEC); Serial.print('/');
Serial.print(date, DEC); Serial.print('/');
Serial.println(year, DEC);
Serial.print("Lat: ");
if (latdir == 'N')
Serial.print('+');
else if (latdir == 'S')
Serial.print('-');
Serial.print(latitude/10000000, DEC); Serial.print('\°', BYTE); Serial.print(' ');
Serial.print((latitude/10000)%100, DEC); Serial.print('\''); Serial.print(' ');
Serial.print((latitude%10000)*6/1000, DEC); Serial.print('.');
Serial.print(((latitude%10000)*6/10)%100, DEC); Serial.println('"');
float latv= latitude*10E-7; // here is where i move the decimal place but get 28.18
Serial.println(latv);
delay(500);
Serial.print("Long: ");
if (longdir == 'E')
Serial.print('+');
else if (longdir == 'W')
Serial.print('-');
Serial.print(longitude/10000000, DEC); Serial.print('\°', BYTE); Serial.print(' ');
Serial.print((longitude/10000)%100, DEC); Serial.print('\''); Serial.print(' ');
Serial.print((longitude%10000)*6/1000, DEC); Serial.print('.');
Serial.print(((longitude%10000)*6/10)%100, DEC); Serial.println('"');
}
//Serial.println(buffer);
}
uint32_t parsedecimal(char *str) {
uint32_t d = 0;
while (str[0] != 0) {
if ((str[0] > '9') || (str[0] < '0'))
return d;
d *= 10;
d += str[0] - '0';
str++;
}
return d;
}
void readline(void) {
char c;
buffidx = 0; // start at begninning
while (1) {
c=mySerial.read();
if (c == -1)
continue;
Serial.print(c);
if (c == '\n')
continue;
if ((buffidx == BUFFSIZ-1) || (c == '\r')) {
buffer[buffidx] = 0;
return;
}
buffer[buffidx++]= c;
}
}



@ Fri, 2010-03-12 14:43
TinyGPS
Hi
Have you had a look at TinyGPS (a GPS/NMEA Parser) ?
http://arduiniana.org/libraries/TinyGPS/
@ Fri, 2010-03-12 21:59
yeah that is older. He
@ Thu, 2010-03-11 17:17
Has to do with print
@ Thu, 2010-03-11 21:43
yes just found that out last
@ Wed, 2010-03-10 23:14
variable typing
Your latitude is of type uint32_t, your latv is of type float.
I don't actually speak "Italian", but I'm guessing the float type does not allow for more significant numbers in your value than four: 18.28, that's four positions.
Maybe you should get yourself a bigger float-type.
Or stick with uint32_t (long 32 bit integers). Find the whole part of the number after the decimal point:
281848348 and take the 1848348 to mean "millionths of a degree" in the rest of your program.For any value of latitude.
@ Wed, 2010-03-10 23:57
how do i get a bigger float
@ Thu, 2010-03-11 15:38
really dunno
Anyone who does? Help the fella out here.
As I said, I don't speak the lingo. I'd have to read the manual. You'd better do that yourself. And then, say a year from now, you can teach me, when pass over into the dark side.
I don't even know if there is such a thing as "a bigger float".
8-)