Lassen iQ GPS datalogger - KML offset error

I’ve just received this datalogger and found that the co-ordinates it generates for Google Earth (KML mode) are not correct.

I’m located in London, UK. I did a walking/bus round trip for about 2-3 miles. Removed the 0,0,0 entries from the resulting output file and wrapped them up in a KML header/footer:

<?xml version="1.0" encoding="UTF-8"?>

Name

Description

4

1

0.1974166631699,51.5142326354980,23

0.1974233388901,51.5142364501953,23

0.1974299997091,51.5142364501953,23

0.1974366605282,51.5142364501953,22

0.1974416673183,51.5142402648926,22

It turns out that the sign of the longitude is incorrect. Those numbers should be -0.19. When I change this in a text editor, the resulting path is correct. Otherwise, the path is mirror imaged across longitude 0.

Can anyone else confirm this behaviour?

M

Sounds like the code is assuming that the data logger is destined for north america and is ignoring the N,S and E,W values in the nmea sentence. I cannot confirm this (being that I live in the us) but imagine that this is the problem. Global economy nowadays isn’t it.

I’ll try NMEA and do the conversion with an external tool.

I’d pay a small fee for anyone who can take the existing firmware and solve this problem and enhance the power-saving features.

mg:
I’ll try NMEA and do the conversion with an external tool.

I wrote a little tool to do just that…

http://www.sparkfun.com/cgi-bin/phpbb/v … php?t=3003

mg:
I’ve just received this datalogger and found that the co-ordinates it generates for Google Earth (KML mode) are not correct.

I’m located in London, UK. I did a walking/bus round trip for about 2-3 miles. Removed the 0,0,0 entries from the resulting output file and wrapped them up in a KML header/footer:

It turns out that the sign of the longitude is incorrect. Those numbers should be -0.19. When I change this in a text editor, the resulting path is correct. Otherwise, the path is mirror imaged across longitude 0.

Can anyone else confirm this behaviour?

M

I just analyzed the code. You’ve discovered a bug specific to your longitude (this would also affect negative equatorial regions).

Here’s the code from the logger firmware that does the KML conversion for latitude (same thing applies to longitude):

//latitude

for (x = 0; x < 7; x++)

{

temp2 = lat[mark1 - 2 + x];

lat[mark1 - 2 + x] = 0;

}

q = atof(temp2)/60; //minutes

r = atof(lat); //degrees

if (r < 0) r -= q; //check for negative degrees is invalid from

//0 to -1 (anything between the two).

//This is because “-0” is not < 0.

else r += q;

//r=latitude

The easiest firmware fix would be to store the flag for N/S and E/W, then apply it at the end:

r += q;

if(NS_Flag == -1) r=0-r;

SFE Guys, can you fix your bug?

-Matt

PS: No fix fee required. And Sparkfun did pay attention to the N/S E/W flags, they just didn’t do enough boundary checking!

I don’t see a way to add a file to the post, so I’ve just copied and pasted the updated code for the affected function from the firmware file. This should replace the function by the same name in the SFE firmware. The whole project will need to be recompiled and loaded into the GPS logger.

I also added comments so others could understand the code a bit better.

-Matt

void get_GPS_KML(void)
{
    float q = 0, r = 0, s = 0;
    int x, y, z;
    char temp;
    char temp2[7];
    char north = 0, west = 0;
    char lat[10], lon[11], alt[5];
    char mark1 = 0, mark2 = 0;

    for (x = 0; x < 160; x++)    //zero the arrays
    {
        GPS_short[x] = 0;
        
        if (x < 11) 	lon[x] = 0;
        if (x < 10) 	lat[x] = 0;
        if (x < 5) 		alt[x] = 0;
    }
    
    U1FCR = 0x02;

    while(1)
    {
        temp = getc2();

//this is the GPS message that's being converted:
//$GPGGA,hhmmss.ss,ddmm.mmmmm,s,dddmm.mmmmm,s,n,qq,pp.p,±aaaaa.aa,M,±xxxx.xx,M,sss,aaaa *cc<CR><LF>
//sync   UTC	   Latitude     Longitude   			Altitude
//							  N/S			E/W

        if (temp == '

)
{
temp = getc2(); //‘G’
temp = getc2(); //‘P’
temp = getc2(); //‘G’

        if (temp == 'G')
        {
            temp = getc2(); //'G'
            temp = getc2(); //'A'
            temp = getc2(); //','
            temp = getc2(); //start of UTC

            if (temp != ',') //if there's real data (if there's a GPS lock?)
            {
                stat0_on();
                temp = 0;

                y = 0;
                x = 0;

                while (x < 9)
                {
                    temp = getc2();

                    if (temp == ',') //"Clear out data" Mode (scrolls past UTC data etc.)
                    {
                        x++;
                        y = 0;
                        temp = getc2();
                    }
                    
                    
                    if (x == 1) //Latitude Mode
                    {
                        lat[y] = temp;
                        if (temp == '.') mark1 = y;
                        y++;

                    }
                    
                    
                    if (x == 2) //North/South Mode
                    {
                        north = temp; //setting the North/South flag
                        y++;
                    }

                    if (x == 3)  //Longitude Mode
                    {
                        lon[y] = temp;
                        if (temp == '.') mark2 = y;
                        y++;
                    }
                    
                    
                    if (x == 4)  //East/West Mode
                    {
						west = temp;  //setting the East/West flag
                        y++;
                    }
                    
                    
                    if (x == 8)   //Altitude mode
                    {
                        alt[y] = temp;
                        y++;
                    }
                    

                }

                break;
            }
        }
    }
}

for (x = 0; x < 8; x++)   //convert latitude to two strings (degrees and minutes)
{
    temp2[x] = lat[mark1 - 2 + x]; //move minutes data to new string
    lat[mark1 - 2 + x] = 0; //clear minutes data out of degrees string
}

//change strings to floats
q = atof(temp2)/60; //minutes
r = atof(lat);           //degrees

r += q; //combined latitude (all degrees with decimal)

if(north == 'S'){ 
	r = 0 - r; //if south, make latitude negative
}

for (x = 0; x < 8; x++)   //convert longitude to two strings (degrees and minutes)
{
    temp2[x] = lon[mark2 - 2 + x]; //move minutes data to new string
    lon[mark2 - 2 + x] = 0; //clear minutes data out of degrees string
}

//change strings to floats
q = atof(temp2)/60; //minutes
s = atof(lon);   //degrees

s += q;

if(west == 'W'){    
	s = 0-s; //if west, make longitude negative
}
	
//convert altitude string to integer
x = atoi(alt);

sprintf(GPS_short,"%3.13f,%3.13f,%d \r\n",s,r,x);

}

Nice catch, dude! Hey, I never claimed to be a “good” programmer…I’ll be looking it over more closely in the next 24 hours and I’ll make sure that the next batch of loggers go out with the fix.

Thanks for pulling my bacon out of the fire!

Pete

Here’s the link to the new code (also available on the product description pages)…

http://www.sparkfun.com/Code/GPSLogger.zip

Pete