Shop OBEX P1 Docs P2 Docs Learn Events
Question about using SERIN to get data from Garmin Legend GPS unit. — Parallax Forums

Question about using SERIN to get data from Garmin Legend GPS unit.

kg6mtikg6mti Posts: 7
edited 2006-08-16 17:05 in BASIC Stamp
Hello there,
·
I am trying to use a BS2sx to capture GPS data from a Garmin Legend GPS unit. I know that this has been done by many users and is probably very simple.
·
Here is the problem that I am having.· When I use the SERIN command to capture data from the GPS unit the application appears to stop when it gets to the SERIN line of code.· I placed a DEBUG statement just before the SERIN command and a DEBUG command just after the SERIN command.· I also added a loop to return to the beginning of the Main label. Both the DEUG commands just output simple text.· If I comment out the SERIN command I receive a debug window with the text output from both DEBUG statements over and over.· When I remove the comment from the SERIN command I only see the text from the first debug statement and the loop stops.
·
If I use a statement like:
·
SERIN 15, 188,· [noparse][[/noparse]GPSdata]
DEBUG GPSdata
·
Would that open a debug window and show me the GPS output from the GPS if the GPS unit is connected to pin 15?
·
Are there any ideas what I am doing wrong?· I have tried my own source code and I have tried source code from the Parallax website and other sites I have found around the Internet.
·
I do know that I am getting output from the GPS.· When I connect the GPS unit directly to my PC and open HyperTerminal I can see the GPS output in plain text.· But when the GPS is connected to the BS2sx I see the behavior mentioned above.
·
Any help will be greatly appreciated.
·
Thank You!
·

Comments

  • allanlane5allanlane5 Posts: 3,815
    edited 2006-07-31 17:29
    Well, when you use the approach you've shown, what you're doing is asking the SERIN command to take the first byte, and put it into a variable named GPSData.

    Then, you're telling SEROUT to output that first byte to the 'debug' port (your PC).

    So, the SERIN is going to 'hang' until it gets a good byte, then send it to your PC. This means you're probably not going to see much very useful.

    I believe the Garmin is actually sending way more than one byte. You can use the 'STR' modifier, to recieve a string into a byte array, if you declare something like "GPSDATA VAR BYTE(13)". I'm not sure what the DEBUG output does with a 'STR' array, though.
  • kg6mtikg6mti Posts: 7
    edited 2006-07-31 17:35
    Thank you for the fast reply,· allanlane5.

    Your information maybe exactly what I am looking for.· You are correct the Garmin GPS sentence is about 50 characters long.· I was using the DEBUG statement just to verify what I am getting from the GPS unit.· Once I know that I am capturing the data successfully I want to parse out the GPS data so that I can output it to a on screen display board for a video camera.
  • Bruce BatesBruce Bates Posts: 3,045
    edited 2006-07-31 17:47
    kg6mti -

    Everything that Allan said is perfectly valid, however, before you pull the REST of your hair out, you may want to try 500 as a baudmode, as that's 4800 baud for the BS-2 SX!

    Regards,

    Bruce Bates

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    <!--StartFragment -->
  • stamptrolstamptrol Posts: 1,731
    edited 2006-07-31 17:47
    The other useful technique is to use the WAIT modifier with your SERIN command, otherwise, you'll be grabbing whatever data is flowing at the moment you start the SERIN command. Typical GPS strings start with an identifing set of characters which WAIT can watch for.

    With the limited variable space available, you might have to grab some data, parse it, send it out, use another SERIN command with the SKIP function, grab another batch of characters, parse them, dump them out to your display, etc.

    I've done this quite successfully up to 3 times in a row in order to get all the data that I need to be sent out.

    Cheers
  • HarborHarbor Posts: 73
    edited 2006-08-01 00:24
    I highly recommend using the WAIT modifier, and also using SPSTR on the SERIN as a format modifier. That causes the string of length you specify to be dumped into the scratchpad. It's nearly hopeless trying to parse the output of a GPS without having a complete message available at once, and the scratchpad ram is the only practical way to do that.
  • kg6mtikg6mti Posts: 7
    edited 2006-08-01 02:37
    I have tried the code below and all the output I get is garbage.· Any idea's??· All your help has been great.· Thank You.


    ' {$STAMP BS2sx}
    ' {$PBASIC 2.5}
    GPSdata VAR Byte(10)
    Main:
    SERIN 0, 500, [noparse][[/noparse]STR GPSdata\10]
    DEBUG GPSdata
    GOTO Main
    END
  • Robert@HCCRobert@HCC Posts: 80
    edited 2006-08-01 07:10
    Here is a litle snippet, try using this and see what you get -Add your variables for baud, TxD and whatnot and hopefully this will help you get the idea.....
    I assume the garmin sends NMEA out like my LassenIQ, and it outputs GPGGA...the serin grabs the data from the GPS, the serout formats and displays it.


    
    'Start GPS capture                                                     ' Capture and display GPS NMEA msg
    DO:  
                                                                                 ' and format data for display
    GOSUB GetLatLong  
    PAUSE 1000   
                                                    
    LOOP
    
    ' GPS subroutines
    '
                                                                                                                      ' Read the GGA sentence from LassenIQ GPS -
    GetLatLong:                                                                                                 ' $GPGGA,hhmmss.ss,llll.lll,a,nnnnn.nnn,b,t,uu,
      SERIN  GPS_TxD,Baud48, [noparse][[/noparse]WAIT("GPGGA,"),SKIP 9,DEC WordData1,             ' v.v,w.w,M,x.x,M,y.y,zzzz*hh <CR><LF>
      SKIP 6, ByteData1, DEC WordData2,SKIP 6, ByteData2]                                ' - store Lat as WordData1, NS Coor as
                                                                                                                       ' ByteData1, store LON as WordData2,and EW Coor as
                                                                                                                       ' ByteData2.
    
      SEROUT  TxD, Baud48, [noparse][[/noparse]CRSRXY, 7, 10, DEC WordData1 DIG 3, DEC WordData1 DIG 2,DegSym, "  ",         ' Print Lat/Long
      DEC WordData1 DIG 1, DEC WordData1 DIG 0,MinSym, " ", ByteData1,CLREOL,
      CRSRXY, 7,11,DEC WordData2 DIG 4,  DEC WordData2 DIG 3, DEC WordData2 DIG 2,DegSym, " ",
      DEC WordData2 DIG 1, DEC WordData2 DIG 0,MinSym, "  ", ByteData2,CLREOL,]
    RETURN
    

    Post Edited (Robert@HCC) : 8/1/2006 7:14:04 AM GMT
  • HarborHarbor Posts: 73
    edited 2006-08-01 08:10
    You should read Nuts & Volts column 83 by Jon Williams. Unfortunately, Jon was
    using a BS2P for that project, so he just slipped everything into scratchpad RAM
    and parsed it at his convenience. I forgot that SPSTR is not available on other
    Stamps, so you can't do that with your SX.

    This is only thinking out loud, and coding in a whisper<g>, but I have to do this
    myself in a week or so, so I gave it a quick once over tonight. No GPS connected,
    so I haven't tested this code, but it should make a starting point for you.

    So with fair warning, and distilling what Jon tells us and some NMEA formats I
    found on the web, here's my best shot at an approach. At least until I have time
    to connect my own GPS and experiment a little bit.

    Every second, you should receive about half a dozen 'sentences' as the NMEA
    protocol defines a single·transmission. Maybe more. Your code will tap into that
    stream of characters at some random point. This is why you have to use the WAIT
    feature to sync up with the start of the sentence type you want to read.

    Garmin may include some non-standard sentences or words in different models,
    like an altitude report, but the stock sentences will be transmitted anyway. The
    stock sentences always begin with the sentence marker (a dollar sign), followed
    by the upper case letter G. (Proprietary sentence formats begin with $P instead.)

    So first, to make sure the connection and the baud rate are correct, let's wait for
    the start of each standard sentence and then print out the format definition part.
    That is, the identifying string that tells you which kind of information will follow.
    Attachment one, gpstest.bsx is a bit of code to do that. Until you can get that to
    work, don't bother to go on. Something is wrong with the fundamentals. Make
    sure the wiring is correct and so forth.

    Once that routine works, we know we can receive the 'sentences' at about 500
    chars a second. Now we have to parse the ones we need "on the fly" because
    your SX can't ship them into scratchpad as the P can, nor does it have enough
    variable memory to hold an entire sentence in ASCII format. So we have to
    convert the string 'words' to binary values as they come in. The obvious way
    to do that is with the formatters provided for SERIN. The faster Stamps may
    be able to parse in pBasic a data stream coming in at 500 chars per second,
    but there is no sense doing something at the token level that can be done at
    the 'firmware' level -- down where Parallax machine code implements the
    tokens. Typically, it is much more efficient that way.

    The basic GPS report is called an RMC, for "Recommended Minimum something
    or other". (Probably sentence type C from the recommended minimum set, but
    it could be named for the author's husband Charlie. Who knows.) Adding the
    prefix, and a 'P' which apparently means 'position', we have $GPRMC as the flag
    for this sentence. So we will modify that SERIN command in our test program to
    begin like this:

    SERIN GpsDataPin, N4800, 3000, TimedOut, [noparse][[/noparse]WAIT ("$GPRMC"),

    I couldn't find the formal grammar for NMEA sentences, (at least without paying
    for a spec from the standards publisher) but we don't really need one for simple
    purposes. Extracting things from what Jon wrote and stuff I found on the web,
    we conclude that an RMC sentence looks like the one below. It begins with the
    ident field and ends with carriage return, linefeed. Each word is demarcated with
    a comma. Thus:

    $GPRMC,212336,A,3251.1320,N,09701.1573,W,0.0,7.2,070202,4.7,E,A*05

    or

    $GPRMC,hhmmss,S,ddmm.mmm,NS,dddmm.mmm,EW,kkk.k,ddd.d,ddmmyy,ddd.d,EW,chksum

    Breaking that down into 'words', we have:

    hhmmss······· UTC time when fix was taken
    S················· Status of the fix. A=active and V=void. (Darned if I know the meaning.)
    ddmm.mmm· Degrees, minutes and second of lattude. Apparently position is reported
    ··················· in thousandths of a minute of arc. Seconds of arc are not used in the report.
    ··················· Since a minute of arc at the equator is one nautical mile or 6000 feet, this
    ··· ··· ··· ······· is a precision of about six feet or two meters. That seems about right for a
    ··················· a "minimum required" report so we have a cross check.
    NS·· ··· ··· ··· The char N or S, for north or south of the equator
    dddmm.mmm Longitude. Same format as latitude, but note extra digit for degrees.
    EW··· ··· ······ The char E or W, for east or west of Greenwich.
    kkk.k··· ··· ··· Speed in knots
    ddd.d··········· Track angle in degrees relative to true north. (If you want to parse this, note that
    ··················· track angles are usually thought of as 0 to 359 by navigators, so you wouldn't be
    ··· ··· ··· ··· ··· able to use DEC3 to get a result that fits in one byte. Use a word variable.)
    ddmmyy··· ··· Day of month, numeric month and two-digit year. I wonder if this has changed
    ··· ··· ··· ··· ··· to four digits now, but everything I found was dated before 2000, so who knows?
    ··· ··· ··· ··· ··· I'm guessing it is still two digits, but reading a sentence from your Legend is the
    ··· ··· ··· ··· ··· quick way to learn.
    ddd.d··· ··· ··· Variation. This might be limited to "dd.d" but parsed correctly, we won't care.
    EW···············Direction of variation. East/west again.
    chksum··· ···· Checksum on the sentence. Always denoted with an asterisk.

    So the second attachment, gpsrmc.bsx,·is a sample of how to parse such things
    using the formatters. For example, to get the latitude when we reach that part
    of the string, we read a DEC2, another DEC2, then finally a DEC3. If we were
    reading these into string variables we'd have to skip the decimal point, but the
    decimal formatter will do that for us. Later in the parse, we have to use SKIP to
    jump over the delimiting comma before reading the N or S qualifier on latitude,
    because we read that as a string of length one. But not when reading decimal.

    Those values·fit in two bytes and one word. That's four bytes for latitude. We
    only need a bit variable for north/south, but I can't see a way to read it in that
    way. Not offhand, so we'll have to read in a full character and reduce it one bit
    later. So we need five bytes for latitude. Add another five for longitude and three
    for UTC time of fix. Since the day might well roll over between one message and
    the next, it isn't safe to postpone getting that value for another sentence. So
    from the same sentence, we need another three bytes for the date. A total of
    six bytes for date time group, and ten for position.

    We're up to sixteen bytes, but we got date, time, lat and long for that many bytes.
    Should be workable. In fact, the code in gpsrmc.bsx requires nineteen bytes and
    one nibble. I changed the year to a word value in case the format has changed to
    send four-digit years by now, and I needed one word for a bit bucket. On the other
    hand,·I noticed the month can be kept in a nibble, so we gained back half a byte.

    You can't "lose your place" when parsing, so I had to use another word variable as
    a bit bucket to receive the parse results for values not being kept, like track angle,
    in order to keep my place while getting to the UTC date. You have to give the
    formatters some place to stick their result even if you don't plan to keep it.

    The code is in the attachments, and it tokenizes, but is not tested, since I haven't
    got my own Garmin hooked up right now. And I should say that I've never tried
    this "parsing with formatters" trick in pBasic. I've always used assembler or C or
    Prolog for parsing. The closest to this sort of thing was FORTRAN, back in the day,
    so you may find places where I've asked something of the formatters they don't
    know how to do in pBasic. I don't think so, (or I'd fix it obviously) but be warned.

    Good luck.

    Post Edited (Harbor) : 8/1/2006 8:24:06 AM GMT
  • Bruce BatesBruce Bates Posts: 3,045
    edited 2006-08-01 08:46
    Harbor -

    The BS-2SX DOES have scratchpad RAM. It's just that it only has 64 bytes of it, as compared to the BS-2p? series which has 128 bytes.

    Regards,

    Bruce Bates

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    <!--StartFragment -->
  • HarborHarbor Posts: 73
    edited 2006-08-01 08:51
    Yes, I know, but the formatter SPSTR is what is not available for the SX. Difference in the pBasic for each model.
  • Bruce BatesBruce Bates Posts: 3,045
    edited 2006-08-01 09:08
    Harbor -

    My sincere apologies, I obviously mis-read your post.

    Regards,

    Bruce Bates

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    <!--StartFragment -->
  • HarborHarbor Posts: 73
    edited 2006-08-01 11:18
    Not at all, Bruce. It was long enough I could have said one thing at the
    beginning and another at the end, without noticing it myself. I had to go back
    and see what I did say<g>. But what I meant to say was definitely related
    to the restriction in formatters available on other models.
  • stamptrolstamptrol Posts: 1,731
    edited 2006-08-01 11:46
    kg6,

    Your code is probably doing what you've asked it to:

    ' {$STAMP BS2sx}
    ' {$PBASIC 2.5}
    GPSdata VAR Byte(10)
    Main:
    SERIN 0, 500, [noparse][[/noparse]STR GPSdata\10] ' immediately grab 10 characters
    DEBUG GPSdata ' without STR here, it displays the ascii of only the first character
    GOTO Main
    END

    Again, as several have suggested, the WAIT modifier will make this work, as it has for others. Do double check the baud
    ( you're set for 4800 on pin 0). My experience has been that using a pin means you should be using INVERTED mode, through a resistor.
    See SERIN in the help file.

    Cheers,
    Tom
  • kg6mtikg6mti Posts: 7
    edited 2006-08-01 18:26
    Wow! Thanks for all the great input.· I am going to try these suggestions tonight.

    I have read the Nuts & Volts papers however as mentioned above the articles use a different stamp chip.· Because the stamp chip is different it is just that much more difficult for me since I already don't really understand what I am doing to have to take out the parts of the code that don't apply or can't be used and modify them to what I need.

    My goal is to learn what I am doing and not just steal someone else's source code.· I want to understand the commands and why they are doing what they are doing.· I really appreciate all the help that you folks are providing.· After I try these comments I will let you know how my success goes.

    The project that I am working on is using the stamp BS2sx to provide text to display on screen with video from a camera that is being transmitted via a ham radio.· The text on the screen will display data from the GPS unit and my ham radio call sign to satisfy the FCC requirements for station identification.
  • kg6mtikg6mti Posts: 7
    edited 2006-08-01 20:00
    stamptrol said...
    kg6,

    Your code is probably doing what you've asked it to:

    ' {$STAMP BS2sx}
    ' {$PBASIC 2.5}
    GPSdata VAR Byte(10)
    Main:
    SERIN 0, 500, [noparse][[/noparse]STR GPSdata\10] ' immediately grab 10 characters
    DEBUG GPSdata ' without STR here, it displays the ascii of only the first character
    GOTO Main
    END

    Again, as several have suggested, the WAIT modifier will make this work, as it has for others. Do double check the baud
    ( you're set for 4800 on pin 0). My experience has been that using a pin means you should be using INVERTED mode, through a resistor.
    See SERIN in the help file.

    Cheers,
    Tom
    Should I use the SER input on the stamp instead?

    Thanks!
  • kg6mtikg6mti Posts: 7
    edited 2006-08-16 04:00
    Thank for all the help.· I have now been able to capture data from the GPS module.· Now I just need to parse for the data that I need and output it to the on screen display module that I am using to get the GPS data to a video screen.· That part I know how to do.

    Thank You.
  • George99George99 Posts: 16
    edited 2006-08-16 17:05
    I'm working on a project using the BS2 and my Garmin eTrex Legend for geocaching. Phase 1 of the project is a remote readout of the data from the unit, and Phase 2 is a bit more complex. I made extensive use of WAIT in getting the data I needed, as the BS2 has 16 bytes of RAM total.

    For example this gets the distance and direction of the current waypoint destination. (GPS interface is set to NMEA data at 4800 baud)

    SERIN gpspin,n4800,2000,nodata,[noparse][[/noparse]WAIT ("$GPRMB"),WAIT(","),STR status \1,WAIT(","),
    WAIT(","),WAIT(","),WAIT(","),WAIT(","),
    WAIT(","),WAIT(","),WAIT(","),WAIT(","),
    DEC5 DistI,DEC5 DistF,DEC5 Bearing]

    I'll put the rest of the code in completed projects.
Sign In or Register to comment.