Shop OBEX P1 Docs P2 Docs Learn Events
GPS Timeout — Parallax Forums

GPS Timeout

David GitzDavid Gitz Posts: 4
edited 2009-03-08 20:31 in Propeller 1
Hi, I'm working on a robotic application and am having the following problem. Besides other sensors, I have a GPS sensor on board. My problem is that in my current code, the program waits for a GPS message before continuing. And sense the GPS is only communicating at 4800 baud it really reduces the execution time of the program. What I would like to do is have this running in the background and the main program would keep running, and when a new message comes in it would get updated but not pause execution. This is probably a misunderstanding of how to use the FullDuplexSerial library file, since this is the reason why it uses another cog to do the uart. I wrote the getgpsrxbuffer function listed at the bottom. Here is my example code:
(For simplicity sake I'm not showing any irrelevant info).


con
GpsBaudRate = 4800
GpsMode = %0000
gpsrx = 2

txPin = 4
rxPin = 3
ComBaudRate = 115200
ComMode = %0000

waitdelay = 100_000

var
long stack[noparse][[/noparse]9]
byte gpsrxbuffer[noparse][[/noparse]50]
byte comrxbuffer[noparse][[/noparse]50]


obj
gpsuart: "Fullduplexserial" 'uart
comuart: "FullDuplexSerial" 'uart

pub init | cogsused

cogsused := cogsused + comuart.start(rxPin,txPin,ComMode,ComBaudRate)
cogsused := cogsused + gpsuart.start(gpsrx,PINNOTUSED,GpsMode,GpsBaudRate)
testsensor

PUB testsensor
repeat
getgpsrxbuffer(@gpsrxbuffer
comuart.str(@gpsrxbuffer)
waitcnt(waitdelay + cnt)

pri getgpsrxbuffer(rxbuffptr) | i

'' Retrieve rx stream into a data block. Fills the data block until a carriage
'' return is retrieved.

i := 0


repeat until (rxbyte := gpsuart.rxcheck) == 13
if rxbyte > 31 AND rxbyte < 126
byte[noparse][[/noparse]rxbuffptr] := rxbyte
i++

byte[noparse][[/noparse]rxbuffptr][noparse][[/noparse]i++] := 0

Thanks!
David

Comments

  • Chuck RiceChuck Rice Posts: 210
    edited 2009-03-08 18:10
    You are hanging on this line:

    repeat until (rxbyte := gpsuart.rxcheck) == 13
    



    There are several ways to do this. One would be to put this code in a separate cog.

    Another would be to use rxcheck diferently:

    if (rxbyte := gpsuart.rxcheck) <> -1
        if rxbyte > 31 AND rxbyte < 126
        byte[noparse][[/noparse]rxbuffptr] := rxbyte
        i++
    
        byte[noparse][[/noparse]rxbuffptr][noparse][[/noparse]i++] := 0
        if rxbyte = 13 then do something with the buffer and set i back to zero
    



    This will test (rxcheck) to see if a character has been received. If it sees a -1, then it skips adding the byte to the buffer. If it is not a -1, it adds they byte to the buffer. Then you can look at the byte to see if the byte received was a carriage return character and if it is, process the buffer and then clear it.
  • David GitzDavid Gitz Posts: 4
    edited 2009-03-08 19:40
    Thanks Chuck, I appreciate your suggestion. I just tried modifying my rxbuffer function to this:
    pri getgpsrxbuffer(rxbuffptr) | i,flag

    '' Retrieve rx stream into a data block. Fills the data block until a carriage
    '' return is retrieved.
    flag := 0
    i := 0


    repeat while ((rxbyte := gpsuart.rxcheck) <> -1 AND flag == 0)

    if rxbyte > 31 AND rxbyte < 126
    byte[noparse][[/noparse]rxbuffptr] := rxbyte
    i++
    if rxbyte == 13
    flag := 1
    'uart.tx(rxbyte)

    byte[noparse][[/noparse]rxbuffptr][noparse][[/noparse]i++] := 0
    return 1

    And in my main program I did this:

    pri datapacketmode | i, j, value1, value2, value3, Ax, Ay, Az, CmpDegrees, GyroYaw, GyroPitch, gpsflag

    comuart.str(@dpt)

    repeat' until strcomp(@rxbuffer,string("done"))
    gpsflag := 0
    !outa[noparse][[/noparse]ledpin1]
    getcomrxbuffer(@comrxbuffer)
    gpsflag := getgpsrxbuffer(@gpsrxbuffer)
    if gpsflag
    waitcnt(waitdelay / 100 + cnt)
    comuart.str(@gpsrxbuffer)
    waitcnt(waitdelay + cnt)

    Now it looks like I'm not getting a delay but I only get part of the gps message, sometimes its 15 characters long, sometimes just a couple comma's in a row.
  • Chuck RiceChuck Rice Posts: 210
    edited 2009-03-08 19:59
    It is hard to tell what is going on with the leading spaces removed. Try creating an archive of the project and attach it. The spaces are very important in SPIN.
  • Mike GreenMike Green Posts: 23,101
    edited 2009-03-08 20:08
    Remember that FullDuplexSerial by default has only a 16 byte buffer. You may need to increase this. There are several versions of FullDuplexSerial around that have larger buffers. I've been using this one (obex.parallax.com/objects/340/), but there are others in the Object Exchange that would work.
  • David GitzDavid Gitz Posts: 4
    edited 2009-03-08 20:09
    Oh sorry, I just copied and pasted it. The top file is the Main file.
  • Chuck RiceChuck Rice Posts: 210
    edited 2009-03-08 20:31
    It looks like you are setting the variable i to zero every time the routine is called. So if you call getgpsrxbuffer it may get a few characters, then return because there are no characters available. The next time it is called, setting i to zero will throw away the characters it got during the previous call. The i variable should only be zeroed when you see the carriage return character. If you have not seen the CR and the rxcheck returns -1, you should return with a "nothing available" flag set. then your main routine can do some more of what it needs to do and call getgpsrxbuffer again later (it should be called at least several times a second, as most GPSes will return data at 1 Hertz). Then getgpsrxbuffer will take up processing at position i and continue filling in characters till the serial buffer is empty (rxcheck=-1) or it sees the end of line character (CR).

    It looks like you are trying to process the buffer as characters are received. That will complicate things. Wait till you have a full line (when you see the CR), then do a repeat loop through the buffer to process the string.

    Also, as Mike said, the default buffer is rather small, you you either need to make it larger, or you will need to call getgpsrxbuffer many times a second so you do not miss characters.
Sign In or Register to comment.