Shop OBEX P1 Docs P2 Docs Learn Events
"Garbage" data from GPS receiver — Parallax Forums

"Garbage" data from GPS receiver

skatjskatj Posts: 88
edited 2008-02-13 01:48 in BASIC Stamp
I'm testing the initialization part of my program, which waits until the GPS receiver locks onto four satellites, and then drives the servos to go forward. This isn't working though, since, according to my debug terminal, it has 0 satellites until about 15 seconds later, when it acquires anywhere from 20-200 satellites and begins moving forward prematurely (the red LED is still blinking).

This is the code snippet I am working with:

Initialize:

 GOSUB Fpu_Reset                      'resets the FPU hardware
  DO
   SEROUT Sio, Baud, [noparse][[/noparse]"!GPS", GetSats]
    SERIN Sio, Baud, 3000, No_Response, [noparse][[/noparse]sats]
      IF sats >= 4 THEN
      DEBUG DEC ? sats, CR
      EXIT
      ELSEIF sats < 4 THEN
      DEBUG DEC ? sats, CR
     ENDIF
  LOOP

'Once four or more satellites have been acquired, the drive servos are set into motion
'and the program goes into autonomous GPS navigation.

'Sets both servos to foward position
  ServoPos1 = 1250
  SEROUT Sdat, Bauds+$8000,[noparse][[/noparse]"!SC", 5, 1,  servoPos1.LOWBYTE, servoPos1.HIGHBYTE, CR]

  ServoPos2 = 500
  SEROUT Sdat, Bauds+$8000,[noparse][[/noparse]"!SC", 13, 1,  servoPos2.LOWBYTE, servoPos2.HIGHBYTE, CR]



Any ideas? I noticed that, in the GPS demo code too, I got a lot of garbage data. Is this because of smart mode? Should I switch to raw NMEA strings?

(Also, I am testing this indoors by holding it out to the window and waiting for the wheels to turn , it eventually can get a signal but I'm not sure if this will mess up the data somehow)

edit: I've added a 2500 millisecond pause to this loop so the data feed is slower, and it fixed the problem. Can someone explain to me why this would fix the problem? Would switching to raw mode let me get the information faster?

Post Edited (skatj) : 2/10/2008 11:19:22 PM GMT

Comments

  • FranklinFranklin Posts: 4,747
    edited 2008-02-10 23:21
    If you could attach your complete code it would help. What is GetSats? What is No_Response? How is sats defined?

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    - Stephen
  • skatjskatj Posts: 88
    edited 2008-02-11 00:23
    Franklin I solved this problem, but I do have some questions about GPS accuracy. (GetSats, No_Response, and sats are all defined correctly, taken from the GPS demo code)

    The documentation says +-5 meters accuracy, which is fine for my application.

    With 5 satellites however, I am getting GPS data that is WAY off the mark.

    For example, I am supposed to be getting around 21 degrees, 19.044 minutes N and 157 degrees, 51.186 minutes west according to Google Earth, but my GPS receiver is telling me 21 degrees, 19.495 minutes west, and 157 degrees, 51.1879 degrees north.

    That's over a mile off for latitude, but for some reason longitude is working fine. Also, both latitude and longitude grow consistently larger as my program runs. The fractional minutes for latitude is now 603 and growing, while my longitude is now 1935. I haven't moved the receiver an inch.

    Any ideas as to why I am getting this data?

    I've uploaded my program, if that helps any.

    edit: I now have 11 satellites, and the data is still off..

    Post Edited (skatj) : 2/11/2008 12:29:59 AM GMT
  • skatjskatj Posts: 88
    edited 2008-02-11 04:36
    Some updates.

    When I use the GPS demo code, it's correct.

    When I use my code, it's way off.


    I don't understand why, the only difference is that, in the demo code, the coordinate data is output in degrees, minutes, seconds format, while my data is output in degrees, minutes, fractional minutes.

    Either my data is being displayed incorrectly, or Google Earth's degrees/minutes/fractional minutes data is off (which I highly doubt).

    Can someone take a look at both programs and see what can be causing this discrepancy?
  • Bruce BatesBruce Bates Posts: 3,045
    edited 2008-02-11 08:54
    Skatj -

    I'm not sure which u-FPU you're using, but that may not make a difference in what I'm about to suggest. Unless I'm mistaken, the following u-FPU instructions don't seem to do what the comments say they are doing:

    (extracted from your program)

    'loads the minutes and fractional minutes into the FPU for calculation (degrees omitted)
    · SHIFTOUT FpuOut, FpuClk, MSBFIRST, [noparse][[/noparse]IntMinutes, LOADBYTE, minutes, FSET]
    · SHIFTOUT FpuOut, FpuClk, MSBFIRST, [noparse][[/noparse]FracMin, LOADWORD, minutesD, FSET]

    'convert from degrees/minutes/fractional minutes to decimal degrees
    · SHIFTOUT FpuOut, FpuClk, MSBFIRST, [noparse][[/noparse]IntMinutes, LOADWORD, 1000, FMUL] 'multiply minutes by 1,000
    · SHIFTOUT FpuOut, FpuClk, MSBFIRST, [noparse][[/noparse]IntMinutes, LOADBYTE, 6, FDIV]··· 'divide it by 6

    In the first comment you say "... (degrees omitted)", yet in the next comment you say "convert from degrees/minutes/fractional minutes to decimal degrees". Are degrees omitted, or not?

    Certainly incorrect comments aren't going to cause a problem, but you've got me pretty well confused as to what is actually going on there in those calculations.

    Regards,

    Bruce Bates

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    "Genius is one percent inspiration and ninety-nine percent perspiration."

    Thomas Alva Edison
  • skatjskatj Posts: 88
    edited 2008-02-11 22:05
    Bruce, the degrees are omitted, it's just a wording problem, sorry.

    My problem comes before that however, since the raw data being debugged is way off according to what it should be in Google Earth.
  • skatjskatj Posts: 88
    edited 2008-02-12 04:24
    I think I did not word my problem very clearly. I am getting data from my GPS receiver that is WAY off compared to what I'm supposed to be getting in Google Earth. Here is some updates on my situation.

    I wrote a program combining code from the GPS demo (which worked correctly for me) and my own program which displayed raw data (which was not working), and the results I got were mind-boggling.

    The demo code ran as expected (though it was quite a bit more than 5 meters off, about 4-5 houses over).

    The raw data, when inputted into Google Earth was still, VERY off.


    After spending an hour analyzing this data in Google Earth and using an online GPS coordinate converter, I found out a few things.

    1. Longitude is fine (raw data is correct)
    2. Latitude, when I input the coordinate data in Google Earth in degrees/minutes/fractional minutes, is off.
    3. Latitude, when I convert to decimal degrees, is off.
    4. Latitude, in the example below, when I convert to degrees/minutes/seconds, the Stamp actually displays this data incorrectly. It displays the seconds as 2.7, when using an online converter (http://www.cosports.com/tools/gps_coords.htm), should be 27 seconds.
    5. However, when the conversion is incorrect, my position on Google Earth is where it is supposed to be. With the online converter, it is wrong.
    6. The decimal degrees conversion given by the debug terminal is also correct, but when using the raw data (degrees/minutes/fractional minutes) in the online converter, the data is off (in the same position as the other "off" data).
    7. I trust this converter over my code, which means that the raw data is wrong (it is wrong in degrees/minutes/fractional minutes anyway).

    Conclusions
    1. The raw data of the latitude is wrong.
    2. The conversion done in the program, is done incorrectly, but somehow outputs the correct position.

    I don't understand how this can happen sad.gif
    Any ideas?

    Here's an example of my debug terminal screen, I've attached the test program.

    The data is organized like this:
    Raw data display (latitude)
    Raw data display (longitude)
    Raw data display (latitude)
    Converted data display from demo code (latitude)
    Raw data display (longitude)
    Converted data display from demo code (longitude)

    Raw GPS data (latitude):
    sats = 12
    
    _degrees = 21
    
    minutes = 19
    
    minutesD.HIGHBYTE = 1
    
    minutesD.LOWBYTE = 199
    
    minutesD = 455
    
    dir = 0
    
    Raw GPS data (longitude):
    sats = 12
    
    _degrees = 157
    
    minutes = 51
    
    minutesD.HIGHBYTE = 7
    
    minutesD.LOWBYTE = 168
    
    minutesD = 1960
    
    dir = 1
    
    ------------------------------------------------
    
    Raw GPS data (latitude):
    sats = 12
    
    _degrees = 21
    
    minutes = 19
    
    minutesD.HIGHBYTE = 1
    
    minutesD.LOWBYTE = 197
    
    minutesD = 453
    
    dir = 0
    
    021° 19' 02.7" N ( 21.3173 )  
    
    -------------------------------------------------- 
    
    Raw GPS data (longitude):
    sats = 12
    
    _degrees = 157
    
    minutes = 51
    
    minutesD.HIGHBYTE = 7
    
    minutesD.LOWBYTE = 172
    
    minutesD = 1964
    
    dir = 1
    
    157° 51' 11.7" W (-157.8532 ) 
    
    




    Thanks,
    skatj
  • phil kennyphil kenny Posts: 233
    edited 2008-02-12 18:13
    I think I see the source of the difficulty that skatj has been having.

    In this case, the code is correct but the error crept in when trying
    to use an online coordinate converter.

    My guess is that when he entered the latitude he used

    21 deg 19.453 minutes

    where he should have entered

    21 deg 19.0453 minutes

    Doing both the Longitude and Latitude calculations by hand:

    Longitude raw data for minutesD.HIGHBYTE = 7

    This is really 7x256 = 1792

    Longitude raw data for minutesD.LOWBYTE = 172

    Adding these we get 1792 + 172 = 1964

    minutes.D has a maximum value of 9999 <<<
    or 0.9999 in 'real' numbers

    This is supposed to be the decimal part of the minutes
    so it has to be less than 1:

    1964/10000 = 0.1964 for the decimal part.of the minutes

    Raw data for minutes = 51

    Therefore the actual minutes = 51.1964 minutes.

    Since there are 60 seconds/minute we multiply 60 x 0.1964
    and get 11.78 seconds for the Longitude.

    Therefore the Longitude is 157 deg 51 min 11.78 sec

    So far, so good.

    Doing the same for the Raw Latitude GPS numbers, will expose
    the problem.

    Latitude raw data for minutesD.HIGHBYTE = 1

    This is really 1x256 = 256

    Latitude raw data for minutesD.LOWBYTE = 197

    Adding these we get 256 + 197 = 453

    To convert this into the 'real' decimal part of the minutes,
    we have to divide by 10,000 just as we did for the Longitude.

    453/10000 = 0.0453

    Here is where the factor of 10 error came from.

    I suspect that 0.453.was used, instead of 0.0453

    Raw data for minutes = 19

    Therefore the actual minutes = 19.0453 minutes

    Converting 0.0453 minutes to seconds

    0.0453 x 60 = 2.72 seconds.

    and the Latitude is 21 deg 19 min 2.72 sec

    The whole problem is that the decimal part of the minutes
    is a four digit number, even if the leading digit is ZERO.

    phil
  • skatjskatj Posts: 88
    edited 2008-02-12 22:23
    That makes sense Phil, thank you for your time and patience in helping me solve this problem smile.gif

    How would I account for this when writing the actual program?
  • phil kennyphil kenny Posts: 233
    edited 2008-02-13 01:48
    Each count in the minuteD value actually represents 1/10,000 or 0.0001 minutes.
    If you want to work strictly with integer numbers (all that a Stamp really
    understands) you have to represent all values in terms of minuteD units

    To add the minuteD number to minutes, multiply minutes by 10,000 then
    add minuteD.

    Let New_minute be:

    New_minute = minute * 10,000 + minuteD

    New_Degrees = 60 * New_Minute

    How you program the FPU depends a lot on how many digits it can
    handle. The maximum Latitude degree value is 180.

    Convert 180 degrees into equivalent minuteD counts as follows

    1 New_Degree = 60 minutes * 10,000 = 600,000 minuteD counts

    180 * 600,000 = 108,000,000 minuteD counts for maximum latitude.

    Four bytes can hold values up to 4,294,967,295. Therefore, each
    newly calculated Latitude and Longitude will need 4 bytes, or 8 bytes
    total if stored as a Stamp variable. The destination Longitude and
    Latitude will also need 8 bytes of memory.

    High precision math can chew up memory very quickly.

    Worst case calculations will involve 9 digit numbers. Can the FPU
    give this precision without overflow?

    I've only shown one way to do this. Others may have different
    solutions which don't require such high precision. It all depends
    on how accurately you want to calculate the locations you are trying
    to navigate to.

    If you really do need this precision and the FPU can't handle 9 digit
    calculations, you can use multi precision arithmetic. Tracy Allen
    has an excellent discussion of this technique on his website at:

    http://www.emesys.com/BS2math6.htm#top

    phil

    Post Edited (phil kenny) : 2/13/2008 2:17:24 AM GMT
Sign In or Register to comment.